JsonSchemaTreeNode (@NotNull Project project, final @NotNull JsonSchemaObject schema, final @NotNull JsonPointerPosition position, final boolean skipLastExpand) { final JsonSchemaTreeNode root = new JsonSchemaTreeNode(null, schema); JsonSchemaService service = JsonSchemaService.Impl.get(project); expandChildSchema(root, schema, service); // set root's position since this children are just variants of root for (JsonSchemaTreeNode treeNode : root.getChildren()) { treeNode.setPosition(position); } final ArrayDeque<JsonSchemaTreeNode> queue = new ArrayDeque<>(root.getChildren()); while (!queue.isEmpty()) { final JsonSchemaTreeNode node = queue.removeFirst(); if (node.isAny() || node.isNothing() || node.getPosition().isEmpty() || node.getSchema() == null) continue; final JsonPointerPosition step = node.getPosition(); if (!typeMatches(step.isObject(0), node.getSchema())) { node.nothingChild(); continue; } final Pair<ThreeState, JsonSchemaObject> pair = doSingleStep(step, node.getSchema(), true); if (ThreeState.NO.equals(pair.getFirst())) node.nothingChild(); else if (ThreeState.YES.equals(pair.getFirst())) node.anyChild(); else { // process step results assert pair.getSecond() != null; if (node.getPosition().size() > 1 || !skipLastExpand) expandChildSchema(node, pair.getSecond(), service); else node.setChild(pair.getSecond()); } queue.addAll(node.getChildren()); } return root; }