Add support for .equals() to Java structs.

- Add a new method to t_java_generator that generates a .equals() method.
- Add a correct but useless implementation of hashCode for structs.
  (This is required by conventino when overriding .equals().)
- Add java_package to DebugProtoTest and OptionalRequiredTest.
- Add a new structure to OptionalRequiredTest to assist testing the behavior
  of .equals() with respect to null and unset fields.
- Clean up test/java/build.xml a bit.  (It still has a ways to go.)
- Add EqualityTest.java to test .equals().
- Add IdentityTest.java to test that writing and reading a structure
  preserves equality.

Tested by runnint atn test.
I also looked at the generated code for OptionalRequiredTest.thrift.


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665541 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/test/DebugProtoTest.thrift b/test/DebugProtoTest.thrift
index cdbea2a..7f031c6 100644
--- a/test/DebugProtoTest.thrift
+++ b/test/DebugProtoTest.thrift
@@ -1,4 +1,5 @@
 namespace cpp thrift.test
+namespace java thrift.test
 
 struct Doubles {
  1: double nan,
diff --git a/test/OptionalRequiredTest.thrift b/test/OptionalRequiredTest.thrift
index a635813..d8f0fa0 100644
--- a/test/OptionalRequiredTest.thrift
+++ b/test/OptionalRequiredTest.thrift
@@ -1,4 +1,5 @@
 namespace cpp thrift.test
+namespace java thrift.test
 
 struct OldSchool {
   1: i16    im_int;
@@ -41,3 +42,12 @@
   5: optional i32 opt5;
   6: optional i32 opt6;
 }
+
+struct JavaTestHelper {
+  1: required i32    req_int;
+  2: optional i32    opt_int;
+  3: required string req_obj;
+  4: optional string opt_obj;
+  5: required binary req_bin;
+  6: optional binary opt_bin;
+}
diff --git a/test/java/build.xml b/test/java/build.xml
index 9d7fb06..68d7b98 100644
--- a/test/java/build.xml
+++ b/test/java/build.xml
@@ -16,20 +16,26 @@
     <exec executable="../../compiler/cpp/thrift">
       <arg line="--gen java ../ThriftTest.thrift" />
     </exec>
-  </target>
-
-  <target name="compile" depends="init,generate">
-    <javac srcdir="${gen}" destdir="${build}" classpath="${cpath}" />
-    <javac srcdir="${src}" destdir="${build}" classpath="${cpath}:${gen}" />
+    <exec executable="../../compiler/cpp/thrift">
+      <arg line="--gen java ../DebugProtoTest.thrift" />
+    </exec>
+    <exec executable="../../compiler/cpp/thrift">
+      <arg line="--gen java ../OptionalRequiredTest.thrift" />
+    </exec>
   </target>
 
   <target name="compileonly">
-    <javac srcdir="${gen}" destdir="${build}" classpath="${cpath}" />
-    <javac srcdir="${src}" destdir="${build}" classpath="${cpath}:${gen}" />
+    <javac debug="true" srcdir="${gen}" destdir="${build}" classpath="${cpath}" />
+    <javac debug="true" srcdir="${src}" destdir="${build}" classpath="${cpath}:${gen}" />
+  </target>
+
+  <target name="compile" depends="init,generate,compileonly">
+    <jar jarfile="thrifttest.jar" basedir="${build}"/>
   </target>
 
   <target name="test" depends="compile">
-    <jar jarfile="thrifttest.jar" basedir="${build}"/>
+    <java classname="com.facebook.thrift.test.IdentityTest" classpath="${cpath}:./thrifttest.jar"/>
+    <java classname="com.facebook.thrift.test.EqualityTest" classpath="${cpath}:./thrifttest.jar"/>
   </target>
 
   <target name="clean">
diff --git a/test/java/src/EqualityTest.java b/test/java/src/EqualityTest.java
new file mode 100644
index 0000000..8bdba2c
--- /dev/null
+++ b/test/java/src/EqualityTest.java
@@ -0,0 +1,1808 @@
+/*
+This program was generated by the following Python script:
+
+#!/usr/bin/python2.5
+
+# Remove this when Python 2.6 hits the streets.
+from __future__ import with_statement
+
+import sys
+import os.path
+
+
+# Quines the easy way.
+with open(sys.argv[0], 'r') as handle:
+  source = handle.read()
+
+with open(os.path.join(os.path.dirname(sys.argv[0]), 'EqualityTest.java'), 'w') as out:
+  print >> out, "/""*"
+  print >> out, "This program was generated by the following Python script:"
+  print >> out
+  out.write(source)
+  print >> out, "*""/"
+
+  print >> out, r'''
+package com.facebook.thrift.test;
+
+// Generated code
+import thrift.test.*;
+
+/'''r'''**
+ * @author David Reiss <dreiss@facebook.com>
+ *'''r'''/
+public class EqualityTest {
+  public static void main(String[] args) throws Exception {
+    JavaTestHelper lhs, rhs;
+'''
+
+  vals = {
+    'int': ("1", "2"),
+    'obj': ("\"foo\"", "\"bar\""),
+    'bin': ("new byte[]{1,2}", "new byte[]{3,4}"),
+  }
+  matrix = (
+    (False,False),
+    (False,True ),
+    (True ,False),
+    (True ,True ),
+  )
+
+  for type in ('int', 'obj', 'bin'):
+    for option in ('req', 'opt'):
+      nulls = matrix[0:1] if type == 'int' else matrix[-1::-1]
+      issets = matrix
+      for is_null in nulls:
+        for is_set in issets:
+          for equal in (True, False):
+            print >> out
+            print >> out, "    lhs = new JavaTestHelper();"
+            print >> out, "    rhs = new JavaTestHelper();"
+            print >> out, "    lhs." + option + "_" + type, "=", vals[type][0] + ";"
+            print >> out, "    rhs." + option + "_" + type, "=", vals[type][0 if equal else 1] + ";"
+            if (is_set[0]): print >> out, "    lhs.__isset." + option + "_" + type, "= true;"
+            if (is_set[1]): print >> out, "    rhs.__isset." + option + "_" + type, "= true;"
+            if (is_null[0]): print >> out, "    lhs." + option + "_" + type, "= null;"
+            if (is_null[1]): print >> out, "    rhs." + option + "_" + type, "= null;"
+            this_present = not is_null[0] and (option == 'req' or is_set[0])
+            that_present = not is_null[1] and (option == 'req' or is_set[1])
+            print >> out, "    // this_present = " + repr(this_present)
+            print >> out, "    // that_present = " + repr(that_present)
+            is_equal = \
+                (not this_present and not that_present) or \
+                (this_present and that_present and equal)
+            eq_str = 'true' if is_equal else 'false'
+
+            print >> out, "    if (lhs.equals(rhs) != "+eq_str+")"
+            print >> out, "      throw new RuntimeException(\"Failure\");"
+            if is_equal:
+              print >> out, "    if (lhs.hashCode() != rhs.hashCode())"
+              print >> out, "      throw new RuntimeException(\"Failure\");"
+
+  print >> out, r'''
+  }
+}
+'''
+*/
+
+package com.facebook.thrift.test;
+
+// Generated code
+import thrift.test.*;
+
+/**
+ * @author David Reiss <dreiss@facebook.com>
+ */
+public class EqualityTest {
+  public static void main(String[] args) throws Exception {
+    JavaTestHelper lhs, rhs;
+
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_int = 1;
+    rhs.req_int = 1;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_int = 1;
+    rhs.req_int = 2;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_int = 1;
+    rhs.req_int = 1;
+    rhs.__isset.req_int = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_int = 1;
+    rhs.req_int = 2;
+    rhs.__isset.req_int = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_int = 1;
+    rhs.req_int = 1;
+    lhs.__isset.req_int = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_int = 1;
+    rhs.req_int = 2;
+    lhs.__isset.req_int = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_int = 1;
+    rhs.req_int = 1;
+    lhs.__isset.req_int = true;
+    rhs.__isset.req_int = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_int = 1;
+    rhs.req_int = 2;
+    lhs.__isset.req_int = true;
+    rhs.__isset.req_int = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_int = 1;
+    rhs.opt_int = 1;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_int = 1;
+    rhs.opt_int = 2;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_int = 1;
+    rhs.opt_int = 1;
+    rhs.__isset.opt_int = true;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_int = 1;
+    rhs.opt_int = 2;
+    rhs.__isset.opt_int = true;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_int = 1;
+    rhs.opt_int = 1;
+    lhs.__isset.opt_int = true;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_int = 1;
+    rhs.opt_int = 2;
+    lhs.__isset.opt_int = true;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_int = 1;
+    rhs.opt_int = 1;
+    lhs.__isset.opt_int = true;
+    rhs.__isset.opt_int = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_int = 1;
+    rhs.opt_int = 2;
+    lhs.__isset.opt_int = true;
+    rhs.__isset.opt_int = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.req_obj = null;
+    rhs.req_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.req_obj = null;
+    rhs.req_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    rhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    rhs.req_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    rhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    rhs.req_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    rhs.req_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    rhs.req_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.__isset.req_obj = true;
+    rhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    rhs.req_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.__isset.req_obj = true;
+    rhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    rhs.req_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.req_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.req_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    rhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    rhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.__isset.req_obj = true;
+    rhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.__isset.req_obj = true;
+    rhs.__isset.req_obj = true;
+    lhs.req_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    rhs.req_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    rhs.req_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    rhs.__isset.req_obj = true;
+    rhs.req_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    rhs.__isset.req_obj = true;
+    rhs.req_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.__isset.req_obj = true;
+    rhs.req_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.__isset.req_obj = true;
+    rhs.req_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.__isset.req_obj = true;
+    rhs.__isset.req_obj = true;
+    rhs.req_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.__isset.req_obj = true;
+    rhs.__isset.req_obj = true;
+    rhs.req_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    rhs.__isset.req_obj = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    rhs.__isset.req_obj = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.__isset.req_obj = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.__isset.req_obj = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "foo";
+    lhs.__isset.req_obj = true;
+    rhs.__isset.req_obj = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_obj = "foo";
+    rhs.req_obj = "bar";
+    lhs.__isset.req_obj = true;
+    rhs.__isset.req_obj = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.opt_obj = null;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.opt_obj = null;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    rhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    rhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.__isset.opt_obj = true;
+    rhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.__isset.opt_obj = true;
+    rhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    rhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    rhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.__isset.opt_obj = true;
+    rhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.__isset.opt_obj = true;
+    rhs.__isset.opt_obj = true;
+    lhs.opt_obj = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    rhs.__isset.opt_obj = true;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    rhs.__isset.opt_obj = true;
+    rhs.opt_obj = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.__isset.opt_obj = true;
+    rhs.opt_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.__isset.opt_obj = true;
+    rhs.opt_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.__isset.opt_obj = true;
+    rhs.__isset.opt_obj = true;
+    rhs.opt_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.__isset.opt_obj = true;
+    rhs.__isset.opt_obj = true;
+    rhs.opt_obj = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    rhs.__isset.opt_obj = true;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    rhs.__isset.opt_obj = true;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.__isset.opt_obj = true;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.__isset.opt_obj = true;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "foo";
+    lhs.__isset.opt_obj = true;
+    rhs.__isset.opt_obj = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_obj = "foo";
+    rhs.opt_obj = "bar";
+    lhs.__isset.opt_obj = true;
+    rhs.__isset.opt_obj = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.req_bin = null;
+    rhs.req_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.req_bin = null;
+    rhs.req_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    rhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    rhs.req_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    rhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    rhs.req_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    rhs.req_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    rhs.req_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.__isset.req_bin = true;
+    rhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    rhs.req_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.__isset.req_bin = true;
+    rhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    rhs.req_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.req_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.req_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    rhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    rhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.__isset.req_bin = true;
+    rhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.__isset.req_bin = true;
+    rhs.__isset.req_bin = true;
+    lhs.req_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    rhs.req_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    rhs.__isset.req_bin = true;
+    rhs.req_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    rhs.__isset.req_bin = true;
+    rhs.req_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.__isset.req_bin = true;
+    rhs.req_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.__isset.req_bin = true;
+    rhs.req_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.__isset.req_bin = true;
+    rhs.__isset.req_bin = true;
+    rhs.req_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.__isset.req_bin = true;
+    rhs.__isset.req_bin = true;
+    rhs.req_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    rhs.__isset.req_bin = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    rhs.__isset.req_bin = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.__isset.req_bin = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.__isset.req_bin = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{1,2};
+    lhs.__isset.req_bin = true;
+    rhs.__isset.req_bin = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.req_bin = new byte[]{1,2};
+    rhs.req_bin = new byte[]{3,4};
+    lhs.__isset.req_bin = true;
+    rhs.__isset.req_bin = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.opt_bin = null;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.opt_bin = null;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    rhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    rhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.__isset.opt_bin = true;
+    rhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.__isset.opt_bin = true;
+    rhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    rhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    rhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.__isset.opt_bin = true;
+    rhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.__isset.opt_bin = true;
+    rhs.__isset.opt_bin = true;
+    lhs.opt_bin = null;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    rhs.__isset.opt_bin = true;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    rhs.__isset.opt_bin = true;
+    rhs.opt_bin = null;
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.__isset.opt_bin = true;
+    rhs.opt_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.__isset.opt_bin = true;
+    rhs.opt_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.__isset.opt_bin = true;
+    rhs.__isset.opt_bin = true;
+    rhs.opt_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.__isset.opt_bin = true;
+    rhs.__isset.opt_bin = true;
+    rhs.opt_bin = null;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    // this_present = False
+    // that_present = False
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    rhs.__isset.opt_bin = true;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    rhs.__isset.opt_bin = true;
+    // this_present = False
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.__isset.opt_bin = true;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.__isset.opt_bin = true;
+    // this_present = True
+    // that_present = False
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{1,2};
+    lhs.__isset.opt_bin = true;
+    rhs.__isset.opt_bin = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != true)
+      throw new RuntimeException("Failure");
+    if (lhs.hashCode() != rhs.hashCode())
+      throw new RuntimeException("Failure");
+
+    lhs = new JavaTestHelper();
+    rhs = new JavaTestHelper();
+    lhs.opt_bin = new byte[]{1,2};
+    rhs.opt_bin = new byte[]{3,4};
+    lhs.__isset.opt_bin = true;
+    rhs.__isset.opt_bin = true;
+    // this_present = True
+    // that_present = True
+    if (lhs.equals(rhs) != false)
+      throw new RuntimeException("Failure");
+
+  }
+}
+
diff --git a/test/java/src/IdentityTest.java b/test/java/src/IdentityTest.java
new file mode 100644
index 0000000..3f64ef7
--- /dev/null
+++ b/test/java/src/IdentityTest.java
@@ -0,0 +1,158 @@
+package com.facebook.thrift.test;
+
+// Generated code
+import thrift.test.*;
+
+import com.facebook.thrift.TSerializer;
+import com.facebook.thrift.TDeserializer;
+import com.facebook.thrift.protocol.TBinaryProtocol;
+import com.facebook.thrift.protocol.TSimpleJSONProtocol;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ArrayList;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ *
+ * @author David Reiss <dreiss@facebook.com>
+ */
+public class IdentityTest {
+  public static Object deepCopy(Object oldObj) throws Exception {
+    ObjectOutputStream oos = null;
+    ObjectInputStream ois = null;
+    try {
+      ByteArrayOutputStream bos =
+        new ByteArrayOutputStream();
+      oos = new ObjectOutputStream(bos);
+      oos.writeObject(oldObj);
+      oos.flush();
+      ByteArrayInputStream bis =
+        new ByteArrayInputStream(bos.toByteArray());
+      ois = new ObjectInputStream(bis);
+      return ois.readObject();
+    } finally {
+      oos.close();
+      ois.close();
+    }
+  }
+
+  public static void main(String[] args) throws Exception {
+    TSerializer   binarySerializer   = new   TSerializer(new TBinaryProtocol.Factory());
+    TDeserializer binaryDeserializer = new TDeserializer(new TBinaryProtocol.Factory());
+
+    OneOfEach ooe = new OneOfEach();
+    ooe.im_true   = true;
+    ooe.im_false  = false;
+    ooe.a_bite    = (byte)0xd6;
+    ooe.integer16 = 27000;
+    ooe.integer32 = 1<<24;
+    ooe.integer64 = (long)6000 * 1000 * 1000;
+    ooe.double_precision = Math.PI;
+    ooe.some_characters  = "JSON THIS! \"\u0001";
+    ooe.base64 = new byte[]{1,2,3,(byte)255};
+
+    Nesting n = new Nesting();
+    n.my_ooe = (OneOfEach)deepCopy(ooe);
+    n.my_ooe.integer16 = 16;
+    n.my_ooe.integer32 = 32;
+    n.my_ooe.integer64 = 64;
+    n.my_ooe.double_precision = (Math.sqrt(5)+1)/2;
+    n.my_ooe.some_characters  = ":R (me going \"rrrr\")";
+    n.my_ooe.zomg_unicode     = "\u04c0\u216e\u039d\u0020\u041d\u03bf\u217f"+
+                                "\u043e\u0261\u0433\u0430\u03c1\u210e\u0020"+
+                                "\u0391\u0074\u0074\u03b1\u217d\u03ba\u01c3"+
+                                "\u203c";
+    n.my_bonk = new Bonk();
+    n.my_bonk.type    = 31337;
+    n.my_bonk.message = "I am a bonk... xor!";
+
+    HolyMoley hm = new HolyMoley();
+    hm.big = new ArrayList<OneOfEach>();
+    hm.contain = new HashSet<List<String>>();
+    hm.bonks = new HashMap<String,List<Bonk>>();
+
+    hm.big.add((OneOfEach)deepCopy(ooe));
+    hm.big.add((OneOfEach)deepCopy(n.my_ooe));
+    hm.big.get(0).a_bite = 0x22;
+    hm.big.get(1).a_bite = 0x33;
+
+    List<String> stage1 = new ArrayList<String>();
+    stage1.add("and a one");
+    stage1.add("and a two");
+    hm.contain.add(stage1);
+    stage1 = new ArrayList<String>();
+    stage1.add("then a one, two");
+    stage1.add("three!");
+    stage1.add("FOUR!!");
+    hm.contain.add(stage1);
+    stage1 = new ArrayList<String>();
+    hm.contain.add(stage1);
+
+    List<Bonk> stage2 = new ArrayList<Bonk>();
+    hm.bonks.put("nothing", stage2);
+    stage2.add(new Bonk());
+    stage2.get(0).type = 1;
+    stage2.get(0).message = "Wait.";
+    stage2.add(new Bonk());
+    stage2.get(1).type = 2;
+    stage2.get(1).message = "What?";
+    hm.bonks.put("something", stage2);
+    stage2 = new ArrayList<Bonk>();
+    stage2.add(new Bonk());
+    stage2.get(0).type = 3;
+    stage2.get(0).message = "quoth";
+    stage2.add(new Bonk());
+    stage2.get(1).type = 4;
+    stage2.get(1).message = "the raven";
+    stage2.add(new Bonk());
+    stage2.get(2).type = 5;
+    stage2.get(2).message = "nevermore";
+    hm.bonks.put("poe", stage2);
+
+    OneOfEach ooe2 = new OneOfEach();
+    binaryDeserializer.deserialize(
+        ooe2,
+        binarySerializer.serialize(ooe));
+
+    if (!ooe.equals(ooe2)) {
+      throw new RuntimeException("Failure: ooe (equals)");
+    }
+    if (ooe.hashCode() != ooe2.hashCode()) {
+      throw new RuntimeException("Failure: ooe (hash)");
+    }
+
+
+    Nesting n2 = new Nesting();
+    binaryDeserializer.deserialize(
+        n2,
+        binarySerializer.serialize(n));
+
+    if (!n.equals(n2)) {
+      throw new RuntimeException("Failure: n (equals)");
+    }
+    if (n.hashCode() != n2.hashCode()) {
+      throw new RuntimeException("Failure: n (hash)");
+    }
+
+    HolyMoley hm2 = new HolyMoley();
+    binaryDeserializer.deserialize(
+        hm2,
+        binarySerializer.serialize(hm));
+
+    if (!hm.equals(hm2)) {
+      throw new RuntimeException("Failure: hm (equals)");
+    }
+    if (hm.hashCode() != hm2.hashCode()) {
+      throw new RuntimeException("Failure: hm (hash)");
+    }
+
+  }
+}