@Override
  public <T extends ExternalizableGraphElement, C extends Collection<? super T>> C readGraphElementCollection(C acc) throws IOException {
    try {
      String className = readUTF();
      Class<?> elemType = Class.forName(className);
      
      if (FactoredExternalizableGraphElement.class.isAssignableFrom(elemType)) {
        int groupCount = readInt();
        while (groupCount-- > 0) {
          RW.readCollection(this, new RW.Reader<>() {
            MethodHandle constructor;
            @Override
            public T read() throws IOException {
              try {
                if (constructor == null)  {
                  // first element
                  ExternalizableGraphElement factorData = readGraphElement();
                  constructor = ourLookup.findConstructor(elemType, MethodType.methodType(void.class, factorData.getClass(), GraphDataInput.class)).bindTo(factorData);
                }
                //noinspection unchecked
                return GraphDataInputImpl.this.processLoadedGraphElement((T)constructor.invoke(GraphDataInputImpl.this));
              }
              catch (IOException e) {
                throw e;
              }
              catch (Throwable e) {
                throw new IOException(e);
              }
            }
          }, acc);
        }
        return acc;
      }

      MethodHandle constructor = ourLookup.findConstructor(elemType, ourDefaultReadConstructorType);
      return RW.readCollection(this, () -> {
        try {
          //noinspection unchecked
          return processLoadedGraphElement((T)constructor.invoke(this));
        }
        catch (IOException e) {
          throw e;
        }
        catch (Throwable e) {
          throw new IOException(e);
        }
      }, acc);
    }
    catch (IOException e) {
      throw e;
    }
    catch (Throwable e) {
      throw new IOException(e);
    }
  }
@Override
  public <T extends ExternalizableGraphElement, C extends Collection<? super T>> C readGraphElementCollection(C acc)