public static byte[] Serialize(this IColumnSpec columnSpec, object data)
        {
            byte[] rawData;
            switch (columnSpec.ColumnType)
            {
                case ColumnType.List:
                case ColumnType.Set:
                    var colType = columnSpec.CollectionValueType.ToType();
                    Type typedColl = typeof(CollectionAccessor<>).MakeGenericType(colType);
                    ICollectionAccessor coll = (ICollectionAccessor) Activator.CreateInstance(typedColl, data);
                    using (MemoryStream ms = new MemoryStream())
                    {
                        ms.WriteShort((short) coll.Count);
                        foreach (object elem in coll)
                        {
                            byte[] rawDataElem = Serialize(columnSpec.CollectionValueType, elem);
                            ms.WriteShortByteArray(rawDataElem);
                        }
                        rawData = ms.ToArray();
                    }
                    break;

                case ColumnType.Map:
                    IDictionary map = (IDictionary) data;
                    using (MemoryStream ms = new MemoryStream())
                    {
                        ms.WriteShort((short) map.Count);
                        foreach (DictionaryEntry de in map)
                        {
                            byte[] rawDataKey = Serialize(columnSpec.CollectionKeyType, de.Key);
                            ms.WriteShortByteArray(rawDataKey);
                            byte[] rawDataValue = Serialize(columnSpec.CollectionValueType, de.Value);
                            ms.WriteShortByteArray(rawDataValue);
                        }
                        rawData = ms.ToArray();
                    }
                    break;

                default:
                    rawData = Serialize(columnSpec.ColumnType, data);
                    break;
            }

            return rawData;
        }
        public static byte[] Serialize(this IColumnSpec columnSpec, object data)
        {
            byte[] rawData;
            switch (columnSpec.ColumnType)
            {
                case ColumnType.List:
                case ColumnType.Set:
                    ICollection coll = (ICollection) data;
                    using (MemoryStream ms = new MemoryStream())
                    {
                        ms.WriteShort((short) coll.Count);
                        foreach (object elem in coll)
                        {
                            byte[] rawDataElem = Serialize(columnSpec.CollectionValueType, elem);
                            ms.WriteShortByteArray(rawDataElem);
                        }
                        rawData = ms.ToArray();
                    }
                    break;

                case ColumnType.Map:
                    IDictionary map = (IDictionary) data;
                    using (MemoryStream ms = new MemoryStream())
                    {
                        ms.WriteShort((short) map.Count);
                        foreach (DictionaryEntry de in map)
                        {
                            byte[] rawDataKey = Serialize(columnSpec.CollectionKeyType, de.Key);
                            ms.WriteShortByteArray(rawDataKey);
                            byte[] rawDataValue = Serialize(columnSpec.CollectionValueType, de.Value);
                            ms.WriteShortByteArray(rawDataValue);
                        }
                        rawData = ms.ToArray();
                    }
                    break;

                default:
                    rawData = Serialize(columnSpec.ColumnType, data);
                    break;
            }

            return rawData;
        }
        public static byte[] SerializeSet(IHashSetAccessor data, Func<object, byte[]> valueSerializer)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ms.WriteUShort((ushort)data.Count);
                foreach (object elem in data)
                {
                    Console.WriteLine(elem);
                    ms.WriteShortByteArray(valueSerializer(elem));                    
                }

                Console.WriteLine(ms.Length);

                return ms.ToArray();
            }
        }
        public static byte[] SerializeList(IList data, Func<object, byte[]> valueSerializer)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ms.WriteUShort((ushort)data.Count);
                foreach (object elem in data)
                {
                    ms.WriteShortByteArray(valueSerializer(elem));
                }

                return ms.ToArray();
            }
        }
        public static byte[] SerializeMap(IDictionary data, Func<object, byte[]> keySerializer, Func<object, byte[]> valueSerializer)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                ms.WriteUShort((ushort)data.Count);
                foreach (DictionaryEntry de in data)
                {
                    ms.WriteShortByteArray(keySerializer(de.Key));
                    ms.WriteShortByteArray(valueSerializer(de.Value));
                }

                return ms.ToArray();
            }
        }
        public static byte[] Serialize(this CqlColumn cqlColumn, object data)
        {
            //null value check
            if (data == null)
                return null;

            byte[] rawData;
            switch (cqlColumn.CqlType)
            {
                case CqlType.List:
                case CqlType.Set:
                    if (!cqlColumn.CollectionValueType.HasValue)
                        throw new CqlException("CqlColumn collection type must has its value type set");

                    var coll = (IEnumerable)data;
                    using (var ms = new MemoryStream())
                    {
                        //write length placeholder
                        ms.Position = 2;
                        short count = 0;
                        foreach (object elem in coll)
                        {
                            byte[] rawDataElem = Serialize(cqlColumn.CollectionValueType.Value, elem);
                            ms.WriteShortByteArray(rawDataElem);
                            count++;
                        }
                        ms.Position = 0;
                        ms.WriteShort(count);
                        rawData = ms.ToArray();
                    }
                    break;

                case CqlType.Map:

                    if (!cqlColumn.CollectionKeyType.HasValue)
                        throw new CqlException("CqlColumn map type must has its key type set");

                    if (!cqlColumn.CollectionValueType.HasValue)
                        throw new CqlException("CqlColumn map type must has its value type set");

                    var map = (IDictionary)data;
                    using (var ms = new MemoryStream())
                    {
                        ms.WriteShort((short)map.Count);
                        foreach (DictionaryEntry de in map)
                        {
                            byte[] rawDataKey = Serialize(cqlColumn.CollectionKeyType.Value, de.Key);
                            ms.WriteShortByteArray(rawDataKey);
                            byte[] rawDataValue = Serialize(cqlColumn.CollectionValueType.Value, de.Value);
                            ms.WriteShortByteArray(rawDataValue);
                        }
                        rawData = ms.ToArray();
                    }
                    break;

                default:
                    rawData = Serialize(cqlColumn.CqlType, data);
                    break;
            }

            return rawData;
        }