public Path path(ObjectNode obj, String location, ParseResult result) {
    boolean hasRef = false;
    Path output = null;
    if (obj.get("$ref") != null) {
      JsonNode ref = obj.get("$ref");
      if (ref.getNodeType().equals(JsonNodeType.STRING)) {
        return pathRef((TextNode) ref, location, result);
      } else if (ref.getNodeType().equals(JsonNodeType.OBJECT)) {
        ObjectNode on = (ObjectNode) ref;

        // extra keys
        Set<String> keys = getKeys(on);
        for (String key : keys) {
          result.extra(location, key, on.get(key));
        }
      }
      return null;
    }
    Path path = new Path();

    ArrayNode parameters = getArray("parameters", obj, false, location, result);
    path.setParameters(parameters(parameters, location, result));

    ObjectNode on = getObject("get", obj, false, location, result);
    if (on != null) {
      Operation op = operation(on, location + "(get)", result);
      if (op != null) {
        path.setGet(op);
      }
    }
    on = getObject("put", obj, false, location, result);
    if (on != null) {
      Operation op = operation(on, location + "(put)", result);
      if (op != null) {
        path.setPut(op);
      }
    }
    on = getObject("post", obj, false, location, result);
    if (on != null) {
      Operation op = operation(on, location + "(post)", result);
      if (op != null) {
        path.setPost(op);
      }
    }
    on = getObject("head", obj, false, location, result);
    if (on != null) {
      Operation op = operation(on, location + "(head)", result);
      if (op != null) {
        path.setHead(op);
      }
    }
    on = getObject("delete", obj, false, location, result);
    if (on != null) {
      Operation op = operation(on, location + "(delete)", result);
      if (op != null) {
        path.setDelete(op);
      }
    }
    on = getObject("patch", obj, false, location, result);
    if (on != null) {
      Operation op = operation(on, location + "(patch)", result);
      if (op != null) {
        path.setPatch(op);
      }
    }
    on = getObject("options", obj, false, location, result);
    if (on != null) {
      Operation op = operation(on, location + "(options)", result);
      if (op != null) {
        path.setOptions(op);
      }
    }

    // extra keys
    Set<String> keys = getKeys(obj);
    for (String key : keys) {
      if (key.startsWith("x-")) {
        path.setVendorExtension(key, extension(obj.get(key)));
      } else if (!PATH_KEYS.contains(key)) {
        result.extra(location, key, obj.get(key));
      }
    }
    return path;
  }