core/src/main/java/com/orientechnologies/orient/core/serialization/serializer/record/binary/OBinaryComparatorV0.java
@Override
  public int compare(final OBinaryField iField1, final OBinaryField iField2) {
    final BytesContainer fieldValue1 = iField1.bytes;
    final int offset1 = fieldValue1.offset;

    final BytesContainer fieldValue2 = iField2.bytes;
    final int offset2 = fieldValue2.offset;

    try {
      switch (iField1.type) {
      case INTEGER: {
        final int value1 = OVarIntSerializer.readAsInteger(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Integer.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final int value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).intValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case LONG: {
        final long value1 = OVarIntSerializer.readAsLong(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Long.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final long value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).longValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case SHORT: {
        final short value1 = OVarIntSerializer.readAsShort(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Short.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final short value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).shortValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case STRING: {
        final String value1 = readString(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return value1.compareTo(Integer.toString(value2));
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return value1.compareTo(Long.toString(value2));
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return value1.compareTo(Long.toString(value2));
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return value1.compareTo(Short.toString(value2));
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return value1.compareTo(Byte.toString(value2));
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return value1.compareTo(Float.toString(value2));
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return value1.compareTo(Double.toString(value2));
        }
        case STRING: {
          final String value2 = readString(fieldValue2);

          final OCollate collate = (iField1.collate != null && !ODefaultCollate.NAME.equals(iField1.collate.getName())) ?
              iField1.collate :
              (iField2.collate != null && !ODefaultCollate.NAME.equals(iField2.collate.getName()) ? iField2.collate : null);

          if (collate != null) {
            final String str1 = (String) collate.transform(value1);
            final String str2 = (String) collate.transform(value2);
            return str1.compareTo(str2);
          }

          return value1.compareTo(value2);
        }
        case BOOLEAN: {
          final boolean value2 = readByte(fieldValue2) == 1;
          return value1.compareTo(Boolean.toString(value2));
        }
        case DECIMAL: {
          final BigDecimal value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset);
          return new BigDecimal(value1).compareTo(value2);
        }
        }
        break;
      }

      case DOUBLE: {
        final double value1 = Double.longBitsToDouble(readLong(fieldValue1));

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Double.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final double value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).doubleValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case FLOAT: {
        final float value1 = Float.intBitsToFloat(readInteger(fieldValue1));

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Float.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final String value2 = readString(fieldValue2);
          return Float.toString(value1).compareTo(value2);
        }
        }
        break;
      }

      case BYTE: {
        final byte value1 = readByte(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Byte.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final byte value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).byteValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case BOOLEAN: {
        final boolean value1 = readByte(fieldValue1) == 1;

        switch (iField2.type) {
        case BOOLEAN: {
          final boolean value2 = readByte(fieldValue2) == 1;
          return (value1 == value2) ? 0 : value1 ? 1 : -1;
        }
        case STRING: {
          final boolean value2 = Boolean.parseBoolean(readString(fieldValue2));
          return (value1 == value2) ? 0 : value1 ? 1 : -1;
        }
        }
        break;
      }

      case DATETIME: {
        final long value1 = OVarIntSerializer.readAsLong(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2AsString = readString(fieldValue2);

          if (OIOUtils.isLong(value2AsString)) {
            final long value2 = Long.parseLong(value2AsString);
            return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
          }

          final ODatabaseDocumentInternal db = ODatabaseRecordThreadLocal.instance().getIfDefined();
          try {
            final SimpleDateFormat dateFormat = db != null ?
                db.getStorage().getConfiguration().getDateTimeFormatInstance() :
                new SimpleDateFormat(OStorageConfiguration.DEFAULT_DATETIME_FORMAT);

            final Date value2AsDate = dateFormat.parse(value2AsString);
            final long value2 = value2AsDate.getTime();
            return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
          } catch (ParseException ignored) {
            try {
              final SimpleDateFormat dateFormat = db != null ?
                  db.getStorage().getConfiguration().getDateFormatInstance() :
                  new SimpleDateFormat(OStorageConfiguration.DEFAULT_DATE_FORMAT);

              final Date value2AsDate = dateFormat.parse(value2AsString);
              final long value2 = value2AsDate.getTime();
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            } catch (ParseException ignore) {
              return new Date(value1).toString().compareTo(value2AsString);
            }
          }
        }
        case DECIMAL: {
          final long value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).longValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case DATE: {
        final long value1 = OVarIntSerializer.readAsLong(fieldValue1) * MILLISEC_PER_DAY;

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2AsString = readString(fieldValue2);

          if (OIOUtils.isLong(value2AsString)) {
            final long value2 = Long.parseLong(value2AsString);
            return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
          }

          final ODatabaseDocumentInternal db = ODatabaseRecordThreadLocal.instance().getIfDefined();
          try {
            final SimpleDateFormat dateFormat = db != null ?
                db.getStorage().getConfiguration().getDateFormatInstance() :
                new SimpleDateFormat(OStorageConfiguration.DEFAULT_DATE_FORMAT);
            final Date value2AsDate = dateFormat.parse(value2AsString);
            long value2 = value2AsDate.getTime();
            value2 = convertDayToTimezone(ODateHelper.getDatabaseTimeZone(), TimeZone.getTimeZone("GMT"), value2);
            return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
          } catch (ParseException ignore) {
            try {
              final SimpleDateFormat dateFormat = db != null ?
                  db.getStorage().getConfiguration().getDateFormatInstance() :
                  new SimpleDateFormat(OStorageConfiguration.DEFAULT_DATETIME_FORMAT);

              final Date value2AsDate = dateFormat.parse(value2AsString);
              long value2 = value2AsDate.getTime();
              value2 = convertDayToTimezone(ODateHelper.getDatabaseTimeZone(), TimeZone.getTimeZone("GMT"), value2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            } catch (ParseException ignored) {
              return new Date(value1).toString().compareTo(value2AsString);
            }
          }
        }
        case DECIMAL: {
          final long value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).longValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case BINARY: {
        switch (iField2.type) {
        case BINARY: {
          final int length1 = OVarIntSerializer.readAsInteger(fieldValue1);
          final int length2 = OVarIntSerializer.readAsInteger(fieldValue2);

          final int max = Math.min(length1, length2);
          for (int i = 0; i < max; ++i) {
            final byte b1 = fieldValue1.bytes[fieldValue1.offset + i];
            final byte b2 = fieldValue2.bytes[fieldValue2.offset + i];

            if (b1 > b2)
              return 1;
            else if (b2 > b1)
              return -1;
          }

          if (length1 > length2)
            return 1;
          else if (length2 > length1)
            return -1;

          // EQUALS
          return 0;
        }
        }
        break;
      }

      case LINK: {
        switch (iField2.type) {
        case LINK: {
          final int clusterId1 = OVarIntSerializer.readAsInteger(fieldValue1);
          final int clusterId2 = OVarIntSerializer.readAsInteger(fieldValue2);
          if (clusterId1 > clusterId2)
            return 1;
          else if (clusterId1 < clusterId2)
            return -1;
          else {
            final long clusterPos1 = OVarIntSerializer.readAsLong(fieldValue1);
            final long clusterPos2 = OVarIntSerializer.readAsLong(fieldValue2);
            if (clusterPos1 > clusterPos2)
              return 1;
            else if (clusterPos1 < clusterPos2)
              return -1;
            return 0;
          }
        }

        case STRING: {
          return readOptimizedLink(fieldValue1, false).compareTo(new ORecordId(readString(fieldValue2)));
        }
        }
        break;
      }

      case DECIMAL: {
        final BigDecimal value1 = ODecimalSerializer.INSTANCE.deserialize(fieldValue1.bytes, fieldValue1.offset);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return value1.compareTo(new BigDecimal(value2));
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return value1.compareTo(new BigDecimal(value2));
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return value1.compareTo(new BigDecimal(value2));
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return value1.compareTo(new BigDecimal(value2));
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return value1.compareTo(new BigDecimal(value2));
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return value1.toString().compareTo(value2);
        }
        case DECIMAL: {
          final BigDecimal value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset);
          return value1.compareTo(value2);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return value1.compareTo(new BigDecimal(value2));
        }
        }
        break;
      }
      }
    } finally {
      fieldValue1.offset = offset1;
      fieldValue2.offset = offset2;
    }

    // NO COMPARE SUPPORTED, RETURN NON EQUALS
    return 1;
  }
@Override
  public int compare(final OBinaryField iField1, final OBinaryField iField2) {
    final BytesContainer fieldValue1 = iField1.bytes;
    final int offset1 = fieldValue1.offset;

    final BytesContainer fieldValue2 = iField2.bytes;
    final int offset2 = fieldValue2.offset;

    try {
      switch (iField1.type) {
      case INTEGER: {
        final int value1 = OVarIntSerializer.readAsInteger(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Integer.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final int value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).intValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case LONG: {
        final long value1 = OVarIntSerializer.readAsLong(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Long.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final long value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).longValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case SHORT: {
        final short value1 = OVarIntSerializer.readAsShort(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Short.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final short value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).shortValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case STRING: {
        final String value1 = readString(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return value1.compareTo(Integer.toString(value2));
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return value1.compareTo(Long.toString(value2));
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return value1.compareTo(Long.toString(value2));
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return value1.compareTo(Short.toString(value2));
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return value1.compareTo(Byte.toString(value2));
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return value1.compareTo(Float.toString(value2));
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return value1.compareTo(Double.toString(value2));
        }
        case STRING: {
          final String value2 = readString(fieldValue2);

          final OCollate collate = (iField1.collate != null && !ODefaultCollate.NAME.equals(iField1.collate.getName())) ?
              iField1.collate :
              (iField2.collate != null && !ODefaultCollate.NAME.equals(iField2.collate.getName()) ? iField2.collate : null);

          if (collate != null) {
            final String str1 = (String) collate.transform(value1);
            final String str2 = (String) collate.transform(value2);
            return str1.compareTo(str2);
          }

          return value1.compareTo(value2);
        }
        case BOOLEAN: {
          final boolean value2 = readByte(fieldValue2) == 1;
          return value1.compareTo(Boolean.toString(value2));
        }
        case DECIMAL: {
          final BigDecimal value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset);
          return new BigDecimal(value1).compareTo(value2);
        }
        }
        break;
      }

      case DOUBLE: {
        final double value1 = Double.longBitsToDouble(readLong(fieldValue1));

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Double.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final double value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).doubleValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case FLOAT: {
        final float value1 = Float.intBitsToFloat(readInteger(fieldValue1));

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Float.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final String value2 = readString(fieldValue2);
          return Float.toString(value1).compareTo(value2);
        }
        }
        break;
      }

      case BYTE: {
        final byte value1 = readByte(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return Byte.toString(value1).compareTo(value2);
        }
        case DECIMAL: {
          final byte value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).byteValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case BOOLEAN: {
        final boolean value1 = readByte(fieldValue1) == 1;

        switch (iField2.type) {
        case BOOLEAN: {
          final boolean value2 = readByte(fieldValue2) == 1;
          return (value1 == value2) ? 0 : value1 ? 1 : -1;
        }
        case STRING: {
          final boolean value2 = Boolean.parseBoolean(readString(fieldValue2));
          return (value1 == value2) ? 0 : value1 ? 1 : -1;
        }
        }
        break;
      }

      case DATETIME: {
        final long value1 = OVarIntSerializer.readAsLong(fieldValue1);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2AsString = readString(fieldValue2);

          if (OIOUtils.isLong(value2AsString)) {
            final long value2 = Long.parseLong(value2AsString);
            return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
          }

          final ODatabaseDocumentInternal db = ODatabaseRecordThreadLocal.instance().getIfDefined();
          try {
            final SimpleDateFormat dateFormat = db != null ?
                db.getStorage().getConfiguration().getDateTimeFormatInstance() :
                new SimpleDateFormat(OStorageConfiguration.DEFAULT_DATETIME_FORMAT);

            final Date value2AsDate = dateFormat.parse(value2AsString);
            final long value2 = value2AsDate.getTime();
            return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
          } catch (ParseException ignored) {
            try {
              final SimpleDateFormat dateFormat = db != null ?
                  db.getStorage().getConfiguration().getDateFormatInstance() :
                  new SimpleDateFormat(OStorageConfiguration.DEFAULT_DATE_FORMAT);

              final Date value2AsDate = dateFormat.parse(value2AsString);
              final long value2 = value2AsDate.getTime();
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            } catch (ParseException ignore) {
              return new Date(value1).toString().compareTo(value2AsString);
            }
          }
        }
        case DECIMAL: {
          final long value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).longValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case DATE: {
        final long value1 = OVarIntSerializer.readAsLong(fieldValue1) * MILLISEC_PER_DAY;

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DATE: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2) * MILLISEC_PER_DAY;
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        case STRING: {
          final String value2AsString = readString(fieldValue2);

          if (OIOUtils.isLong(value2AsString)) {
            final long value2 = Long.parseLong(value2AsString);
            return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
          }

          final ODatabaseDocumentInternal db = ODatabaseRecordThreadLocal.instance().getIfDefined();
          try {
            final SimpleDateFormat dateFormat = db != null ?
                db.getStorage().getConfiguration().getDateFormatInstance() :
                new SimpleDateFormat(OStorageConfiguration.DEFAULT_DATE_FORMAT);
            final Date value2AsDate = dateFormat.parse(value2AsString);
            long value2 = value2AsDate.getTime();
            value2 = convertDayToTimezone(ODateHelper.getDatabaseTimeZone(), TimeZone.getTimeZone("GMT"), value2);
            return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
          } catch (ParseException ignore) {
            try {
              final SimpleDateFormat dateFormat = db != null ?
                  db.getStorage().getConfiguration().getDateFormatInstance() :
                  new SimpleDateFormat(OStorageConfiguration.DEFAULT_DATETIME_FORMAT);

              final Date value2AsDate = dateFormat.parse(value2AsString);
              long value2 = value2AsDate.getTime();
              value2 = convertDayToTimezone(ODateHelper.getDatabaseTimeZone(), TimeZone.getTimeZone("GMT"), value2);
              return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
            } catch (ParseException ignored) {
              return new Date(value1).toString().compareTo(value2AsString);
            }
          }
        }
        case DECIMAL: {
          final long value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset).longValue();
          return (value1 < value2) ? -1 : ((value1 == value2) ? 0 : 1);
        }
        }
        break;
      }

      case BINARY: {
        switch (iField2.type) {
        case BINARY: {
          final int length1 = OVarIntSerializer.readAsInteger(fieldValue1);
          final int length2 = OVarIntSerializer.readAsInteger(fieldValue2);

          final int max = Math.min(length1, length2);
          for (int i = 0; i < max; ++i) {
            final byte b1 = fieldValue1.bytes[fieldValue1.offset + i];
            final byte b2 = fieldValue2.bytes[fieldValue2.offset + i];

            if (b1 > b2)
              return 1;
            else if (b2 > b1)
              return -1;
          }

          if (length1 > length2)
            return 1;
          else if (length2 > length1)
            return -1;

          // EQUALS
          return 0;
        }
        }
        break;
      }

      case LINK: {
        switch (iField2.type) {
        case LINK: {
          final int clusterId1 = OVarIntSerializer.readAsInteger(fieldValue1);
          final int clusterId2 = OVarIntSerializer.readAsInteger(fieldValue2);
          if (clusterId1 > clusterId2)
            return 1;
          else if (clusterId1 < clusterId2)
            return -1;
          else {
            final long clusterPos1 = OVarIntSerializer.readAsLong(fieldValue1);
            final long clusterPos2 = OVarIntSerializer.readAsLong(fieldValue2);
            if (clusterPos1 > clusterPos2)
              return 1;
            else if (clusterPos1 < clusterPos2)
              return -1;
            return 0;
          }
        }

        case STRING: {
          return readOptimizedLink(fieldValue1, false).compareTo(new ORecordId(readString(fieldValue2)));
        }
        }
        break;
      }

      case DECIMAL: {
        final BigDecimal value1 = ODecimalSerializer.INSTANCE.deserialize(fieldValue1.bytes, fieldValue1.offset);

        switch (iField2.type) {
        case INTEGER: {
          final int value2 = OVarIntSerializer.readAsInteger(fieldValue2);
          return value1.compareTo(new BigDecimal(value2));
        }
        case LONG:
        case DATETIME: {
          final long value2 = OVarIntSerializer.readAsLong(fieldValue2);
          return value1.compareTo(new BigDecimal(value2));
        }
        case SHORT: {
          final short value2 = OVarIntSerializer.readAsShort(fieldValue2);
          return value1.compareTo(new BigDecimal(value2));
        }
        case FLOAT: {
          final float value2 = Float.intBitsToFloat(readInteger(fieldValue2));
          return value1.compareTo(new BigDecimal(value2));
        }
        case DOUBLE: {
          final double value2 = Double.longBitsToDouble(readLong(fieldValue2));
          return value1.compareTo(new BigDecimal(value2));
        }
        case STRING: {
          final String value2 = readString(fieldValue2);
          return value1.toString().compareTo(value2);
        }
        case DECIMAL: {
          final BigDecimal value2 = ODecimalSerializer.INSTANCE.deserialize(fieldValue2.bytes, fieldValue2.offset);
          return value1.compareTo(value2);
        }
        case BYTE: {
          final byte value2 = readByte(fieldValue2);
          return value1.compareTo(new BigDecimal(value2));
        }
        }
        break;
      }
      }
    } finally {
      fieldValue1.offset = offset1;
      fieldValue2.offset = offset2;
    }

    // NO COMPARE SUPPORTED, RETURN NON EQUALS
    return 1;
  }
Compares two values executing also conversion between types.

@param iField1 First value to compare
@param iField2 Second value to compare

@return 0 if they matches, >0 if first value is major than second, <0 in case is minor