public int Serialize(ref byte[] bytes, int offset, TCollection value, IFormatterResolver formatterResolver)
        {
            if (value == null)
            {
                return(MessagePackBinary.WriteNil(ref bytes, offset));
            }
            else
            {
                // Optimize iteration(array is fastest)
                var array = value as TElement[];
                if (array != null)
                {
                    var startOffset = offset;
                    var formatter   = formatterResolver.GetFormatterWithVerify <TElement>();

                    offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, array.Length);

                    foreach (var item in array)
                    {
                        offset += formatter.Serialize(ref bytes, offset, item, formatterResolver);
                    }

                    return(offset - startOffset);
                }
                else
                {
                    var startOffset = offset;
                    var formatter   = formatterResolver.GetFormatterWithVerify <TElement>();

                    // knows count or not.
                    var seqCount = GetCount(value);
                    if (seqCount != null)
                    {
                        offset += MessagePackBinary.WriteArrayHeader(ref bytes, offset, seqCount.Value);

                        // Unity's foreach struct enumerator causes boxing so iterate manually.
                        var e = GetSourceEnumerator(value);
                        try
                        {
                            while (e.MoveNext())
                            {
#if NETSTANDARD
                                offset += formatter.Serialize(ref bytes, offset, e.Current, formatterResolver);
#else
                                offset += formatter.Serialize(ref bytes, (int)offset, (TElement)e.Current, (IFormatterResolver)formatterResolver);
#endif
                            }
                        }
                        finally
                        {
                            e.Dispose();
                        }

                        return(offset - startOffset);
                    }
                    else
                    {
                        // write message first -> open header space -> write header
                        var writeStarOffset = offset;

                        var count     = 0;
                        var moveCount = 0;

                        // count = 16 <= 65535, header len is "3" so choose default space.
                        offset += 3;

                        var e = GetSourceEnumerator(value);
                        try
                        {
                            while (e.MoveNext())
                            {
                                count++;
#if NETSTANDARD
                                var writeSize = formatter.Serialize(ref bytes, offset, e.Current, formatterResolver);
#else
                                var writeSize = formatter.Serialize(ref bytes, (int)offset, (TElement)e.Current, (IFormatterResolver)formatterResolver);
#endif
                                moveCount += writeSize;
                                offset    += writeSize;
                            }
                        }
                        finally
                        {
                            e.Dispose();
                        }

                        var headerLength = MessagePackBinary.GetArrayHeaderLength(count);
                        if (headerLength != 3)
                        {
                            if (headerLength == 1)
                            {
                                offset -= 2;                    // 1
                            }
                            else
                            {
                                offset += 2;  // 5
                            }
                            MessagePackBinary.EnsureCapacity(ref bytes, offset, headerLength);
                            Buffer.BlockCopy(bytes, writeStarOffset + 3, bytes, writeStarOffset + headerLength, moveCount);
                        }
                        MessagePackBinary.WriteArrayHeader(ref bytes, writeStarOffset, count);

                        return(offset - startOffset);
                    }
                }
            }
        }