// Path: src/main/java/com/cedarsoftware/util/DeepEquals.java
// public static boolean deepEquals(Object a, Object b)
// {
//     return deepEquals(a, b, new HashMap());
// }
// 
// Path: src/main/java/com/cedarsoftware/util/DeepEquals.java
// public static int deepHashCode(Object obj)
// {
//     Set<Object> visited = new HashSet<>();
//     LinkedList<Object> stack = new LinkedList<>();
//     stack.addFirst(obj);
//     int hash = 0;
// 
//     while (!stack.isEmpty())
//     {
//         obj = stack.removeFirst();
//         if (obj == null || visited.contains(obj))
//         {
//             continue;
//         }
// 
//         visited.add(obj);
// 
//         if (obj.getClass().isArray())
//         {
//             final int len = Array.getLength(obj);
//             for (int i = 0; i < len; i++)
//             {
//                 stack.addFirst(Array.get(obj, i));
//             }
//             continue;
//         }
// 
//         if (obj instanceof Collection)
//         {
//             stack.addAll(0, (Collection)obj);
//             continue;
//         }
// 
//         if (obj instanceof Map)
//         {
//             stack.addAll(0, ((Map)obj).keySet());
//             stack.addAll(0, ((Map)obj).values());
//             continue;
//         }
// 
//         if (obj instanceof Double || obj instanceof Float)
//         {
//             // just take the integral value for hashcode
//             // equality tests things more comprehensively
//             stack.add(Math.round(((Number) obj).doubleValue()));
//             continue;
//         }
// 
//         if (hasCustomHashCode(obj.getClass()))
//         {   // A real hashCode() method exists, call it.
//             hash += obj.hashCode();
//             continue;
//         }
// 
//         Collection<Field> fields = ReflectionUtils.getDeepDeclaredFields(obj.getClass());
//         for (Field field : fields)
//         {
//             try
//             {
//                 stack.addFirst(field.get(obj));
//             }
//             catch (Exception ignored) { }
//         }
//     }
//     return hash;
// }


import org.agrona.collections.Object2ObjectHashMap;
import org.junit.Test;
import java.awt.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import static com.cedarsoftware.util.DeepEquals.deepEquals;
import static com.cedarsoftware.util.DeepEquals.deepHashCode;
import static java.lang.Math.*;
import static java.util.Arrays.asList;
import static org.junit.Assert.*;
		assertTrue(deepEquals(x1, x2));

		// Proves that objects are being compared against the correct objects in each collection (all objects have same
        // hash code, so the unordered compare must handle checking item by item for hash-collided items)
		Set<DumbHash> d1 = new LinkedHashSet<>();
		Set<DumbHash> d2 = new LinkedHashSet<>();
		d1.add(new DumbHash("alpha"));
		d1.add(new DumbHash("bravo"));
		d1.add(new DumbHash("charlie"));
		
		d2.add(new DumbHash("bravo"));
		d2.add(new DumbHash("alpha"));
		d2.add(new DumbHash("charlie"));
		assert deepEquals(d1, d2);

        d2.clear();
        d2.add(new DumbHash("bravo"));
        d2.add(new DumbHash("alpha"));
        d2.add(new DumbHash("delta"));
        assert !deepEquals(d2, d1);
    }

    @Test
    public void testEquivalentMaps()
    {
        Map map1 = new LinkedHashMap();
        fillMap(map1);
        Map map2 = new HashMap();
        fillMap(map2);
        assertTrue(deepEquals(map1, map2));
// Path: src/main/java/com/cedarsoftware/util/DeepEquals.java
// public static boolean deepEquals(Object a, Object b)
// {
//     return deepEquals(a, b, new HashMap());
// }
// 
// Path: src/main/java/com/cedarsoftware/util/DeepEquals.java
// public static int deepHashCode(Object obj)
// {
//     Set<Object> visited = new HashSet<>();
//     LinkedList<Object> stack = new LinkedList<>();
//     stack.addFirst(obj);
//     int hash = 0;
// 
//     while (!stack.isEmpty())
//     {
//         obj = stack.removeFirst();
//         if (obj == null || visited.contains(obj))
//         {
//             continue;
//         }
// 
//         visited.add(obj);
// 
//         if (obj.getClass().isArray())
//         {
//             final int len = Array.getLength(obj);
//             for (int i = 0; i < len; i++)
//             {
//                 stack.addFirst(Array.get(obj, i));
//             }
//             continue;
//         }
// 
//         if (obj instanceof Collection)
//         {
//             stack.addAll(0, (Collection)obj);
//             continue;
//         }
// 
//         if (obj instanceof Map)
//         {
//             stack.addAll(0, ((Map)obj).keySet());
//             stack.addAll(0, ((Map)obj).values());
//             continue;
//         }
// 
//         if (obj instanceof Double || obj instanceof Float)
//         {
//             // just take the integral value for hashcode
//             // equality tests things more comprehensively
//             stack.add(Math.round(((Number) obj).doubleValue()));
//             continue;
//         }
// 
//         if (hasCustomHashCode(obj.getClass()))
//         {   // A real hashCode() method exists, call it.
//             hash += obj.hashCode();
//             continue;
//         }
// 
//         Collection<Field> fields = ReflectionUtils.getDeepDeclaredFields(obj.getClass());
//         for (Field field : fields)
//         {
//             try
//             {
//                 stack.addFirst(field.get(obj));
//             }
//             catch (Exception ignored) { }
//         }
//     }
//     return hash;
// }


// Path: src/test/java/com/cedarsoftware/util/TestDeepEquals.java
import org.agrona.collections.Object2ObjectHashMap;
import org.junit.Test;
import java.awt.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import static com.cedarsoftware.util.DeepEquals.deepEquals;
import static com.cedarsoftware.util.DeepEquals.deepHashCode;
import static java.lang.Math.*;
import static java.util.Arrays.asList;
import static org.junit.Assert.*;

		assertTrue(deepEquals(x1, x2));

		// Proves that objects are being compared against the correct objects in each collection (all objects have same
        // hash code, so the unordered compare must handle checking item by item for hash-collided items)
		Set<DumbHash> d1 = new LinkedHashSet<>();
		Set<DumbHash> d2 = new LinkedHashSet<>();
		d1.add(new DumbHash("alpha"));
		d1.add(new DumbHash("bravo"));
		d1.add(new DumbHash("charlie"));
		
		d2.add(new DumbHash("bravo"));
		d2.add(new DumbHash("alpha"));
		d2.add(new DumbHash("charlie"));
		assert deepEquals(d1, d2);

        d2.clear();
        d2.add(new DumbHash("bravo"));
        d2.add(new DumbHash("alpha"));
        d2.add(new DumbHash("delta"));
        assert !deepEquals(d2, d1);
    }

    @Test
    public void testEquivalentMaps()
    {
        Map map1 = new LinkedHashMap();
        fillMap(map1);
        Map map2 = new HashMap();
        fillMap(map2);
        assertTrue(deepEquals(map1, map2));
        assertEquals(deepHashCode(map1), deepHashCode(map2));