public NFCompressedGraph buildGraph() {
    for (String nodeType : graphSpec.getNodeTypes()) {
      NFBuildGraphNodeList nodeOrdinals = buildGraphNodeCache.getNodes(nodeType);
      addNodeType(nodeType, nodeOrdinals);
    }

    return new NFCompressedGraph(
        graphSpec,
        modelHolder,
        graphBuffer.getData(),
        graphBuffer.length(),
        compressedGraphPointers);
  }
  private void serializeMultipleProperty(
      NFBuildGraphNode node,
      NFPropertySpec propertySpec,
      int connectionModelIndex,
      ByteArrayBuffer toBuffer) {
    OrdinalSet connections = node.getConnectionSet(connectionModelIndex, propertySpec);

    int numBitsInBitSet = buildGraphNodeCache.numNodes(propertySpec.getToNodeType());
    int bitSetSize = ((numBitsInBitSet - 1) / 8) + 1;

    if (connections.size() < bitSetSize) {
      if (propertySpec.isHashed()) {
        hashedPropertyBuilder.buildProperty(connections);
        if (fieldBuffer.length() < bitSetSize) {
          int log2BytesUsed = 32 - Integer.numberOfLeadingZeros((int) fieldBuffer.length());
          toBuffer.writeByte((byte) log2BytesUsed);
          toBuffer.write(fieldBuffer);
          fieldBuffer.reset();
          return;
        }
      } else {
        compactPropertyBuilder.buildProperty(connections);
        if (fieldBuffer.length() < bitSetSize) {
          toBuffer.writeVInt((int) fieldBuffer.length());
          toBuffer.write(fieldBuffer);
          fieldBuffer.reset();
          return;
        }
      }

      fieldBuffer.reset();
    }

    bitSetPropertyBuilder.buildProperty(connections, numBitsInBitSet);
    toBuffer.writeByte((byte) 0x80);
    toBuffer.write(fieldBuffer);
    fieldBuffer.reset();
  }