diff --git a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/Wildcards.java b/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/Wildcards.java
deleted file mode 100644
index 2268ce6..0000000
--- a/java_gen/pre-written/src/main/java/org/projectfloodlight/openflow/protocol/Wildcards.java
+++ /dev/null
@@ -1,656 +0,0 @@
-/**
- *    Copyright 2013, Big Switch Networks, Inc.
- *
- *    Licensed 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.projectfloodlight.openflow.protocol;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import com.google.common.base.Joiner;
-
-/**
- * a more user friendly representation of the wildcards bits in an OpenFlow
- * match. The Wildcards object is
- * <ul>
- * <li>immutable (i.e., threadsafe)</li>
- * <li>instance managed (don't instantiate it yourself), instead call "of"</li>
- * <ul>
- * <p>
- * You can construct a Wildcard object from either its integer representation
- * </p>
- * <code>
- *    Wildcard.of(0x3820e0);
- *  </code>
- * <p>
- * Or start with either an empty or full wildcard, and select/unselect foo.
- * </p>
- * <code>
- *  Wildcard w = Wildcards.NONE
- *                .set(Flag.DL_SRC, Flag. DL_DST, Flag.DL_VLAN_PCP)
- *                .setNwDstMask(8)
- *                .setNwSrcMask(8);
- *  </code>
- * <p>
- * <b>Remember:</b> Wildcards objects are immutable. set... operations have
- * <b>NO EFFECT</b> on the current wildcard object. You HAVE to use the returned
- * changed object.
- * </p>
- *
- * @author Andreas Wundsam <andreas.wundsam@bigswitch.com>
- */
-public class Wildcards {
-    public class OFWildcardFlags {
-        final public static int OFPFW_ALL = ((1 << 22) - 1);
-
-        final public static int OFPFW_IN_PORT = 1 << 0; /* Switch input port. */
-        final public static int OFPFW_DL_VLAN = 1 << 1; /* VLAN id. */
-        final public static int OFPFW_DL_SRC = 1 << 2; /* Ethernet source address. */
-        final public static int OFPFW_DL_DST = 1 << 3; /*
-                                                        * Ethernet destination
-                                                        * address.
-                                                        */
-        final public static int OFPFW_DL_TYPE = 1 << 4; /* Ethernet frame type. */
-        final public static int OFPFW_NW_PROTO = 1 << 5; /* IP protocol. */
-        final public static int OFPFW_TP_SRC = 1 << 6; /* TCP/UDP source port. */
-        final public static int OFPFW_TP_DST = 1 << 7; /* TCP/UDP destination port. */
-
-        /*
-         * IP source address wildcard bit count. 0 is exact match, 1 ignores the
-         * LSB, 2 ignores the 2 least-significant bits, ..., 32 and higher wildcard
-         * the entire field. This is the *opposite* of the usual convention where
-         * e.g. /24 indicates that 8 bits (not 24 bits) are wildcarded.
-         */
-        final public static int OFPFW_NW_SRC_SHIFT = 8;
-        final public static int OFPFW_NW_SRC_BITS = 6;
-        final public static int OFPFW_NW_SRC_MASK = ((1 << OFPFW_NW_SRC_BITS) - 1) << OFPFW_NW_SRC_SHIFT;
-        final public static int OFPFW_NW_SRC_ALL = 32 << OFPFW_NW_SRC_SHIFT;
-
-        /* IP destination address wildcard bit count. Same format as source. */
-        final public static int OFPFW_NW_DST_SHIFT = 14;
-        final public static int OFPFW_NW_DST_BITS = 6;
-        final public static int OFPFW_NW_DST_MASK = ((1 << OFPFW_NW_DST_BITS) - 1) << OFPFW_NW_DST_SHIFT;
-        final public static int OFPFW_NW_DST_ALL = 32 << OFPFW_NW_DST_SHIFT;
-
-        final public static int OFPFW_DL_VLAN_PCP = 1 << 20; /* VLAN priority. */
-        final public static int OFPFW_NW_TOS = 1 << 21; /*
-                                                         * IP ToS (DSCP field, 6
-                                                         * bits).
-                                                         */
-
-        final public static int OFPFW_ALL_SANITIZED = (((1 << 22) - 1)
-                                                       & ~OFPFW_NW_SRC_MASK & ~OFPFW_NW_DST_MASK)
-                                                      | OFPFW_NW_SRC_ALL
-                                                      | OFPFW_NW_DST_ALL;
-
-
-    }
-
-    public final static Wildcards FULL = new Wildcards(OFWildcardFlags.OFPFW_ALL_SANITIZED);
-    private static final int FULL_INT = FULL.getInt();
-
-    public final static Wildcards EXACT = new Wildcards(0);
-
-    // floodlight common case: matches on inport + l2
-    public final static int INT_INPORT_L2_MATCH = 0x3820e0;
-    public final static Wildcards INPORT_L2_MATCH = new Wildcards(
-            INT_INPORT_L2_MATCH);
-
-    /**
-     * enum type for the binary flags that can be set in the wildcards field of
-     * an OFWildcardFlags. Replaces the unwieldy c-ish int constants in OFWildcardFlags.
-     */
-    public static enum Flag {
-        IN_PORT(OFWildcardFlags.OFPFW_IN_PORT),  /* Switch input port. */
-        DL_VLAN(OFWildcardFlags.OFPFW_DL_VLAN), /* VLAN id. */
-        DL_SRC(OFWildcardFlags.OFPFW_DL_SRC), /* Ethernet source address. */
-        DL_DST(OFWildcardFlags.OFPFW_DL_DST), /* Ethernet destination addr */
-        DL_TYPE(OFWildcardFlags.OFPFW_DL_TYPE), /* Ethernet frame type. */
-        NW_PROTO(OFWildcardFlags.OFPFW_NW_PROTO), /* IP protocol. */
-        TP_SRC(OFWildcardFlags.OFPFW_TP_SRC), /* TCP/UDP source port. */
-        TP_DST(OFWildcardFlags.OFPFW_TP_DST), /* TCP/UDP destination port. */
-        DL_VLAN_PCP(OFWildcardFlags.OFPFW_DL_VLAN_PCP), /* VLAN priority. */
-        NW_SRC(-1) { /*
-                      * virtual NW_SRC flag => translates to the strange 6 bits
-                      * in the header
-                      */
-            @Override
-            boolean isBolean() {
-                return false;
-            }
-
-            @Override
-            int getInt(int flags) {
-                return ((flags & OFWildcardFlags.OFPFW_NW_SRC_MASK) >> OFWildcardFlags.OFPFW_NW_SRC_SHIFT);
-            }
-
-            @Override
-            int setInt(int flags, int srcMask) {
-                return (flags & ~OFWildcardFlags.OFPFW_NW_SRC_MASK) | (srcMask << OFWildcardFlags.OFPFW_NW_SRC_SHIFT);
-            }
-
-            @Override
-            int wildcard(int flags) {
-                return flags & ~OFWildcardFlags.OFPFW_NW_SRC_MASK;
-            }
-
-            @Override
-            int matchOn(int flags) {
-                return flags | OFWildcardFlags.OFPFW_NW_SRC_ALL;
-            }
-
-            @Override
-            boolean isPartiallyOn(int flags) {
-                int intValue = getInt(flags);
-                return intValue > 0 && intValue < 32;
-            }
-
-            @Override
-            boolean isFullyOn(int flags) {
-                return getInt(flags) >= 32;
-            }
-
-        },
-        NW_DST(-1) { /*
-                      * virtual NW_SRC flag => translates to the strange 6 bits
-                      * in the header
-                      */
-            @Override
-            boolean isBolean() {
-                return false;
-            }
-
-            @Override
-            int getInt(int flags) {
-                return ((flags & OFWildcardFlags.OFPFW_NW_DST_MASK) >> OFWildcardFlags.OFPFW_NW_DST_SHIFT);
-            }
-
-            @Override
-            int setInt(int flags, int srcMask) {
-                return (flags & ~OFWildcardFlags.OFPFW_NW_DST_MASK) | (srcMask << OFWildcardFlags.OFPFW_NW_DST_SHIFT);
-            }
-
-            @Override
-            int wildcard(int flags) {
-                return flags & ~OFWildcardFlags.OFPFW_NW_DST_MASK;
-            }
-
-            @Override
-            int matchOn(int flags) {
-                return flags | OFWildcardFlags.OFPFW_NW_DST_ALL;
-            }
-
-            @Override
-            boolean isFullyOn(int flags) {
-                return getInt(flags) >= 32;
-            }
-        },
-        NW_TOS(OFWildcardFlags.OFPFW_NW_TOS); /* IP ToS (DSCP field, 6 bits). */
-
-        final int bitPosition;
-
-        Flag(int bitPosition) {
-            this.bitPosition = bitPosition;
-        }
-
-        /**
-         * @return a modified OF-1.0 flags field with this flag cleared (match
-         *         on this field)
-         */
-        int matchOn(int flags) {
-            return flags & ~this.bitPosition;
-        }
-
-        /**
-         * @return a modified OF-1.0 flags field with this flag set (wildcard
-         *         this field)
-         */
-        int wildcard(int flags) {
-            return flags | this.bitPosition;
-        }
-
-        /**
-         * @return true iff this is a true boolean flag that can either be off
-         *         or on.True in OF-1.0 for all fields except NW_SRC and NW_DST
-         */
-        boolean isBolean() {
-            return false;
-        }
-
-        /**
-         * @return true iff this wildcard field is currently 'partially on'.
-         *         Always false for true Boolean Flags. Can be true in OF-1.0
-         *         for NW_SRC, NW_DST.
-         */
-        boolean isPartiallyOn(int flags) {
-            return false;
-        }
-
-        /**
-         * @return true iff this wildcard field currently fully on (fully
-         *         wildcarded). Equivalent to the boolean flag being set in the
-         *         bitmask for bit flags, and to the wildcarded bit length set
-         *         to >=32 for NW_SRC and NW_DST
-         * @param flags
-         * @return
-         */
-        boolean isFullyOn(int flags) {
-            return (flags & this.bitPosition) != 0;
-        }
-
-        /**
-         * set the integer representation of this flag. only for NW_SRC and
-         * NW_DST
-         */
-        int setInt(int flags, int srcMask) {
-            throw new UnsupportedOperationException();
-        }
-
-        /**
-         * set the integer representation of this flag. only for NW_SRC and
-         * NW_DST
-         */
-        int getInt(int flags) {
-            throw new UnsupportedOperationException();
-        }
-
-
-    }
-
-    private final int flags;
-
-    /** private constructor. use Wildcard.of() instead */
-    private Wildcards(int flags) {
-        this.flags = flags;
-    }
-
-    /**
-     * return a wildcard object matching the given int flags. May reuse / cache
-     * frequently used wildcard instances. Don't rely on it though (use equals
-     * not ==).
-     *
-     * @param flags
-     * @return
-     */
-    public static Wildcards of(int paramFlags) {
-        int flags = paramFlags; //sanitizeInt(paramFlags);
-        switch(flags) {
-            case 0x0000:
-                return EXACT;
-            case OFWildcardFlags.OFPFW_ALL_SANITIZED:
-                return FULL;
-            case INT_INPORT_L2_MATCH:
-                return INPORT_L2_MATCH;
-            default:
-                return new Wildcards(flags);
-        }
-    }
-
-    /** convience method return a wildcard for exactly one set flag */
-    public static Wildcards of(Wildcards.Flag setFlag) {
-        return Wildcards.of(setFlag.wildcard(0));
-    }
-
-    /** convience method return a wildcard for exactly two set flags */
-    public static Wildcards of(Wildcards.Flag setFlag, Wildcards.Flag setFlag2) {
-        return Wildcards.of(setFlag.wildcard(setFlag2.wildcard(0)));
-    }
-
-    /** convience method return a wildcard for an arbitrary number of set flags */
-    public static Wildcards of(Wildcards.Flag... setFlags) {
-        int flags = 0;
-        for (Wildcards.Flag flag : setFlags)
-            flags = flag.wildcard(0);
-        return Wildcards.of(flags);
-    }
-
-    /** convience method return a wildcards for ofmatches that match on one flag */
-    public static Wildcards ofMatches(Wildcards.Flag setFlag) {
-        return Wildcards.of(setFlag.matchOn(FULL_INT));
-    }
-
-    /**
-     * convience method return a wildcard for for an ofmatch that match on two
-     * flags
-     */
-    public static Wildcards ofMatches(Wildcards.Flag setFlag, Wildcards.Flag setFlag2) {
-        return Wildcards.of(setFlag.matchOn(setFlag2.matchOn(FULL_INT)));
-    }
-
-    /**
-     * convience method return a wildcard for an ofmatch that amtch on an
-     * arbitrary number of set flags
-     */
-    public static Wildcards ofMatches(Wildcards.Flag... setFlags) {
-        int flags = FULL_INT;
-        for (Wildcards.Flag flag : setFlags)
-           flags = flag.matchOn(flags);
-        return Wildcards.of(flags);
-    }
-
-    public static Wildcards ofMatches(Set<Wildcards.Flag> wSet) {
-        int flags = FULL_INT;
-        for (Wildcards.Flag flag : wSet)
-           flags = flag.matchOn(flags);
-        return Wildcards.of(flags);
-    }
-
-    /**
-     * return a Wildcards object that has the given flags set
-     * <p>
-     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
-     * unmodified. </b>
-     */
-    public Wildcards wildcard(Wildcards.Flag flag) {
-        int flags = flag.wildcard(this.flags);
-        if (flags == this.flags)
-            return this;
-        else
-            return new Wildcards(flags);
-    }
-
-    /**
-     * return a Wildcards object that has the given flags set
-     * <p>
-     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
-     * unmodified. </b>
-     */
-    public Wildcards wildcard(Wildcards.Flag flag, Wildcards.Flag flag2) {
-        int flags = flag.wildcard(flag2.wildcard(this.flags));
-        if (flags == this.flags)
-            return this;
-        else
-            return new Wildcards(flags);
-    }
-
-    /**
-     * return a Wildcards object that has the given flags wildcarded
-     * <p>
-     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
-     * unmodified. </b>
-     */
-    public Wildcards wildcard(Wildcards.Flag... setFlags) {
-        int flags = this.flags;
-        for (Wildcards.Flag flag : setFlags)
-            flags = flag.wildcard(flags);
-        if (flags == this.flags)
-            return this;
-        else
-            return new Wildcards(flags);
-    }
-
-    /**
-     * return a Wildcards object that matches on exactly the given flag
-     * <p>
-     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
-     * unmodified. </b>
-     */
-    public Wildcards matchOn(Wildcards.Flag flag) {
-        int flags = flag.matchOn(this.flags);
-        if (flags == this.flags)
-            return this;
-        else
-            return new Wildcards(flags);
-    }
-
-    /**
-     * return a Wildcards object that matches on exactly the given flags
-     * <p>
-     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
-     * unmodified. </b>
-     */
-    public Wildcards matchOn(Wildcards.Flag flag, Wildcards.Flag flag2) {
-        int flags = flag.matchOn(flag2.matchOn(this.flags));
-        if (flags == this.flags)
-            return this;
-        else
-            return new Wildcards(flags);
-    }
-
-    /**
-     * return a Wildcards object that matches on exactly the given flags
-     * <p>
-     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
-     * unmodified. </b>
-     */
-    public Wildcards matchOn(Wildcards.Flag... setFlags) {
-        int flags = this.flags;
-        for (Wildcards.Flag flag : setFlags)
-            flags = flag.matchOn(flags);
-        if (flags == this.flags)
-            return this;
-        else
-            return new Wildcards(flags);
-    }
-
-    /**
-     * return the nw src mask in normal CIDR style, e.g., 8 means x.x.x.x/8
-     * means 8 bits wildcarded
-     */
-    public int getNwSrcMask() {
-        return Math.max(0, 32 - Flag.NW_SRC.getInt(flags));
-    }
-
-    /**
-     * return the nw dst mask in normal CIDR style, e.g., 8 means x.x.x.x/8
-     * means 8 bits wildcarded
-     */
-    public int getNwDstMask() {
-        return Math.max(0, 32 - Flag.NW_DST.getInt(flags));
-    }
-
-    /**
-     * return a Wildcard object that has the given nwSrcCidrMask set.
-     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
-     * unmodified. </b>
-     *
-     * @param srcCidrMask
-     *            source mask to set in <b>normal CIDR notation</b>, i.e., 8
-     *            means x.x.x.x/8
-     * @return a modified object
-     */
-    public Wildcards withNwSrcMask(int srcCidrMask) {
-        int flags = Flag.NW_SRC.setInt(this.flags, Math.max(0, 32 - srcCidrMask));
-        if (flags == this.flags)
-            return this;
-        else
-            return new Wildcards(flags);
-    }
-
-    /**
-     * return a Wildcard object that has the given nwDstCidrMask set.
-     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
-     * unmodified. </b>
-     *
-     * @param dstCidrMask
-     *            dest mask to set in <b>normal CIDR notation</b>, i.e., 8 means
-     *            x.x.x.x/8
-     * @return a modified object
-     */
-    public Wildcards withNwDstMask(int dstCidrMask) {
-        int flags = Flag.NW_DST.setInt(this.flags, Math.max(0, 32 - dstCidrMask));
-        if (flags == this.flags)
-            return this;
-        else
-            return new Wildcards(flags);
-    }
-
-    /**
-     * return a Wildcard object that is inverted to this wildcard object.
-     * <b>NOTE:</b> NOT a mutator function. 'this' wildcard object stays
-     * unmodified. </b>
-     * @return a modified object
-     */
-    public Wildcards inverted() {
-        return Wildcards.of(flags ^ OFWildcardFlags.OFPFW_ALL_SANITIZED);
-    }
-
-    public boolean isWildcarded(Flag flag) {
-        return flag.isFullyOn(flags);
-    }
-
-    /**
-     * return all wildcard flags that are fully wildcarded as an EnumSet. Do not
-     * modify. Note: some flags (like NW_SRC and NW_DST) that are partially
-     * wildcarded are not returned in this set.
-     *
-     * @return the EnumSet of wildcards
-     */
-    public EnumSet<Wildcards.Flag> getWildcardedFlags() {
-        EnumSet<Wildcards.Flag> res = EnumSet.noneOf(Wildcards.Flag.class);
-        for (Wildcards.Flag flag : Flag.values()) {
-            if (flag.isFullyOn(flags)) {
-                res.add(flag);
-            }
-        }
-        return res;
-    }
-
-    /** return the OpenFlow 'wire' integer representation of these wildcards */
-    public int getInt() {
-        return flags;
-    }
-
-    /**
-     * return the OpenFlow 'wire' integer representation of these wildcards.
-     * Sanitize nw_src and nw_dst to be max. 32 (values > 32 are technically
-     * possible, but don't make semantic sense)
-     */
-    public static int sanitizeInt(int flags) {
-        if (((flags & OFWildcardFlags.OFPFW_NW_SRC_MASK) >> OFWildcardFlags.OFPFW_NW_SRC_SHIFT) > 32) {
-            flags = (flags & ~OFWildcardFlags.OFPFW_NW_SRC_MASK) | OFWildcardFlags.OFPFW_NW_SRC_ALL;
-        }
-        if (((flags & OFWildcardFlags.OFPFW_NW_DST_MASK) >> OFWildcardFlags.OFPFW_NW_DST_SHIFT) > 32) {
-            flags = (flags & ~OFWildcardFlags.OFPFW_NW_DST_MASK) | OFWildcardFlags.OFPFW_NW_DST_ALL;
-        }
-        return flags;
-    }
-
-    /**
-     * is this a wildcard set that has all flags set + and full (/0) nw_src and
-     * nw_dst wildcarding ?
-     */
-    public boolean isFull() {
-        return flags == OFWildcardFlags.OFPFW_ALL || flags == OFWildcardFlags.OFPFW_ALL_SANITIZED;
-    }
-
-    /** is this a wildcard of an exact match */
-    public boolean isExact() {
-        return flags == 0;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + flags;
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (getClass() != obj.getClass())
-            return false;
-        Wildcards other = (Wildcards) obj;
-        if (flags != other.flags)
-            return false;
-        return true;
-    }
-
-    private final static Joiner pipeJoiner = Joiner.on("|");
-
-    @Override
-    public String toString() {
-        List<String> res = new ArrayList<String>();
-        for (Wildcards.Flag flag : Flag.values()) {
-            if (flag.isFullyOn(flags)) {
-                res.add(flag.name().toLowerCase());
-            }
-        }
-
-        if (Flag.NW_SRC.isPartiallyOn(flags)) {
-            res.add("nw_src(/" + getNwSrcMask() + ")");
-        }
-
-        if (Flag.NW_DST.isPartiallyOn(flags)) {
-            res.add("nw_dst(/" + getNwDstMask() + ")");
-        }
-
-        return pipeJoiner.join(res);
-    }
-
-    private final static Joiner commaJoiner = Joiner.on(", ");
-
-    /** a Java expression that constructs 'this' wildcards set */
-    public String toJava() {
-        if(isFull()) {
-            return "Wildcards.FULL";
-        } else  if (isExact()){
-            return "Wildcards.EXACT";
-        }
-
-        StringBuilder b = new StringBuilder();
-
-        EnumSet<Flag> myFlags = getWildcardedFlags();
-        if (myFlags.size() < 3) {
-            // default to start with empty
-            b.append("Wildcards.of("
-                     + commaJoiner.join(prefix("Flag.", myFlags.iterator())) + ")");
-        } else {
-            // too many - start with full
-
-            EnumSet<Flag> invFlags = inverted().getWildcardedFlags();
-            b.append("Wildcards.ofMatches("
-                     + commaJoiner.join(prefix("Flag.", invFlags.iterator())) + ")");
-        }
-        if (Flag.NW_SRC.isPartiallyOn(flags)) {
-            b.append(".setNwSrcMask(" + getNwSrcMask() + ")");
-        }
-        if (Flag.NW_DST.isPartiallyOn(flags)) {
-            b.append(".setNwDstMask(" + getNwDstMask() + ")");
-        }
-        return b.toString();
-    }
-
-    private Iterator<String> prefix(final String prefix, final Iterator<?> i) {
-        return new Iterator<String>() {
-
-            @Override
-            public boolean hasNext() {
-                return i.hasNext();
-            }
-
-            @Override
-            public String next() {
-                Object next = i.next();
-                return next == null ? null : prefix + next.toString();
-            }
-
-            @Override
-            public void remove() {
-                i.remove();
-            }
-        };
-    }
-
-
-}
\ No newline at end of file
