public static Object fieldTypeFromStream(
      final ODocument iDocument, OType iType, final Object iValue) {
    if (iValue == null) return null;

    if (iType == null) iType = OType.EMBEDDED;

    switch (iType) {
      case STRING:
      case INTEGER:
      case BOOLEAN:
      case FLOAT:
      case DECIMAL:
      case LONG:
      case DOUBLE:
      case SHORT:
      case BYTE:
      case BINARY:
      case DATE:
      case DATETIME:
      case LINK:
        return simpleValueFromStream(iValue, iType);

      case EMBEDDED:
        // EMBEDED RECORD
        return ((ODocument) OStringSerializerEmbedded.INSTANCE.fromStream((String) iValue))
            .addOwner(iDocument);

      case CUSTOM:
        // RECORD
        final Object result = OStringSerializerAnyStreamable.INSTANCE.fromStream((String) iValue);
        if (result instanceof ODocument) ((ODocument) result).addOwner(iDocument);
        return result;

      case EMBEDDEDSET:
      case EMBEDDEDLIST:
        {
          final String value = (String) iValue;
          return ORecordSerializerSchemaAware2CSV.INSTANCE.embeddedCollectionFromStream(
              iDocument, iType, null, null, value);
        }

      case EMBEDDEDMAP:
        {
          final String value = (String) iValue;
          return ORecordSerializerSchemaAware2CSV.INSTANCE.embeddedMapFromStream(
              iDocument, null, value, null);
        }
    }

    throw new IllegalArgumentException(
        "Type " + iType + " not supported to convert value: " + iValue);
  }
  public static void fieldTypeToString(
      final StringBuilder iBuffer, OType iType, final Object iValue) {
    if (iValue == null) return;

    final long timer = PROFILER.startChrono();

    if (iType == null) {
      if (iValue instanceof ORID) iType = OType.LINK;
      else iType = OType.EMBEDDED;
    }

    switch (iType) {
      case STRING:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.string2string"),
            "Serialize string to string",
            timer);
        break;

      case BOOLEAN:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.bool2string"),
            "Serialize boolean to string",
            timer);
        break;

      case INTEGER:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.int2string"),
            "Serialize integer to string",
            timer);
        break;

      case FLOAT:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.float2string"),
            "Serialize float to string",
            timer);
        break;

      case DECIMAL:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.decimal2string"),
            "Serialize decimal to string",
            timer);
        break;

      case LONG:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.long2string"),
            "Serialize long to string",
            timer);
        break;

      case DOUBLE:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.double2string"),
            "Serialize double to string",
            timer);
        break;

      case SHORT:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.short2string"),
            "Serialize short to string",
            timer);
        break;

      case BYTE:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.byte2string"),
            "Serialize byte to string",
            timer);
        break;

      case BINARY:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.binary2string"),
            "Serialize binary to string",
            timer);
        break;

      case DATE:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.date2string"),
            "Serialize date to string",
            timer);
        break;

      case DATETIME:
        simpleValueToStream(iBuffer, iType, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.datetime2string"),
            "Serialize datetime to string",
            timer);
        break;

      case LINK:
        if (iValue instanceof ORecordId) ((ORecordId) iValue).toString(iBuffer);
        else ((ORecord<?>) iValue).getIdentity().toString(iBuffer);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.link2string"),
            "Serialize link to string",
            timer);
        break;

      case EMBEDDEDSET:
        ORecordSerializerSchemaAware2CSV.INSTANCE.embeddedCollectionToStream(
            ODatabaseRecordThreadLocal.INSTANCE.getIfDefined(),
            null,
            iBuffer,
            null,
            null,
            iValue,
            null,
            true);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.embedSet2string"),
            "Serialize embeddedset to string",
            timer);
        break;

      case EMBEDDEDLIST:
        ORecordSerializerSchemaAware2CSV.INSTANCE.embeddedCollectionToStream(
            ODatabaseRecordThreadLocal.INSTANCE.getIfDefined(),
            null,
            iBuffer,
            null,
            null,
            iValue,
            null,
            true);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.embedList2string"),
            "Serialize embeddedlist to string",
            timer);
        break;

      case EMBEDDEDMAP:
        ORecordSerializerSchemaAware2CSV.INSTANCE.embeddedMapToStream(
            ODatabaseRecordThreadLocal.INSTANCE.getIfDefined(),
            null,
            iBuffer,
            null,
            null,
            iValue,
            null,
            true);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.embedMap2string"),
            "Serialize embeddedmap to string",
            timer);
        break;

      case EMBEDDED:
        OStringSerializerEmbedded.INSTANCE.toStream(iBuffer, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.embed2string"),
            "Serialize embedded to string",
            timer);
        break;

      case CUSTOM:
        OStringSerializerAnyStreamable.INSTANCE.toStream(iBuffer, iValue);
        PROFILER.stopChrono(
            PROFILER.getProcessMetric("serializer.record.string.custom2string"),
            "Serialize custom to string",
            timer);
        break;

      default:
        throw new IllegalArgumentException(
            "Type " + iType + " not supported to convert value: " + iValue);
    }
  }