make logical oper typesafe and remove code duplication
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
index 996aba2..d9993b0 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddress.java
@@ -32,20 +32,20 @@
      * @param   IPAddress<?> other
      * @return  new IPAddress<?> object after the AND oper
      */
-    public abstract IPAddress<?> and(IPAddress<?> other);
+    public abstract F and(F other);
 
     /**
      * Perform a low level OR operation on the bits of two IPAddress<?> objects
      * @param   IPAddress<?> other
      * @return  new IPAddress<?> object after the AND oper
      */
-    public abstract IPAddress<?> or(IPAddress<?> other);
+    public abstract F or(F other);
 
     /**
      * Returns a new IPAddress object with the bits inverted
      * @return  IPAddress<?>
      */
-    public abstract IPAddress<?> not();
+    public abstract F not();
 
     @Override
     public abstract boolean equals(Object other);
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
index f9eefc1..ba7eb93 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPAddressWithMask.java
@@ -9,7 +9,7 @@
 
     public abstract IPVersion getIpVersion();
 
-    public IPAddress<?> getSubnetBroadcastAddress() {
+    public F getSubnetBroadcastAddress() {
         if (!mask.isCidrMask()) {
             throw new IllegalArgumentException("Mask Invalid " + mask +
                                                " cannot get subnet for non CIDR mask");
@@ -17,7 +17,7 @@
         return value.or(mask.not());
     }
 
-    public boolean isSubnetBroadcastAddress(IPAddress<?> candidate) {
+    public boolean isSubnetBroadcastAddress(F candidate) {
         return getSubnetBroadcastAddress().equals(candidate);
     }
 
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
index 677fb38..43fefac 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv4Address.java
@@ -75,7 +75,7 @@
     }
 
     @Override
-    public IPv4Address and(IPAddress<?> other) {
+    public IPv4Address and(IPv4Address other) {
         if (other == null) {
             throw new NullPointerException("Other IP Address must not be null");
         }
@@ -84,7 +84,7 @@
     }
 
     @Override
-    public IPv4Address or(IPAddress<?> other) {
+    public IPv4Address or(IPv4Address other) {
         if (other == null) {
             throw new NullPointerException("Other IP Address must not be null");
         }
@@ -191,7 +191,7 @@
 
     @Override
     public IPv4Address applyMask(IPv4Address mask) {
-        return IPv4Address.of(this.rawValue & mask.rawValue);
+        return and(mask);
     }
 
     @Override
diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
index 5dcaa6e..1ee9e89 100644
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
+++ b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/types/IPv6Address.java
@@ -99,7 +99,7 @@
     }
 
     @Override
-    public IPv6Address and(IPAddress<?> other) {
+    public IPv6Address and(IPv6Address other) {
         if (other == null) {
             throw new NullPointerException("Other IP Address must not be null");
         }
@@ -108,7 +108,7 @@
     }
 
     @Override
-    public IPv6Address or(IPAddress<?> other) {
+    public IPv6Address or(IPv6Address other) {
         if (other == null) {
             throw new NullPointerException("Other IP Address must not be null");
         }
@@ -389,7 +389,7 @@
 
     @Override
     public IPv6Address applyMask(IPv6Address mask) {
-        return IPv6Address.of(this.raw1 & mask.raw1, this.raw2 & mask.raw2);
+        return and(mask);
     }
 
     @Override