public override void readWrite(Reader reader, int index, object[] versions)
        {
            if (reader.interrupted())
            {
                reader.resume();
            }

            if (IS_TOBJECT)
            {
                TObject[] objects = reader.readTObject();

                if (reader.interrupted())
                {
                    reader.interrupt(null);
                    return;
                }

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <T>)versions[i]).set(index, (T)(object)objects[i]);
                }
            }
            else if (typeof(T) == typeof(bool))
            {
                if (!reader.canReadBoolean())
                {
                    reader.interrupt(null);
                    return;
                }

                bool value = reader.readBoolean();

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <bool>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(byte))
            {
                if (!reader.canReadByte())
                {
                    reader.interrupt(null);
                    return;
                }

                byte value = reader.readByte();

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <byte>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(char))
            {
                if (!reader.canReadCharacter())
                {
                    reader.interrupt(null);
                    return;
                }

                char value = reader.readCharacter();

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <char>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(short))
            {
                if (!reader.canReadShort())
                {
                    reader.interrupt(null);
                    return;
                }

                short value = reader.readShort();

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <short>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(int))
            {
                if (!reader.canReadInteger())
                {
                    reader.interrupt(null);
                    return;
                }

                int value = reader.readInteger();

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <int>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(long))
            {
                if (!reader.canReadLong())
                {
                    reader.interrupt(null);
                    return;
                }

                long value = reader.readLong();

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <long>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(float))
            {
                if (!reader.canReadFloat())
                {
                    reader.interrupt(null);
                    return;
                }

                float value = reader.readFloat();

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <float>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(double))
            {
                if (!reader.canReadDouble())
                {
                    reader.interrupt(null);
                    return;
                }

                double value = reader.readDouble();

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <double>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(string))
            {
                string value = reader.readString();

                if (reader.interrupted())
                {
                    reader.interrupt(null);
                    return;
                }

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <string>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(System.DateTime?))
            {
                if (!reader.canReadDate())
                {
                    reader.interrupt(null);
                    return;
                }

                System.DateTime?value = reader.readDate();

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <System.DateTime?>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(System.Numerics.BigInteger?))
            {
                System.Numerics.BigInteger?value = reader.readBigInteger();

                if (reader.interrupted())
                {
                    reader.interrupt(null);
                    return;
                }

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <System.Numerics.BigInteger?>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(decimal?))
            {
                decimal?value = reader.readDecimal();

                if (reader.interrupted())
                {
                    reader.interrupt(null);
                    return;
                }

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <decimal?>)versions[i]).set(index, value);
                }
            }
            else if (typeof(T) == typeof(byte[]))
            {
                byte[] value = reader.readBinary();

                if (reader.interrupted())
                {
                    reader.interrupt(null);
                    return;
                }

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    ((TArrayVersion <byte[]>)versions[i]).set(index, value);
                }
            }
            else
            {
                object o = UnknownObjectSerializer.read(reader);

                if (reader.interrupted())
                {
                    reader.interrupt(null);
                    return;
                }

                for (int i = versions.Length - 1; i >= 0; i--)
                {
                    object value = o;

                    if (value is TObject[])
                    {
                        value = ((TObject[])value)[i];
                    }

                    ((TArrayVersion <T>)versions[i]).set(index, (T)value);
                }
            }
        }
        //

        public override void writeWrite(Writer writer, int index)
        {
            if (writer.interrupted())
            {
                writer.resume();
            }

            if (IS_TOBJECT)
            {
                writer.writeTObject((TObject)(object)get(index));

                if (writer.interrupted())
                {
                    writer.interrupt(null);
                    return;
                }
            }
            else if (typeof(T) == typeof(bool))
            {
                if (!writer.canWriteBoolean())
                {
                    writer.interrupt(null);
                    return;
                }

                TArrayVersion <bool> version = (TArrayVersion <bool>)(object) this;
                writer.writeBoolean(version.get(index));
            }
            else if (typeof(T) == typeof(byte))
            {
                if (!writer.canWriteByte())
                {
                    writer.interrupt(null);
                    return;
                }

                TArrayVersion <byte> version = (TArrayVersion <byte>)(object) this;
                writer.writeByte(version.get(index));
            }
            else if (typeof(T) == typeof(char))
            {
                if (!writer.canWriteCharacter())
                {
                    writer.interrupt(null);
                    return;
                }

                TArrayVersion <char> version = (TArrayVersion <char>)(object) this;
                writer.writeCharacter(version.get(index));
            }
            else if (typeof(T) == typeof(short))
            {
                if (!writer.canWriteShort())
                {
                    writer.interrupt(null);
                    return;
                }

                TArrayVersion <short> version = (TArrayVersion <short>)(object) this;
                writer.writeShort(version.get(index));
            }
            else if (typeof(T) == typeof(int))
            {
                if (!writer.canWriteInteger())
                {
                    writer.interrupt(null);
                    return;
                }

                TArrayVersion <int> version = (TArrayVersion <int>)(object) this;
                writer.writeInteger(version.get(index));
            }
            else if (typeof(T) == typeof(long))
            {
                if (!writer.canWriteLong())
                {
                    writer.interrupt(null);
                    return;
                }

                TArrayVersion <long> version = (TArrayVersion <long>)(object) this;
                writer.writeLong(version.get(index));
            }
            else if (typeof(T) == typeof(float))
            {
                if (!writer.canWriteFloat())
                {
                    writer.interrupt(null);
                    return;
                }

                TArrayVersion <float> version = (TArrayVersion <float>)(object) this;
                writer.writeFloat(version.get(index));
            }
            else if (typeof(T) == typeof(double))
            {
                if (!writer.canWriteDouble())
                {
                    writer.interrupt(null);
                    return;
                }

                TArrayVersion <double> version = (TArrayVersion <double>)(object) this;
                writer.writeDouble(version.get(index));
            }
            else if (typeof(T) == typeof(string))
            {
                TArrayVersion <string> version = (TArrayVersion <string>)(object) this;
                writer.writeString(version.get(index));

                if (writer.interrupted())
                {
                    writer.interrupt(null);
                    return;
                }
            }
            else if (typeof(T) == typeof(System.DateTime?))
            {
                if (!writer.canWriteDate())
                {
                    writer.interrupt(null);
                    return;
                }

                TArrayVersion <System.DateTime?> version = (TArrayVersion <System.DateTime?>)(object) this;
                writer.writeDate(version.get(index));
            }
            else if (typeof(T) == typeof(System.Numerics.BigInteger?))
            {
                TArrayVersion <System.Numerics.BigInteger?> version = (TArrayVersion <System.Numerics.BigInteger?>)(object) this;
                writer.writeBigInteger(version.get(index));

                if (writer.interrupted())
                {
                    writer.interrupt(null);
                    return;
                }
            }
            else if (typeof(T) == typeof(decimal?))
            {
                TArrayVersion <decimal?> version = (TArrayVersion <decimal?>)(object) this;
                writer.writeDecimal(version.get(index));

                if (writer.interrupted())
                {
                    writer.interrupt(null);
                    return;
                }
            }
            else if (typeof(T) == typeof(byte[]))
            {
                TArrayVersion <byte[]> version = (TArrayVersion <byte[]>)(object) this;
                writer.writeBinary(version.get(index));

                if (writer.interrupted())
                {
                    writer.interrupt(null);
                    return;
                }
            }
            else
            {
                UnknownObjectSerializer.write(writer, get(index));

                if (writer.interrupted())
                {
                    writer.interrupt(null);
                    return;
                }
            }
        }