/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.ignite.internal.marshaller.optimized;

import java.io.Externalizable;
import java.io.IOException;
import java.io.NotActiveException;
import java.io.NotSerializableException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.text.SimpleDateFormat;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.PriorityQueue;
import java.util.Properties;
import java.util.Queue;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.UUID;
import java.util.Vector;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.internal.util.io.GridUnsafeDataInput;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.marshaller.MarshallerContext;
import org.apache.ignite.marshaller.MarshallerContextTestImpl;
import org.apache.ignite.marshaller.MarshallerExclusions;
import org.apache.ignite.testframework.GridTestUtils;
import org.apache.ignite.testframework.junits.common.GridCommonAbstractTest;
import org.jetbrains.annotations.Nullable;
import org.junit.Test;

import static org.junit.Assert.assertArrayEquals;

/**
 * Test for optimized object streams.
 */
public class OptimizedObjectStreamSelfTest extends GridCommonAbstractTest {
    /** */
    private static final MarshallerContext CTX = new MarshallerContextTestImpl();

    /** */
    private ConcurrentMap<Class, OptimizedClassDescriptor> clsMap = new ConcurrentHashMap<>();

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testNull() throws Exception {
        assertNull(marshalUnmarshal(null));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testByte() throws Exception {
        byte val = 10;

        assertEquals(new Byte(val), marshalUnmarshal(val));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testShort() throws Exception {
        short val = 100;

        assertEquals(new Short(val), marshalUnmarshal(val));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testInteger() throws Exception {
        int val = 100;

        assertEquals(new Integer(val), marshalUnmarshal(val));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testLong() throws Exception {
        long val = 1000L;

        assertEquals(new Long(val), marshalUnmarshal(val));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testFloat() throws Exception {
        float val = 10.0f;

        assertEquals(val, marshalUnmarshal(val), 0);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testDouble() throws Exception {
        double val = 100.0d;

        assertEquals(val, marshalUnmarshal(val), 0);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testBoolean() throws Exception {
        assertEquals(Boolean.TRUE, marshalUnmarshal(Boolean.TRUE));

        assertEquals(Boolean.FALSE, marshalUnmarshal(Boolean.FALSE));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testChar() throws Exception {
        char val = 10;

        assertEquals(new Character(val), marshalUnmarshal(val));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testByteArray() throws Exception {
        byte[] arr = marshalUnmarshal(new byte[] {1, 2});

        assertArrayEquals(new byte[] {1, 2}, arr);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testShortArray() throws Exception {
        short[] arr = marshalUnmarshal(new short[] {1, 2});

        assertArrayEquals(new short[] {1, 2}, arr);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testIntArray() throws Exception {
        int[] arr = marshalUnmarshal(new int[] {1, 2});

        assertArrayEquals(new int[] {1, 2}, arr);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testLongArray() throws Exception {
        long[] arr = marshalUnmarshal(new long[] {1L, 2L});

        assertArrayEquals(new long[] {1, 2}, arr);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testFloatArray() throws Exception {
        float[] arr = marshalUnmarshal(new float[] {1.0f, 2.0f});

        assertArrayEquals(new float[] {1.0f, 2.0f}, arr, 0.1f);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testDoubleArray() throws Exception {
        double[] arr = marshalUnmarshal(new double[] {1.0d, 2.0d});

        assertArrayEquals(new double[] {1.0d, 2.0d}, arr, 0.1d);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testBooleanArray() throws Exception {
        boolean[] arr = marshalUnmarshal(new boolean[] {true, false, false});

        assertEquals(3, arr.length);
        assertEquals(true, arr[0]);
        assertEquals(false, arr[1]);
        assertEquals(false, arr[2]);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testCharArray() throws Exception {
        char[] arr = marshalUnmarshal(new char[] {1, 2});

        assertArrayEquals(new char[] {1, 2}, arr);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testObject() throws Exception {
        TestObject obj = new TestObject();

        obj.longVal = 100L;
        obj.doubleVal = 100.0d;
        obj.longArr = new Long[] {200L, 300L};
        obj.doubleArr = new Double[] {200.0d, 300.0d};

        assertEquals(obj, marshalUnmarshal(obj));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testRequireSerializable() throws Exception {
        try {
            OptimizedMarshaller marsh = new OptimizedMarshaller(true);

            marsh.setContext(CTX);

            marsh.marshal(new Object());

            assert false : "Exception not thrown.";
        }
        catch (IgniteCheckedException e) {
            NotSerializableException serEx = e.getCause(NotSerializableException.class);

            if (serEx == null)
                throw e;
        }
    }

    /**
     * Test informative exception message while failed object unmarshalling
     *
     * @throws Exception If failed.
     */
    @Test
    public void testFailedUnmarshallingLogging() throws Exception {
        OptimizedMarshaller marsh = new OptimizedMarshaller(true);

        marsh.setContext(CTX);

        try {
            marsh.unmarshal(marsh.marshal(new BadDeserializableObject()), null);
        }
        catch (IgniteCheckedException ex) {
            assertTrue(ex.getCause().getMessage().contains(
                "object [typeName=org.apache.ignite.internal.marshaller.optimized.OptimizedObjectStreamSelfTest$BadDeserializableObject]"));

            assertTrue(ex.getCause().getCause().getMessage().contains("field [name=val"));
        }
    }

    /**
     * Test informative exception message while failed object marshalling
     *
     * @throws Exception If failed.
     */
    @Test
    public void testFailedMarshallingLogging() throws Exception {
        OptimizedMarshaller marsh = new OptimizedMarshaller(true);

        marsh.setContext(CTX);

        try {
            marsh.marshal(new BadSerializableObject());
        }
        catch (IgniteCheckedException ex) {
            assertTrue(ex.getCause().getMessage().contains(
                "object [typeName=org.apache.ignite.internal.marshaller.optimized.OptimizedObjectStreamSelfTest$BadSerializableObject]"));

            assertTrue(ex.getCause().getCause().getMessage().contains("field [name=val"));
        }
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testPool() throws Exception {
        final TestObject obj = new TestObject();

        obj.longVal = 100L;
        obj.doubleVal = 100.0d;
        obj.longArr = new Long[100 * 1024];
        obj.doubleArr = new Double[100 * 1024];

        Arrays.fill(obj.longArr, 100L);
        Arrays.fill(obj.doubleArr, 100.0d);

        final OptimizedMarshaller marsh = new OptimizedMarshaller();

        marsh.setContext(CTX);

        marsh.setPoolSize(5);

        try {
            multithreaded(new Callable<Object>() {
                @Override public Object call() throws Exception {
                    for (int i = 0; i < 50; i++)
                        assertEquals(obj, marsh.unmarshal(marsh.marshal(obj), null));

                    return null;
                }
            }, 20);
        }
        finally {
            marsh.setPoolSize(0);
        }
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testObjectWithNulls() throws Exception {
        TestObject obj = new TestObject();

        obj.longVal = 100L;
        obj.longArr = new Long[] {200L, 300L};

        assertEquals(obj, marshalUnmarshal(obj));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testObjectArray() throws Exception {
        TestObject obj1 = new TestObject();

        obj1.longVal = 100L;
        obj1.doubleVal = 100.0d;
        obj1.longArr = new Long[] {200L, 300L};
        obj1.doubleArr = new Double[] {200.0d, 300.0d};

        TestObject obj2 = new TestObject();

        obj2.longVal = 400L;
        obj2.doubleVal = 400.0d;
        obj2.longArr = new Long[] {500L, 600L};
        obj2.doubleArr = new Double[] {500.0d, 600.0d};

        TestObject[] arr = {obj1, obj2};

        assertArrayEquals(arr, (Object[])marshalUnmarshal(arr));

        String[] strArr = {"str1", "str2"};

        assertArrayEquals(strArr, (String[])marshalUnmarshal(strArr));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testExternalizable() throws Exception {
        ExternalizableTestObject1 obj = new ExternalizableTestObject1();

        obj.longVal = 100L;
        obj.doubleVal = 100.0d;
        obj.longArr = new Long[] {200L, 300L};
        obj.doubleArr = new Double[] {200.0d, 300.0d};

        assertEquals(obj, marshalUnmarshal(obj));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testExternalizableWithNulls() throws Exception {
        ExternalizableTestObject2 obj = new ExternalizableTestObject2();

        obj.longVal = 100L;
        obj.doubleVal = 100.0d;
        obj.longArr = new Long[] {200L, 300L};
        obj.doubleArr = new Double[] {200.0d, 300.0d};

        obj = marshalUnmarshal(obj);

        assertEquals(100L, obj.longVal.longValue());
        assertNull(obj.doubleVal);
        assertArrayEquals(new Long[] {200L, 300L}, obj.longArr);
        assertNull(obj.doubleArr);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testLink() throws Exception {
        for (int i = 0; i < 20; i++) {
            LinkTestObject1 obj1 = new LinkTestObject1();
            LinkTestObject2 obj2 = new LinkTestObject2();
            LinkTestObject2 obj3 = new LinkTestObject2();

            obj1.val = 100;
            obj2.ref = obj1;
            obj3.ref = obj1;

            LinkTestObject2[] arr = new LinkTestObject2[] {obj2, obj3};

            assertArrayEquals(arr, (Object[])marshalUnmarshal(arr));
        }
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testCycleLink() throws Exception {
        for (int i = 0; i < 20; i++) {
            CycleLinkTestObject obj = new CycleLinkTestObject();

            obj.val = 100;
            obj.ref = obj;

            assertEquals(obj, marshalUnmarshal(obj));
        }
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testNoDefaultConstructor() throws Exception {
        NoDefaultConstructorTestObject obj = new NoDefaultConstructorTestObject(100);

        assertEquals(obj, marshalUnmarshal(obj));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testEnum() throws Exception {
        assertEquals(TestEnum.B, marshalUnmarshal(TestEnum.B));

        TestEnum[] arr = new TestEnum[] {TestEnum.C, TestEnum.A, TestEnum.B, TestEnum.A};

        assertArrayEquals(arr, (Object[])marshalUnmarshal(arr));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testCollection() throws Exception {
        TestObject obj1 = new TestObject();

        obj1.longVal = 100L;
        obj1.doubleVal = 100.0d;
        obj1.longArr = new Long[] {200L, 300L};
        obj1.doubleArr = new Double[] {200.0d, 300.0d};

        TestObject obj2 = new TestObject();

        obj2.longVal = 400L;
        obj2.doubleVal = 400.0d;
        obj2.longArr = new Long[] {500L, 600L};
        obj2.doubleArr = new Double[] {500.0d, 600.0d};

        Collection<TestObject> col = F.asList(obj1, obj2);

        assertEquals(col, marshalUnmarshal(col));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testMap() throws Exception {
        TestObject obj1 = new TestObject();

        obj1.longVal = 100L;
        obj1.doubleVal = 100.0d;
        obj1.longArr = new Long[] {200L, 300L};
        obj1.doubleArr = new Double[] {200.0d, 300.0d};

        TestObject obj2 = new TestObject();

        obj2.longVal = 400L;
        obj2.doubleVal = 400.0d;
        obj2.longArr = new Long[] {500L, 600L};
        obj2.doubleArr = new Double[] {500.0d, 600.0d};

        Map<Integer, TestObject> map = F.asMap(1, obj1, 2, obj2);

        assertEquals(map, marshalUnmarshal(map));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testUuid() throws Exception {
        UUID uuid = UUID.randomUUID();

        assertEquals(uuid, marshalUnmarshal(uuid));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testDate() throws Exception {
        Date date = new Date();

        assertEquals(date, marshalUnmarshal(date));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testTransient() throws Exception {
        TransientTestObject obj = marshalUnmarshal(new TransientTestObject(100, 200, "str1", "str2"));

        assertEquals(100, obj.val1);
        assertEquals(0, obj.val2);
        assertEquals("str1", obj.str1);
        assertNull(obj.str2);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testWriteReadObject() throws Exception {
        WriteReadTestObject obj = marshalUnmarshal(new WriteReadTestObject(100, "str"));

        assertEquals(100, obj.val);
        assertEquals("Optional data", obj.str);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testWriteReplace() throws Exception {
        ReplaceTestObject obj = marshalUnmarshal(new ReplaceTestObject(100));

        assertEquals(200, obj.value());
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testWriteReplaceNull() throws Exception {
        ReplaceNullTestObject obj = marshalUnmarshal(new ReplaceNullTestObject());

        assertNull(obj);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testReadResolve() throws Exception {
        ResolveTestObject obj = marshalUnmarshal(new ResolveTestObject(100));

        assertEquals(200, obj.value());
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testArrayDeque() throws Exception {
        Queue<Integer> queue = new ArrayDeque<>();

        for (int i = 0; i < 100; i++)
            queue.add(i);

        Queue<Integer> newQueue = marshalUnmarshal(queue);

        assertEquals(queue.size(), newQueue.size());

        Integer i;

        while ((i = newQueue.poll()) != null)
            assertEquals(queue.poll(), i);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testArrayList() throws Exception {
        Collection<Integer> list = new ArrayList<>();

        for (int i = 0; i < 100; i++)
            list.add(i);

        assertEquals(list, marshalUnmarshal(list));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testHashMap() throws Exception {
        Map<Integer, Integer> map = new HashMap<>();

        for (int i = 0; i < 100; i++)
            map.put(i, i);

        assertEquals(map, marshalUnmarshal(map));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testHashSet() throws Exception {
        Collection<Integer> set = new HashSet<>();

        for (int i = 0; i < 100; i++)
            set.add(i);

        assertEquals(set, marshalUnmarshal(set));
    }

    /**
     * @throws Exception If failed.
     */
    @SuppressWarnings("UseOfObsoleteCollectionType")
    @Test
    public void testHashtable() throws Exception {
        Map<Integer, Integer> map = new Hashtable<>();

        for (int i = 0; i < 100; i++)
            map.put(i, i);

        assertEquals(map, marshalUnmarshal(map));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testIdentityHashMap() throws Exception {
        Map<Integer, Integer> map = new IdentityHashMap<>();

        for (int i = 0; i < 100; i++)
            map.put(i, i);

        assertEquals(map, marshalUnmarshal(map));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testLinkedHashMap() throws Exception {
        Map<Integer, Integer> map = new LinkedHashMap<>();

        for (int i = 0; i < 100; i++)
            map.put(i, i);

        assertEquals(map, marshalUnmarshal(map));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testLinkedHashSet() throws Exception {
        Collection<Integer> set = new LinkedHashSet<>();

        for (int i = 0; i < 100; i++)
            set.add(i);

        assertEquals(set, marshalUnmarshal(set));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testLinkedList() throws Exception {
        Collection<Integer> list = new LinkedList<>();

        for (int i = 0; i < 100; i++)
            list.add(i);

        assertEquals(list, marshalUnmarshal(list));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testPriorityQueue() throws Exception {
        Queue<Integer> queue = new PriorityQueue<>();

        for (int i = 0; i < 100; i++)
            queue.add(i);

        Queue<Integer> newQueue = marshalUnmarshal(queue);

        assertEquals(queue.size(), newQueue.size());

        Integer i;

        while ((i = newQueue.poll()) != null)
            assertEquals(queue.poll(), i);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testProperties() throws Exception {
        Properties dflts = new Properties();

        dflts.setProperty("key1", "val1");
        dflts.setProperty("key2", "wrong");

        Properties props = new Properties(dflts);

        props.setProperty("key2", "val2");

        Properties newProps = marshalUnmarshal(props);

        assertEquals("val1", newProps.getProperty("key1"));
        assertEquals("val2", newProps.getProperty("key2"));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testTreeMap() throws Exception {
        Map<Integer, Integer> map = new TreeMap<>();

        for (int i = 0; i < 100; i++)
            map.put(i, i);

        assertEquals(map, marshalUnmarshal(map));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testTreeSet() throws Exception {
        Collection<Integer> set = new TreeSet<>();

        for (int i = 0; i < 100; i++)
            set.add(i);

        assertEquals(set, marshalUnmarshal(set));
    }

    /**
     * @throws Exception If failed.
     */
    @SuppressWarnings("UseOfObsoleteCollectionType")
    @Test
    public void testVector() throws Exception {
        Collection<Integer> vector = new Vector<>();

        for (int i = 0; i < 100; i++)
            vector.add(i);

        assertEquals(vector, marshalUnmarshal(vector));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testString() throws Exception {
        assertEquals("Latin", marshalUnmarshal("Latin"));
        assertEquals("Кириллица", marshalUnmarshal("Кириллица"));
        assertEquals("中国的", marshalUnmarshal("中国的"));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testReadLine() throws Exception {
        OptimizedObjectInputStream in = new OptimizedObjectInputStream(new GridUnsafeDataInput());

        byte[] bytes = "line1\nline2\r\nli\rne3\nline4".getBytes();

        in.in().bytes(bytes, bytes.length);

        assertEquals("line1", in.readLine());
        assertEquals("line2", in.readLine());
        assertEquals("line3", in.readLine());
        assertEquals("line4", in.readLine());
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testHierarchy() throws Exception {
        C c = new C(100, "str", 200, "str", 300, "str");

        C newC = marshalUnmarshal(c);

        assertEquals(100, newC.valueA());
        assertEquals("Optional data", newC.stringA());
        assertEquals(200, newC.valueB());
        assertNull(newC.stringB());
        assertEquals(0, newC.valueC());
        assertEquals("Optional data", newC.stringC());
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testInet4Address() throws Exception {
        Inet4Address addr = (Inet4Address)InetAddress.getByName("localhost");

        assertEquals(addr, marshalUnmarshal(addr));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testClass() throws Exception {
        assertEquals(int.class, marshalUnmarshal(int.class));
        assertEquals(Long.class, marshalUnmarshal(Long.class));
        assertEquals(TestObject.class, marshalUnmarshal(TestObject.class));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testWriteReadFields() throws Exception {
        WriteReadFieldsTestObject obj = marshalUnmarshal(new WriteReadFieldsTestObject(100, "str"));

        assertEquals(100, obj.val);
        assertEquals("Optional data", obj.str);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testWriteFields() throws Exception {
        WriteFieldsTestObject obj = marshalUnmarshal(new WriteFieldsTestObject(100, "str"));

        assertEquals(100, obj.val);
        assertEquals("Optional data", obj.str);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testBigInteger() throws Exception {
        BigInteger b = new BigInteger("54654865468745468465321414646834562346475457488");

        assertEquals(b, marshalUnmarshal(b));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testBigDecimal() throws Exception {
        BigDecimal b = new BigDecimal("849572389457208934572093574.123512938654126458542145");

        assertEquals(b, marshalUnmarshal(b));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testSimpleDateFormat() throws Exception {
        SimpleDateFormat f = new SimpleDateFormat("MM/dd/yyyy");

        assertEquals(f, marshalUnmarshal(f));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testComplexObject() throws Exception {
        ComplexTestObject obj = new ComplexTestObject();

        assertEquals(obj, marshalUnmarshal(obj));

        ExternalizableTestObject1 extObj1 = new ExternalizableTestObject1();

        extObj1.longVal = 1000L;
        extObj1.doubleVal = 1000.0d;
        extObj1.longArr = new Long[] {1000L, 2000L, 3000L};
        extObj1.doubleArr = new Double[] {1000.0d, 2000.0d, 3000.0d};

        ExternalizableTestObject1 extObj2 = new ExternalizableTestObject1();

        extObj2.longVal = 2000L;
        extObj2.doubleVal = 2000.0d;
        extObj2.longArr = new Long[] {4000L, 5000L, 6000L};
        extObj2.doubleArr = new Double[] {4000.0d, 5000.0d, 6000.0d};

        Properties props = new Properties();

        props.setProperty("name", "value");

        Collection<Integer> col = F.asList(10, 20, 30);

        Map<Integer, String> map = F.asMap(10, "str1", 20, "str2", 30, "str3");

        obj = new ComplexTestObject(
            (byte)1,
            (short)10,
            100,
            1000L,
            100.0f,
            1000.0d,
            'a',
            false,
            (byte)2,
            (short)20,
            200,
            2000L,
            200.0f,
            2000.0d,
            'b',
            true,
            new byte[] {1, 2, 3},
            new short[] {10, 20, 30},
            new int[] {100, 200, 300},
            new long[] {1000, 2000, 3000},
            new float[] {100.0f, 200.0f, 300.0f},
            new double[] {1000.0d, 2000.0d, 3000.0d},
            new char[] {'a', 'b', 'c'},
            new boolean[] {false, true},
            new ExternalizableTestObject1[] {extObj1, extObj2},
            "String",
            TestEnum.A,
            UUID.randomUUID(),
            props,
            new ArrayList<>(col),
            new HashMap<>(map),
            new HashSet<>(col),
            new LinkedList<>(col),
            new LinkedHashMap<>(map),
            new LinkedHashSet<>(col),
            new Date(),
            ExternalizableTestObject2.class
        );

        assertEquals(obj, marshalUnmarshal(obj));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testReadToArray() throws Exception {
        OptimizedObjectStreamRegistry reg = new OptimizedObjectSharedStreamRegistry();

        OptimizedObjectInputStream in = reg.in();

        try {
            byte[] arr = new byte[50];

            for (int i = 0; i < arr.length; i++)
                arr[i] = (byte)i;

            in.in().bytes(arr, arr.length);

            byte[] buf = new byte[10];

            assertEquals(10, in.read(buf));

            for (int i = 0; i < buf.length; i++)
                assertEquals(i, buf[i]);

            buf = new byte[30];

            assertEquals(20, in.read(buf, 0, 20));

            for (int i = 0; i < buf.length; i++)
                assertEquals(i < 20 ? 10 + i : 0, buf[i]);

            buf = new byte[30];

            assertEquals(10, in.read(buf, 10, 10));

            for (int i = 0; i < buf.length; i++)
                assertEquals(i >= 10 && i < 20 ? 30 + (i - 10) : 0, buf[i]);

            buf = new byte[20];

            assertEquals(10, in.read(buf));

            for (int i = 0; i < buf.length; i++)
                assertEquals(i < 10 ? 40 + i : 0, buf[i]);
        }
        finally {
            reg.closeIn(in);
        }
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testHandleTableGrow() throws Exception {
        List<String> c = new ArrayList<>();

        for (int i = 0; i < 29; i++)
            c.add("str");

        String str = c.get(28);

        c.add("str");
        c.add(str);

        List<Object> c0 = marshalUnmarshal(c);

        assertTrue(c0.get(28) == c0.get(30));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testIncorrectExternalizable() throws Exception {
        GridTestUtils.assertThrows(
            log,
            new Callable<Object>() {
                @Override public Object call() throws Exception {
                    return marshalUnmarshal(new IncorrectExternalizable());
                }
            },
            IOException.class,
            null);
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testExcludedClass() throws Exception {
        Class<?>[] exclClasses = U.staticField(MarshallerExclusions.class, "EXCL_CLASSES");

        assertFalse(F.isEmpty(exclClasses));

        for (Class<?> cls : exclClasses)
            assertEquals(cls, marshalUnmarshal(cls));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testInet6Address() throws Exception {
        final InetAddress address = Inet6Address.getByAddress(new byte[16]);

        assertEquals(address, marshalUnmarshal(address));
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testPutFieldsWithDefaultWriteObject() throws Exception {
        try {
            marshalUnmarshal(new CustomWriteObjectMethodObject("test"));
        }
        catch (IOException e) {
            assert e.getCause().getCause() instanceof NotActiveException;
        }
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testThrowable() throws Exception {
        Throwable t = new Throwable("Throwable");

        assertEquals(t.getMessage(), ((Throwable)marshalUnmarshal(t)).getMessage());
    }

    /**
     * @throws Exception If failed.
     */
    @Test
    public void testNestedReadWriteObject() throws Exception {
        NestedReadWriteObject[] arr = new NestedReadWriteObject[5];

        arr[0] = new NestedReadWriteObject(null, null, 1, "n1");
        arr[1] = new NestedReadWriteObject(arr[0], null, 2, "n2");
        arr[2] = new NestedReadWriteObject(null, arr[0], 3, "n3");
        arr[3] = new NestedReadWriteObject(arr[1], arr[2], 4, "n4");
        arr[4] = new NestedReadWriteObject(arr[3], arr[0], 5, "n4");

        assertTrue(Objects.deepEquals(arr, marshalUnmarshal(arr)));
    }

    /**
     * Marshals and unmarshals object.
     *
     * @param obj Original object.
     * @return Object after marshalling and unmarshalling.
     * @throws Exception In case of error.
     */
    private <T> T marshalUnmarshal(@Nullable Object obj) throws Exception {
        OptimizedObjectOutputStream out = null;
        OptimizedObjectInputStream in = null;

        OptimizedObjectStreamRegistry reg = new OptimizedObjectSharedStreamRegistry();

        try {
            out = reg.out();

            out.context(clsMap, CTX, null, true);

            out.writeObject(obj);

            byte[] arr = out.out().array();

            in = reg.in();

            in.context(clsMap, CTX, null, getClass().getClassLoader(), true);

            in.in().bytes(arr, arr.length);

            Object obj0 = in.readObject();

            checkHandles(out, in);

            return (T)obj0;
        }
        finally {
            reg.closeOut(out);
            reg.closeIn(in);
        }
    }

    /**
     * Checks that handles are equal in output and input streams.
     *
     * @param out Output stream.
     * @param in Input stream.
     */
    private void checkHandles(OptimizedObjectOutputStream out, OptimizedObjectInputStream in) {
        Object[] outHandles = out.handledObjects();
        Object[] inHandles = in.handledObjects();

        assertEquals(outHandles.length, inHandles.length);

        for (int i = 0; i < outHandles.length; i++) {
            if (outHandles[i] == null)
                assertTrue(inHandles[i] == null);
            else {
                assertFalse(inHandles[i] == null);

                assertTrue(outHandles[i].getClass() == inHandles[i].getClass());
            }
        }
    }

    /** */
    private static class IncorrectExternalizable implements Externalizable {
        /**
         * Required by {@link Externalizable}.
         */
        public IncorrectExternalizable() {
            // No-op.
        }

        /** {@inheritDoc} */
        @Override public void writeExternal(ObjectOutput out) throws IOException {
            out.writeInt(0);
            out.writeInt(200);
            out.writeObject("str");
        }

        /** {@inheritDoc} */
        @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            in.readInt();
            in.readObject();
        }
    }

    /**
     * Test object.
     */
    private static class TestObject implements Serializable {
        /** */
        private Long longVal;

        /** */
        private Double doubleVal;

        /** */
        private Long[] longArr;

        /** */
        private Double[] doubleArr;

        /** {@inheritDoc} */
        @Override public boolean equals(Object o) {
            if (this == o)
                return true;

            if (o == null || getClass() != o.getClass())
                return false;

            TestObject obj = (TestObject)o;

            return longVal != null ? longVal.equals(obj.longVal) : obj.longVal == null &&
                doubleVal != null ? doubleVal.equals(obj.doubleVal) : obj.doubleVal == null &&
                Arrays.equals(longArr, obj.longArr) &&
                Arrays.equals(doubleArr, obj.doubleArr);
        }
    }

    /**
     * Externalizable test object.
     */
    private static class ExternalizableTestObject1 implements Externalizable {
        /** */
        private Long longVal;

        /** */
        private Double doubleVal;

        /** */
        private Long[] longArr;

        /** */
        private Double[] doubleArr;

        /**
         * Required by {@link Externalizable}.
         */
        public ExternalizableTestObject1() {
            // No-op.
        }

        /** {@inheritDoc} */
        @Override public boolean equals(Object o) {
            if (this == o)
                return true;

            if (o == null || getClass() != o.getClass())
                return false;

            ExternalizableTestObject1 obj = (ExternalizableTestObject1)o;

            return longVal != null ? longVal.equals(obj.longVal) : obj.longVal == null &&
                doubleVal != null ? doubleVal.equals(obj.doubleVal) : obj.doubleVal == null &&
                Arrays.equals(longArr, obj.longArr) &&
                Arrays.equals(doubleArr, obj.doubleArr);
        }

        /** {@inheritDoc} */
        @Override public void writeExternal(ObjectOutput out) throws IOException {
            out.writeLong(longVal);
            out.writeDouble(doubleVal);
            U.writeArray(out, longArr);
            U.writeArray(out, doubleArr);
        }

        /** {@inheritDoc} */
        @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            longVal = in.readLong();
            doubleVal = in.readDouble();

            Object[] arr = U.readArray(in);

            longArr = Arrays.copyOf(arr, arr.length, Long[].class);

            arr = U.readArray(in);

            doubleArr = Arrays.copyOf(arr, arr.length, Double[].class);
        }
    }

    /**
     * Externalizable test object.
     */
    private static class ExternalizableTestObject2 implements Externalizable {
        /** */
        private Long longVal;

        /** */
        private Double doubleVal;

        /** */
        private Long[] longArr;

        /** */
        private Double[] doubleArr;

        /**
         * Required by {@link Externalizable}.
         */
        public ExternalizableTestObject2() {
            // No-op.
        }

        /** {@inheritDoc} */
        @Override public boolean equals(Object o) {
            if (this == o)
                return true;

            if (o == null || getClass() != o.getClass())
                return false;

            ExternalizableTestObject2 obj = (ExternalizableTestObject2)o;

            return longVal != null ? longVal.equals(obj.longVal) : obj.longVal == null &&
                doubleVal != null ? doubleVal.equals(obj.doubleVal) : obj.doubleVal == null &&
                Arrays.equals(longArr, obj.longArr) &&
                Arrays.equals(doubleArr, obj.doubleArr);
        }

        /** {@inheritDoc} */
        @Override public void writeExternal(ObjectOutput out) throws IOException {
            out.writeLong(longVal);
            U.writeArray(out, longArr);
        }

        /** {@inheritDoc} */
        @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            longVal = in.readLong();

            Object[] arr = U.readArray(in);

            longArr = Arrays.copyOf(arr, arr.length, Long[].class);
        }
    }

    /**
     * Test object.
     */
    private static class LinkTestObject1 implements Serializable {
        /** */
        private int val;

        /** {@inheritDoc} */
        @Override public boolean equals(Object o) {
            if (this == o)
                return true;

            if (o == null || getClass() != o.getClass())
                return false;

            LinkTestObject1 obj = (LinkTestObject1)o;

            return val == obj.val;
        }
    }

    /**
     * Test object.
     */
    private static class LinkTestObject2 implements Serializable {
        /** */
        private LinkTestObject1 ref;

        /** {@inheritDoc} */
        @Override public boolean equals(Object o) {
            if (this == o)
                return true;

            if (o == null || getClass() != o.getClass())
                return false;

            LinkTestObject2 obj = (LinkTestObject2)o;

            return ref != null ? ref.equals(obj.ref) : obj.ref == null;
        }
    }

    /**
     * Cycle link test object.
     */
    private static class CycleLinkTestObject implements Serializable {
        /** */
        private int val;

        /** */
        private CycleLinkTestObject ref;

        /** {@inheritDoc} */
        @Override public boolean equals(Object o) {
            if (this == o)
                return true;

            if (o == null || getClass() != o.getClass())
                return false;

            CycleLinkTestObject obj = (CycleLinkTestObject)o;

            return val == obj.val && ref != null ? ref.val == val : obj.ref == null;
        }
    }

    /**
     * Test object without default constructor.
     */
    private static class NoDefaultConstructorTestObject implements Serializable {
        /** */
        private int val;

        /**
         * @param val Value.
         */
        private NoDefaultConstructorTestObject(int val) {
            this.val = val;
        }

        /** {@inheritDoc} */
        @Override public boolean equals(Object o) {
            if (this == o)
                return true;

            if (o == null || getClass() != o.getClass())
                return false;

            NoDefaultConstructorTestObject obj = (NoDefaultConstructorTestObject)o;

            return val == obj.val;
        }
    }

    /**
     * Test object with transient fields.
     */
    @SuppressWarnings("TransientFieldNotInitialized")
    private static class TransientTestObject implements Serializable {
        /** */
        private int val1;

        /** */
        private transient int val2;

        /** */
        private String str1;

        /** */
        private transient String str2;

        /**
         * @param val1 Value 1.
         * @param val2 Value 2.
         * @param str1 String 1.
         * @param str2 String 2.
         */
        private TransientTestObject(int val1, int val2, String str1, String str2) {
            this.val1 = val1;
            this.val2 = val2;
            this.str1 = str1;
            this.str2 = str2;
        }
    }

    /**
     * Test object with {@code writeObject} and {@code readObject} methods.
     */
    private static class WriteReadTestObject implements Serializable {
        /** */
        private int val;

        /** */
        private transient String str;

        /**
         * @param val Value.
         * @param str String.
         */
        private WriteReadTestObject(int val, String str) {
            this.val = val;
            this.str = str;
        }

        /**
         * @param out Output stream.
         * @throws IOException In case of error.
         */
        private void writeObject(ObjectOutputStream out) throws IOException {
            out.defaultWriteObject();

            out.writeUTF("Optional data");
        }

        /**
         * @param in Input stream.
         * @throws IOException In case of error.
         * @throws ClassNotFoundException If class not found.
         */
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            in.defaultReadObject();

            str = in.readUTF();
        }
    }

    /**
     * Test object that uses {@code writeFields} and {@code readFields} methods.
     */
    private static class WriteReadFieldsTestObject implements Serializable {
        /** */
        private int val;

        /** */
        private String str;

        /**
         * @param val Value.
         * @param str String.
         */
        private WriteReadFieldsTestObject(int val, String str) {
            this.val = val;
            this.str = str;
        }

        /**
         * @param out Output stream.
         * @throws IOException In case of error.
         */
        private void writeObject(ObjectOutputStream out) throws IOException {
            ObjectOutputStream.PutField fields = out.putFields();

            fields.put("val", val);
            fields.put("str", "Optional data");

            out.writeFields();
        }

        /**
         * @param in Input stream.
         * @throws IOException In case of error.
         * @throws ClassNotFoundException If class not found.
         */
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            ObjectInputStream.GetField fields = in.readFields();

            val = fields.get("val", 0);
            str = (String)fields.get("str", null);
        }
    }

    /**
     * Test object that uses {@code writeFields} and {@code readFields} methods.
     */
    private static class WriteFieldsTestObject implements Serializable {
        /** */
        private int val;

        /** */
        private String str;

        /**
         * @param val Value.
         * @param str String.
         */
        private WriteFieldsTestObject(int val, String str) {
            this.val = val;
            this.str = str;
        }

        /**
         * @param out Output stream.
         * @throws IOException In case of error.
         */
        private void writeObject(ObjectOutputStream out) throws IOException {
            ObjectOutputStream.PutField fields = out.putFields();

            fields.put("val", val);
            fields.put("str", "Optional data");

            out.writeFields();
        }
    }

    /**
     * Base object with {@code writeReplace} method.
     */
    private abstract static class ReplaceTestBaseObject implements Serializable {
        /** */
        private int val;

        /**
         * @param val Value.
         */
        private ReplaceTestBaseObject(int val) {
            this.val = val;
        }

        /**
         * @return Value.
         */
        public int value() {
            return val;
        }

        /**
         * @return Replaced object.
         * @throws ObjectStreamException In case of error.
         */
        protected Object writeReplace() throws ObjectStreamException {
            return new ReplaceTestObject(val * 2);
        }
    }

    /**
     * Test object for {@code writeReplace} method.
     */
    private static class ReplaceTestObject extends ReplaceTestBaseObject {
        /**
         * @param val Value.
         */
        private ReplaceTestObject(int val) {
            super(val);
        }
    }

    /**
     * Test object with {@code writeReplace} method.
     */
    private static class ReplaceNullTestObject implements Serializable {
        /**
         * @return Replaced object.
         * @throws ObjectStreamException In case of error.
         */
        protected Object writeReplace() throws ObjectStreamException {
            return null;
        }
    }

    /**
     * Base object with {@code readResolve} method.
     */
    private abstract static class ResolveTestBaseObject implements Serializable {
        /** */
        private int val;

        /**
         * @param val Value.
         */
        private ResolveTestBaseObject(int val) {
            this.val = val;
        }

        /**
         * @return Value.
         */
        public int value() {
            return val;
        }

        /**
         * @return Replaced object.
         * @throws ObjectStreamException In case of error.
         */
        protected Object readResolve() throws ObjectStreamException {
            return new ResolveTestObject(val * 2);
        }
    }

    /**
     * Test object for {@code readResolve} method.
     */
    private static class ResolveTestObject extends ResolveTestBaseObject {
        /**
         * @param val Value.
         */
        private ResolveTestObject(int val) {
            super(val);
        }
    }

    /**
     * Class A.
     */
    private static class A implements Serializable {
        /** */
        private int valA;

        /** */
        private transient String strA;

        /**
         * @param valA Value A.
         * @param strA String A.
         */
        A(int valA, String strA) {
            this.valA = valA;
            this.strA = strA;
        }

        /**
         * @return Value.
         */
        int valueA() {
            return valA;
        }

        /**
         * @return String.
         */
        String stringA() {
            return strA;
        }

        /**
         * @param out Output stream.
         * @throws IOException In case of error.
         */
        private void writeObject(ObjectOutputStream out) throws IOException {
            out.writeObject("Optional data");

            out.defaultWriteObject();
        }

        /**
         * @param in Input stream.
         * @throws IOException In case of error.
         * @throws ClassNotFoundException If class not found.
         */
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            strA = (String)in.readObject();

            in.defaultReadObject();
        }
    }

    /**
     * Class B.
     */
    private static class B extends A {
        /** */
        private int valB;

        /** */
        @SuppressWarnings("TransientFieldNotInitialized")
        private transient String strB;

        /**
         * @param valA Value A.
         * @param strA String A.
         * @param valB Value B.
         * @param strB String B.
         */
        B(int valA, String strA, int valB, String strB) {
            super(valA, strA);

            this.valB = valB;
            this.strB = strB;
        }

        /**
         * @return Value.
         */
        int valueB() {
            return valB;
        }

        /**
         * @return String.
         */
        String stringB() {
            return strB;
        }
    }

    /**
     * Class C.
     */
    private static class C extends B {
        /** */
        @SuppressWarnings("InstanceVariableMayNotBeInitializedByReadObject")
        private int valC;

        /** */
        private transient String strC;

        /**
         * @param valA Value A.
         * @param strA String A.
         * @param valB Value B.
         * @param strB String B.
         * @param valC Value C.
         * @param strC String C.
         */
        C(int valA, String strA, int valB, String strB, int valC, String strC) {
            super(valA, strA, valB, strB);

            this.valC = valC;
            this.strC = strC;
        }

        /**
         * @return Value.
         */
        int valueC() {
            return valC;
        }

        /**
         * @return String.
         */
        String stringC() {
            return strC;
        }

        /**
         * @param out Output stream.
         * @throws IOException In case of error.
         */
        private void writeObject(ObjectOutputStream out) throws IOException {
            out.writeUTF("Optional data");
        }

        /**
         * @param in Input stream.
         * @throws IOException In case of error.
         * @throws ClassNotFoundException If class not found.
         */
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            strC = in.readUTF();
        }
    }

    /**
     * Complex test object.
     */
    private static class ComplexTestObject implements Serializable {
        /** */
        private byte byteVal1;

        /** */
        private short shortVal1;

        /** */
        private int intVal1;

        /** */
        private long longVal1;

        /** */
        private float floatVal1;

        /** */
        private double doubleVal1;

        /** */
        private char cVal1;

        /** */
        private boolean boolVal1;

        /** */
        private Byte byteVal2;

        /** */
        private Short shortVal2;

        /** */
        private Integer intVal2;

        /** */
        private Long longVal2;

        /** */
        private Float floatVal2;

        /** */
        private Double doubleVal2;

        /** */
        private Character cVal2;

        /** */
        private Boolean boolVal2;

        /** */
        private byte[] byteArr;

        /** */
        private short[] shortArr;

        /** */
        private int[] intArr;

        /** */
        private long[] longArr;

        /** */
        private float[] floatArr;

        /** */
        private double[] doubleArr;

        /** */
        private char[] cArr;

        /** */
        private boolean[] boolArr;

        /** */
        private ExternalizableTestObject1[] objArr;

        /** */
        private String str;

        /** */
        private TestEnum enumVal;

        /** */
        private UUID uuid;

        /** */
        private Properties props;

        /** */
        private ArrayList<Integer> arrList;

        /** */
        private HashMap<Integer, String> hashMap;

        /** */
        private HashSet<Integer> hashSet;

        /** */
        private LinkedList<Integer> linkedList;

        /** */
        private LinkedHashMap<Integer, String> linkedHashMap;

        /** */
        private LinkedHashSet<Integer> linkedHashSet;

        /** */
        private Date date;

        /** */
        private Class<?> cls;

        /** */
        private ComplexTestObject self;

        /** */
        private ComplexTestObject() {
            self = this;
        }

        /**
         * @param byteVal1 Byte value.
         * @param shortVal1 Short value.
         * @param intVal1 Integer value.
         * @param longVal1 Long value.
         * @param floatVal1 Float value.
         * @param doubleVal1 Double value.
         * @param cVal1 Char value.
         * @param boolVal1 Boolean value.
         * @param byteVal2 Byte value.
         * @param shortVal2 Short value.
         * @param intVal2 Integer value.
         * @param longVal2 Long value.
         * @param floatVal2 Float value.
         * @param doubleVal2 Double value.
         * @param cVal2 Char value.
         * @param boolVal2 Boolean value.
         * @param byteArr Bytes array.
         * @param shortArr Shorts array.
         * @param intArr Integers array.
         * @param longArr Longs array.
         * @param floatArr Floats array.
         * @param doubleArr Doubles array.
         * @param cArr Chars array.
         * @param boolArr Booleans array.
         * @param objArr Objects array.
         * @param str String.
         * @param enumVal Enum.
         * @param uuid UUID.
         * @param props Properties.
         * @param arrList ArrayList.
         * @param hashMap HashMap.
         * @param hashSet HashSet.
         * @param linkedList LinkedList.
         * @param linkedHashMap LinkedHashMap.
         * @param linkedHashSet LinkedHashSet.
         * @param date Date.
         * @param cls Class.
         */
        private ComplexTestObject(byte byteVal1, short shortVal1, int intVal1, long longVal1, float floatVal1,
            double doubleVal1, char cVal1, boolean boolVal1, Byte byteVal2, Short shortVal2, Integer intVal2,
            Long longVal2, Float floatVal2, Double doubleVal2, Character cVal2, Boolean boolVal2, byte[] byteArr,
            short[] shortArr, int[] intArr, long[] longArr, float[] floatArr, double[] doubleArr, char[] cArr,
            boolean[] boolArr, ExternalizableTestObject1[] objArr, String str, TestEnum enumVal, UUID uuid,
            Properties props, ArrayList<Integer> arrList, HashMap<Integer, String> hashMap, HashSet<Integer> hashSet,
            LinkedList<Integer> linkedList, LinkedHashMap<Integer, String> linkedHashMap,
            LinkedHashSet<Integer> linkedHashSet, Date date, Class<?> cls) {
            this.byteVal1 = byteVal1;
            this.shortVal1 = shortVal1;
            this.intVal1 = intVal1;
            this.longVal1 = longVal1;
            this.floatVal1 = floatVal1;
            this.doubleVal1 = doubleVal1;
            this.cVal1 = cVal1;
            this.boolVal1 = boolVal1;
            this.byteVal2 = byteVal2;
            this.shortVal2 = shortVal2;
            this.intVal2 = intVal2;
            this.longVal2 = longVal2;
            this.floatVal2 = floatVal2;
            this.doubleVal2 = doubleVal2;
            this.cVal2 = cVal2;
            this.boolVal2 = boolVal2;
            this.byteArr = byteArr;
            this.shortArr = shortArr;
            this.intArr = intArr;
            this.longArr = longArr;
            this.floatArr = floatArr;
            this.doubleArr = doubleArr;
            this.cArr = cArr;
            this.boolArr = boolArr;
            this.objArr = objArr;
            this.str = str;
            this.enumVal = enumVal;
            this.uuid = uuid;
            this.props = props;
            this.arrList = arrList;
            this.hashMap = hashMap;
            this.hashSet = hashSet;
            this.linkedList = linkedList;
            this.linkedHashMap = linkedHashMap;
            this.linkedHashSet = linkedHashSet;
            this.date = date;
            this.cls = cls;

            self = this;
        }

        /** {@inheritDoc} */
        @SuppressWarnings("RedundantIfStatement")
        @Override public boolean equals(Object o) {
            if (this == o)
                return true;

            if (o == null || getClass() != o.getClass())
                return false;

            ComplexTestObject obj = (ComplexTestObject)o;

            if (boolVal1 != obj.boolVal1)
                return false;

            if (byteVal1 != obj.byteVal1)
                return false;

            if (cVal1 != obj.cVal1)
                return false;

            if (Double.compare(obj.doubleVal1, doubleVal1) != 0)
                return false;

            if (Float.compare(obj.floatVal1, floatVal1) != 0)
                return false;

            if (intVal1 != obj.intVal1)
                return false;

            if (longVal1 != obj.longVal1)
                return false;

            if (shortVal1 != obj.shortVal1)
                return false;

            if (arrList != null ? !arrList.equals(obj.arrList) : obj.arrList != null)
                return false;

            if (!Arrays.equals(boolArr, obj.boolArr))
                return false;

            if (boolVal2 != null ? !boolVal2.equals(obj.boolVal2) : obj.boolVal2 != null)
                return false;

            if (!Arrays.equals(byteArr, obj.byteArr))
                return false;

            if (byteVal2 != null ? !byteVal2.equals(obj.byteVal2) : obj.byteVal2 != null)
                return false;

            if (!Arrays.equals(cArr, obj.cArr))
                return false;

            if (cVal2 != null ? !cVal2.equals(obj.cVal2) : obj.cVal2 != null)
                return false;

            if (cls != null ? !cls.equals(obj.cls) : obj.cls != null)
                return false;

            if (date != null ? !date.equals(obj.date) : obj.date != null)
                return false;

            if (!Arrays.equals(doubleArr, obj.doubleArr))
                return false;

            if (doubleVal2 != null ? !doubleVal2.equals(obj.doubleVal2) : obj.doubleVal2 != null)
                return false;

            if (enumVal != obj.enumVal)
                return false;

            if (!Arrays.equals(floatArr, obj.floatArr))
                return false;

            if (floatVal2 != null ? !floatVal2.equals(obj.floatVal2) : obj.floatVal2 != null)
                return false;

            if (hashMap != null ? !hashMap.equals(obj.hashMap) : obj.hashMap != null)
                return false;

            if (hashSet != null ? !hashSet.equals(obj.hashSet) : obj.hashSet != null)
                return false;

            if (!Arrays.equals(intArr, obj.intArr))
                return false;

            if (intVal2 != null ? !intVal2.equals(obj.intVal2) : obj.intVal2 != null)
                return false;

            if (linkedHashMap != null ? !linkedHashMap.equals(obj.linkedHashMap) : obj.linkedHashMap != null)
                return false;

            if (linkedHashSet != null ? !linkedHashSet.equals(obj.linkedHashSet) : obj.linkedHashSet != null)
                return false;

            if (linkedList != null ? !linkedList.equals(obj.linkedList) : obj.linkedList != null)
                return false;

            if (!Arrays.equals(longArr, obj.longArr))
                return false;

            if (longVal2 != null ? !longVal2.equals(obj.longVal2) : obj.longVal2 != null)
                return false;

            if (!Arrays.equals(objArr, obj.objArr))
                return false;

            if (props != null ? !props.equals(obj.props) : obj.props != null)
                return false;

            if (!Arrays.equals(shortArr, obj.shortArr))
                return false;

            if (shortVal2 != null ? !shortVal2.equals(obj.shortVal2) : obj.shortVal2 != null)
                return false;

            if (str != null ? !str.equals(obj.str) : obj.str != null)
                return false;

            if (uuid != null ? !uuid.equals(obj.uuid) : obj.uuid != null)
                return false;

            if (self != this)
                return false;

            return true;
        }
    }

    /**
     * Test enum.
     */
    private enum TestEnum {
        /** */
        A,

        /** */
        B,

        /** */
        C
    }

    /**
     * Class with custom serialization method which at the beginning invokes
     * {@link ObjectOutputStream#defaultWriteObject()} and {@link ObjectOutputStream#putFields()} then.
     */
    public static class CustomWriteObjectMethodObject implements Serializable {
        /** */
        private final String name;

        /**
         * Creates new instance.
         * @param name Object name.
         */
        public CustomWriteObjectMethodObject(String name) {
            this.name = name;
        }

        /** */
        private void writeObject(ObjectOutputStream stream) throws IOException {
            stream.defaultWriteObject();

            ObjectOutputStream.PutField fields = stream.putFields();
            fields.put("name", "test");

            stream.writeFields();
        }
    }

    /**
     * Class with custom {@link #writeObject(ObjectOutputStream)} and/or
     * {@link #readObject(ObjectInputStream)} implementation uses {@link ObjectOutputStream#writeObject(Object)} and/or
     * {@link ObjectInputStream#readObject()} internally.
     */
    private static class NestedReadWriteObject implements Serializable {
        /** */
        private transient NestedReadWriteObject obj1;

        /** */
        private transient NestedReadWriteObject obj2;

        /** */
        private int val;

        /** */
        private String str;

        /** */
        public NestedReadWriteObject(NestedReadWriteObject obj1, NestedReadWriteObject obj2, int val, String str) {
            this.obj1 = obj1;
            this.obj2 = obj2;
            this.val = val;
            this.str = str;
        }

        /**
         * @param out Output stream.
         * @throws IOException In case of error.
         */
        private void writeObject(ObjectOutputStream out) throws IOException {
            out.writeObject(obj1);

            out.defaultWriteObject();

            out.writeObject(obj2);
        }

        /**
         * @param in Input stream.
         * @throws IOException In case of error.
         * @throws ClassNotFoundException If class not found.
         */
        private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
            obj1 = (NestedReadWriteObject)in.readObject();

            in.defaultReadObject();

            obj2 = (NestedReadWriteObject)in.readObject();
        }

        /** {@inheritDoc} */
        @Override public boolean equals(Object obj) {
            if (obj == this)
                return true;

            if (!(obj instanceof NestedReadWriteObject))
                return false;

            NestedReadWriteObject o = (NestedReadWriteObject)obj;

            return o.val == val && Objects.equals(o.str, str) && Objects.equals(o.obj1, obj1)
                && Objects.equals(o.obj2, obj2);
        }

        /** {@inheritDoc} */
        @Override public int hashCode() {
            int res = obj1 != null ? obj1.hashCode() : 0;

            res = 31 * res + (obj2 != null ? obj2.hashCode() : 0);

            res = 31 * res + val;

            res = 31 * res + (str != null ? str.hashCode() : 0);

            return res;
        }
    }

    /** */
    static class BadDeserializableObject implements Serializable {
        /** */
        BadDeserializableValue val = new BadDeserializableValue();
    }

    /** */
    static class BadDeserializableValue implements Serializable {
        /** */
        private void writeObject(ObjectOutputStream os) throws IOException {
            os.write(10);
        }

        /** */
        private void readObject(ObjectInputStream os) {
            throw new RuntimeException("bad object");
        }
    }

    /** */
    static class BadSerializableObject implements Serializable {
        /** */
        BadSerializableValue val = new BadSerializableValue();
    }

    /** */
    static class BadSerializableValue implements Serializable {
        /** */
        private void writeObject(ObjectOutputStream os) {
            throw new RuntimeException("bad object");
        }

        /** */
        private void readObject(ObjectInputStream os) {
            throw new RuntimeException("bad object");
        }
    }

}
