java_gen: add documentation
diff --git a/java_gen/java_model.py b/java_gen/java_model.py
index 4ac497f..9e5731b 100644
--- a/java_gen/java_model.py
+++ b/java_gen/java_model.py
@@ -114,6 +114,10 @@
                     members=self.interfaces)
 
     def generate_class(self, clazz):
+        """ return wether or not to generate implementation class clazz.
+            Now true for everything except OFTableModVer10.
+            @param clazz JavaOFClass instance
+        """
         if clazz.interface.name.startswith("OFMatchV"):
             return True
         elif clazz.name == "OFTableModVer10":
@@ -188,10 +192,17 @@
         Version agnostic, in contrast to the loxi_ir python model.
     """
     def __init__(self, c_name, version_map):
+        """"
+        @param c_name: loxi style name (e.g., of_flow_add)
+        @param version_map map of { JavaOFVersion: OFClass (from loxi_ir) }
+        """
         self.c_name = c_name
         self.version_map = version_map
+        # name: the Java Type name, e.g., OFFlowAdd
         self.name = java_type.name_c_to_caps_camel(c_name) if c_name != "of_header" else "OFMessage"
+        # variable_name name to use for variables of this type. i.e., flowAdd
         self.variable_name = self.name[2].lower() + self.name[3:]
+        # name for use in constants: FLOW_ADD
         self.constant_name = c_name.upper().replace("OF_", "")
 
         pck_suffix, parent_interface = self.class_info()
@@ -202,6 +213,10 @@
             self.parent_interface = None
 
     def class_info(self):
+        """ return tuple of (package_prefix, parent_class) for the current JavaOFInterface"""
+        # FIXME: This duplicates inheritance information that is now available in the loxi_ir
+        # model (note, that the loxi model is on versioned classes). Should check/infer the
+        # inheritance information from the versioned lox_ir classes.
         if re.match(r'OF.+StatsRequest$', self.name):
             return ("", "OFStatsRequest")
         elif re.match(r'OF.+StatsReply$', self.name):
@@ -241,6 +256,9 @@
     @property
     @memoize
     def members(self):
+        """return a list of all members to be exposed by this interface. Corresponds to
+           the union of the members of the vesioned classes without length, fieldlength
+           and pads (those are handled automatically during (de)serialization and not exposed"""
         all_versions = []
         member_map = collections.OrderedDict()
 
@@ -258,15 +276,18 @@
     @property
     @memoize
     def is_virtual(self):
+        """ Is this interface virtual. If so, do not generate a builder interface """
         return self.name in model.virtual_interfaces or all(ir_class.virtual for ir_class in self.version_map.values())
 
     @property
     def is_universal(self):
+        """ Is this interface universal, i.e., does it exist in all OF versions? """
         return len(self.all_versions) == len(model.versions)
 
     @property
     @memoize
     def all_versions(self):
+        """ return list of all versions that this interface exists in """
         return self.version_map.keys()
 
     def has_version(self, version):
@@ -289,6 +310,11 @@
         Version specific child of a JavaOFInterface
     """
     def __init__(self, interface, version, ir_class):
+        """
+        @param interface JavaOFInterface instance of the parent interface
+        @param version JavaOFVersion
+        @param ir_class OFClass from loxi_ir
+        """
         self.interface = interface
         self.ir_class = ir_class
         self.c_name = self.ir_class.name
@@ -319,11 +345,13 @@
 
     @property
     def min_length(self):
+        """ @return the minimum wire length of an instance of this class in bytes """
         id_tuple = (self.ir_class.name, self.version.int_version)
         return of_g.base_length[id_tuple] if id_tuple in of_g.base_length else -1
 
     @property
     def is_fixed_length(self):
+        """ true iff this class serializes to a fixed length on the wire """
         return (self.ir_class.name, self.version.int_version) in of_g.is_fixed_length
 
     def all_properties(self):
diff --git a/java_gen/java_type.py b/java_gen/java_type.py
index 38ce1ff..78ae9d6 100644
--- a/java_gen/java_type.py
+++ b/java_gen/java_type.py
@@ -21,8 +21,10 @@
     else:
         return camel
 
-
 java_primitive_types = set("byte char short int long".split(" "))
+
+### info table about java primitive types, for casting literals in the source code
+# { name : (signed?, length_in_bits) }
 java_primitives_info = {
         'byte' : (True, 8),
         'char' : (False, 16),
@@ -31,7 +33,12 @@
         'long' : (True, 64),
 }
 
-def format_primitive_value(t, value):
+def format_primitive_literal(t, value):
+    """ Format a primitive numeric literal for inclusion in the
+        java source code. Takes care of casting the literal
+        apropriately for correct representation despite Java's
+        signed-craziness
+    """
     signed, bits = java_primitives_info[t]
     max = (1 << bits)-1
     if value > max:
@@ -59,8 +66,13 @@
     def __str__(self):
         return "[Version: %d, Read: '%s', Write: '%s']" % (self.version, self.read, self.write)
 
+### FIXME: This class should really be cleaned up
 class JType(object):
-    """ Wrapper class to hold C to Java type conversion information """
+    """ Wrapper class to hold C to Java type conversion information. JTypes can have a 'public'
+        and or 'private' java type associated with them and can define how those types can be
+        read from and written to ChannelBuffers.
+
+    """
     def __init__(self, pub_type, priv_type=None, size=None, read_op=None, write_op=None):
         self.pub_type = pub_type    # the type we expose externally, e.g. 'U8'
         if priv_type is None:
@@ -76,15 +88,31 @@
 #        self._write_op = write_op
 
     def op(self, version=ANY, read=None, write=None, pub_type=ANY):
+        """
+        define operations to be performed for reading and writing this type
+        (when read_op, write_op is called). The operations 'read' and 'write'
+        can either be strings ($name, and $version and $length will be replaced),
+        or callables (name, version and length) will be passed.
+
+        @param version int      OF version to define operation for, or ANY for all
+        @param pub_type boolean whether to define operations for the public type (True), the
+                                private type(False) or both (ALL)
+        @param read read expression (either string or callable)s
+        @param write write expression (either string or callable)
+        """
+
         pub_types = [ pub_type ] if pub_type is not ANY else [ False, True ]
         for pub_type in pub_types:
             self.ops[(version,pub_type)] = VersionOp(version, read, write)
         return self
 
     def format_value(self, value, pub_type=True):
+        # Format a constant value of this type, for inclusion in the java source code
+        # For primitive types, takes care of casting the value appropriately, to
+        # cope with java's signedness limitation
         t = self.pub_type if pub_type else self.priv_type
         if t in java_primitive_types:
-            return format_primitive_value(t, value)
+            return format_primitive_literal(t, value)
         else:
             return value
 
@@ -102,7 +130,18 @@
         return self.pub_type != self.priv_type
 
     def read_op(self, version=None, length=None, pub_type=True):
+        """ return a Java stanza that reads a value of this JType from ChannelBuffer bb.
+        @param version int - OF wire version to generate expression for
+        @param pub_type boolean use this JTypes 'public' (True), or private (False) representation
+        @param length string, for operations that need it (e.g., read a list of unknown length)
+               Java expression evaluating to the byte length to be read. Defaults to the remainig
+               length of the message.
+        @return string containing generated Java expression.
+        """
         if length is None:
+             # assumes that
+             # (1) length of the message has been read to 'length'
+             # (2) readerIndex at the start of the message has been stored in 'start'
             length = "length - (bb.readerIndex() - start)";
 
         ver = ANY if version is None else version.int_version
@@ -119,6 +158,13 @@
             return _read_op.replace("$length", str(length)).replace("$version", version.of_version)
 
     def write_op(self, version=None, name=None, pub_type=True):
+        """ return a Java stanza that writes a value of this JType contained in Java expression
+        'name' to ChannelBuffer bb.
+        @param name string containing Java expression that evaluations to the value to be written
+        @param version int - OF wire version to generate expression for
+        @param pub_type boolean use this JTypes 'public' (True), or private (False) representation
+        @return string containing generated Java expression.
+        """
         ver = ANY if version is None else version.int_version
         _write_op = None
         if (ver, pub_type) in self.ops:
@@ -126,6 +172,7 @@
         elif (ANY, pub_type) in self.ops:
             _write_op = self.ops[(ANY, pub_type)].write
         if _write_op is None:
+
             _write_op = 'ChannelUtilsVer$version.write%s(bb, $name)' % self.pub_type
         if callable(_write_op):
             return _write_op(version, name)
@@ -133,17 +180,28 @@
             return _write_op.replace("$name", str(name)).replace("$version", version.of_version)
 
     def skip_op(self, version=None, length=None):
+        """ return a java stanza that skips an instance of JType in the input ChannelBuffer 'bb'.
+            This is used in the Reader implementations for virtual classes (because after the
+            discriminator field, the concrete Reader instance will re-read all the fields)
+            Currently just delegates to read_op + throws away the result."""
         return self.read_op(version, length)
 
     @property
     def is_primitive(self):
+        """ return true if the pub_type is a java primitive type (and thus needs
+        special treatment, because it doesn't have methods)"""
         return self.pub_type in java_primitive_types
 
     @property
     def is_array(self):
+        """ return true iff the pub_type is a Java array (and thus requires special
+        treament for equals / toString etc.) """
         return self.pub_type.endswith("[]")
 
 
+##### Predefined JType mappings
+# FIXME: This list needs to be pruned / cleaned up. Most of these are schematic.
+
 u8 =  JType('byte',  size=1) \
         .op(read='bb.readByte()', write='bb.writeByte($name)')
 u8_list =  JType('List<U8>',  size=1) \
@@ -265,7 +323,8 @@
         'of_meter_features_t': meter_features,
         }
 
-## This is where we drop in special case handling for certain types
+## Map that defines exceptions from the standard loxi->java mapping scheme
+# map of {<loxi_class_name> : { <loxi_member_name> : <JType instance> } }
 exceptions = {
         'of_packet_in': {
             'data' : octets,
@@ -277,26 +336,26 @@
 }
 
 
-enum_wire_types = {
-        "uint8_t": JType("byte").op(read="bb.readByte()", write="bb.writeByte($name)"),
-        "uint16_t": JType("short").op(read="bb.readShort()", write="bb.writeShort($name)"),
-        "uint32_t": JType("int").op(read="bb.readInt()", write="bb.writeInt($name)"),
-        "uint64_t": JType("long").op(read="bb.readLong()", write="bb.writeLong($name)"),
-}
-
-def convert_enum_wire_type_to_jtype(wire_type):
-    return enum_wire_types[wire_type]
-
+# Create a default mapping for a list type. Type defauls to List<${java_mapping_of_name}>
 def make_standard_list_jtype(c_type):
     m = re.match(r'list\(of_([a-zA-Z_]+)_t\)', c_type)
     if not m:
         raise Exception("Not a recgonized standard list type declaration: %s" % c_type)
     base_name = m.group(1)
     java_base_name = name_c_to_caps_camel(base_name)
+
+    # read op assumes the class has a public final static field READER that implements
+    # OFMessageReader<$class> i.e., can deserialize an instance of class from a ChannelBuffer
+    # write op assumes class implements Writeable
     return JType("List<OF%s>" % java_base_name) \
-        .op(read= 'ChannelUtils.readList(bb, $length, OF%sVer$version.READER)' % java_base_name, \
+        .op(
+            read= 'ChannelUtils.readList(bb, $length, OF%sVer$version.READER)' % java_base_name, \
             write='ChannelUtils.writeList(bb, $name)')
 
+
+#### main entry point for conversion of LOXI types (c_types) Java types.
+# FIXME: This badly needs a refactoring
+
 def convert_to_jtype(obj_name, field_name, c_type):
     """ Convert from a C type ("uint_32") to a java type ("U32")
     and return a JType object with the size, internal type, and marshalling functions"""
@@ -320,3 +379,15 @@
         print "WARN: Couldn't find java type conversion for '%s' in %s:%s" % (c_type, obj_name, field_name)
         jtype = name_c_to_caps_camel(re.sub(r'_t$', "", c_type))
         return JType(jtype)
+
+
+#### Enum specific wiretype definitions
+enum_wire_types = {
+        "uint8_t": JType("byte").op(read="bb.readByte()", write="bb.writeByte($name)"),
+        "uint16_t": JType("short").op(read="bb.readShort()", write="bb.writeShort($name)"),
+        "uint32_t": JType("int").op(read="bb.readInt()", write="bb.writeInt($name)"),
+        "uint64_t": JType("long").op(read="bb.readLong()", write="bb.writeLong($name)"),
+}
+
+def convert_enum_wire_type_to_jtype(wire_type):
+    return enum_wire_types[wire_type]