private int writeOType(BinaryBuffer buffer, Object value, OType valueType, OType?linkedType)
        {
            int pointer = 0;

            switch (valueType)
            {
            case OType.Integer:
            case OType.Long:
            case OType.Short:
                pointer = buffer.WriteVariant(Convert.ToInt32(value));
                break;

            case OType.String:
                pointer = buffer.Write((string)value);
                break;

            case OType.Double:
                pointer = buffer.Write((double)value);
                break;

            case OType.Float:
                pointer = buffer.Write((float)value);
                break;

            case OType.Byte:
                pointer = buffer.Write((byte)value);
                break;

            case OType.Boolean:
                pointer = buffer.Write(((bool)value) ? (byte)1 : (byte)0);
                break;

            case OType.DateTime:
                DateTime unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
                pointer = buffer.WriteVariant((long)((DateTime)value - unixEpoch).TotalMilliseconds);
                break;

            //case OType.Decimal:
            //    /*
            //     * The Decimal is converted to an integer and stored as scale and value
            //     * (example "10234.546" is stored as scale "3" and value as:"10234546")
            //     *  +---------------+-------------------+--------------+
            //     *  | scale:byte[4] | valueSize:byte[4] | value:byte[] |
            //     *  +---------------+-------------------+--------------+
            //     *  scale an 4 byte integer that represent the scale of the value
            //     *  valueSize the length of the value
            //     *  bytes value the bytes that represent the value of the   decimal in big-endian order.
            //     */
            //    var dec = ((decimal)value);
            //    byte[] bytes = BinarySerializer.ToArray(dec);
            //    var unscaledValueBytes = FromDecimal(dec);
            //    var unscaledValue = new BigInteger(unscaledValueBytes);
            //    break;
            case OType.Link:
                ORID rid = (ORID)value;
                pointer = buffer.Write(rid);
                break;

            case OType.LinkList:
            case OType.LinkSet:
                var col = (ICollection <ORID>)value;
                pointer = buffer.WriteVariant(col.Count);

                foreach (var item in col)
                {
                    if (item == null)
                    {
                        buffer.Write(NULL_RECORD_ID);
                    }
                    else
                    {
                        buffer.Write(item);
                    }
                }
                break;

            case OType.LinkBag:
                break;

            default:
                throw new NotImplementedException("Type " + valueType + " still not supported");
            }
            return(pointer);
        }
        private string SerializeObjectValue(object value, Type valueType)
        {
            StringBuilder bld = new StringBuilder();

            if ((valueType.IsArray) || (valueType.GetTypeInfo().IsGenericType))
            {
                if (valueType.Name == "Dictionary`2")
                {
                    bld.Append("{");

                    IDictionary <string, object> collection = (IDictionary <string, object>)value;

                    bool first = true;
                    foreach (var keyVal in collection)
                    {
                        if (!first)
                        {
                            bld.Append(",");
                        }

                        first = false;

                        string serialized = SerializeValue(keyVal.Value);
                        bld.Append("\"" + keyVal.Key + "\":" + serialized);
                    }

                    bld.Append("}");
                }
                else
                {
                    bld.Append(valueType.Name == "HashSet`1" ? "<" : "[");

                    IEnumerable collection = (IEnumerable)value;

                    bool first = true;
                    foreach (object val in collection)
                    {
                        if (!first)
                        {
                            bld.Append(",");
                        }

                        first = false;
                        bld.Append(SerializeValue(val));
                    }

                    bld.Append(valueType.Name == "HashSet`1" ? ">" : "]");
                }
            }
            // if property is ORID type it needs to be serialized as ORID
            else if (valueType.GetTypeInfo().IsClass&& (valueType.Name == "ORID"))
            {
                bld.Append(((ORID)value).RID);
            }
            else if (valueType.GetTypeInfo().IsClass&& (valueType.Name == "ODocument"))
            {
                var document  = (ODocument)value;
                var className = string.IsNullOrEmpty(document.OClassName) ? string.Empty : document.OClassName + "@";
                bld.AppendFormat("({0}{1})", className, SerializeDocument(document));
            }
            else if (valueType.GetTypeInfo().IsClass&& (valueType.Name == "OEmbeddedRidBag"))
            {
                //bld.AppendFormat("({0})", SerializeDocument((ODocument)value));
                OEmbeddedRidBag ridbag = (OEmbeddedRidBag)value;
                if (ridbag.Count > 0)
                {
                    BinaryBuffer buffer = new BinaryBuffer();
                    bld.Append("%");
                    buffer.Write((byte)1);      // config
                    buffer.Write(ridbag.Count); //size
                    foreach (var item in ridbag)
                    {
                        buffer.Write(item);
                    }
                    bld.Append(Convert.ToBase64String(buffer.ToArray()));
                    bld.Append(";");
                }
            }

            return(bld.ToString());
        }
        public byte[] Serialize(ODocument document)
        {
            var       buffer = new BinaryBuffer();
            ODocument schema = null; // Until Implementing schema this is null class

            // Version
            buffer.Add((byte)SERIALIZER_VERSION);

            // Class Name
            if (!String.IsNullOrEmpty(document.OClassName))
            {
                buffer.WriteVariant(document.OClassName.Length);
                var className = BinarySerializer.ToArray(document.OClassName);
                buffer.AddRange(className);
            }
            else
            {
                var length = BinarySerializer.ToArray((int)0);
                buffer.AddRange(length);
            }

            // Header
            var propNames = document.Keys.Where(k => !k.StartsWith("@")).ToArray();
            var pos       = new int[propNames.Length];
            var val       = new KeyValuePair <string, Object> [propNames.Length];

            for (var i = 0; i < propNames.Length; i++)
            {
                var prop = propNames[i];
                if (schema != null)
                {
                }
                else
                {
                    buffer.WriteVariant(prop.Length);
                    var propName = BinarySerializer.ToArray(prop);
                    buffer.AddRange(propName);
                    pos[i] = buffer.Allocate(sizeof(int) + 1);
                }
                val[i] = new KeyValuePair <string, object>(prop, document.GetField <object>(prop));
            }

            buffer.WriteVariant(0); // Header stop byte

            // Data
            for (int i = 0; i < val.Length; i++)
            {
                int pointer = 0;
                var value   = val[i].Value;
                if (value != null)
                {
                    var valueType = TypeConverter.TypeToDbName(value.GetType());
                    pointer = writeOType(buffer, value, valueType, getLinkedType(valueType, val[i].Key));
                    buffer.Write(pos[i], pointer);
                    if (schema == null)
                    {
                        buffer.Write((pos[i] + sizeof(int)), (byte)valueType);
                    }
                }
            }
            return(buffer.ToArray());
        }