private static DependencyNode readDependencyNode(final IonReader reader, final ReadContext context, @Nullable String fieldName) {
    if (reader.next() == null) return null;
    assertFieldName(reader, fieldName);
    reader.stepIn();

    DependencyNode dependency =
      context.nodesMap
        .computeIfAbsent(readInt(reader, OBJECT_ID_FIELD), new IntObjectMap.ObjectFactory<DependencyNode>() {

          @Override
          public DependencyNode newInstance() {
            String type = readString(reader, "_type", context.stringCache);
            long id = readLong(reader, "id");
            int resolutionStateOrdinal = readInt(reader, "resolutionState");
            ResolutionState resolutionState = resolutionStateOrdinal == -1 ? null : RESOLUTION_STATES[resolutionStateOrdinal];
            String selectionReason = readString(reader, "selectionReason", context.stringCache);
            DependencyNode node;
            if (ProjectDependencyNode.class.getSimpleName().equals(type)) {
              String projectName = assertNotNull(readString(reader, "projectName", context.stringCache));
              String projectPath = assertNotNull(readString(reader, "projectPath", context.stringCache));
              node = new ProjectDependencyNodeImpl(id, projectName, projectPath);
            }
            else if (ArtifactDependencyNode.class.getSimpleName().equals(type)) {
              String group = assertNotNull(readString(reader, "group", context.stringCache));
              String module = assertNotNull(readString(reader, "module", context.stringCache));
              String version = assertNotNull(readString(reader, "version", context.stringCache));
              node = new ArtifactDependencyNodeImpl(id, group, module, version);
            }
            else if (FileCollectionDependencyNode.class.getSimpleName().equals(type)) {
              String displayName = assertNotNull(readString(reader, "displayName", context.stringCache));
              String path = assertNotNull(readString(reader, "path", context.stringCache));
              node = new FileCollectionDependencyNodeImpl(id, displayName, path);
            }
            else if (DependencyScopeNode.class.getSimpleName().equals(type)) {
              String scope = assertNotNull(readString(reader, "scope", context.stringCache));
              String displayName = assertNotNull(readString(reader, "displayName", context.stringCache));
              String description = assertNotNull(readString(reader, "description", context.stringCache));
              node = new DependencyScopeNode(id, scope, displayName, description);
            }
            else if (ReferenceNode.class.getSimpleName().equals(type)) {
              node = new ReferenceNode(id);
            }
            else if (UnknownDependencyNode.class.getSimpleName().equals(type)) {
              String name = assertNotNull(readString(reader, "name", context.stringCache));
              node = new UnknownDependencyNode(id, name);
            }
            else {
              throw new RuntimeException("Unsupported dependency node");
            }
            if (node instanceof AbstractDependencyNode) {
              ((AbstractDependencyNode)node).setResolutionState(resolutionState);
              ((AbstractDependencyNode)node).setSelectionReason(selectionReason);
            }
            return node;
          }

          @Override
          public void fill(DependencyNode node) {
            if (node instanceof AbstractDependencyNode) {
              node.getDependencies().addAll(readDependencyNodes(reader, context));
            }
          }
        });
    reader.stepOut();
    return dependency;
  }
private static DependencyNode readDependencyNode(final IonReader reader, final ReadContext context, @Nullable String fieldName)