diff --git a/conf/onos.properties b/conf/onos.properties
index 668da42..d186e54 100644
--- a/conf/onos.properties
+++ b/conf/onos.properties
@@ -11,7 +11,6 @@
 net.floodlightcontroller.restserver.RestApiServer.port = 8080
 net.floodlightcontroller.core.FloodlightProvider.openflowport = 6633
 net.floodlightcontroller.core.FloodlightProvider.workerthreads = 16
-net.floodlightcontroller.jython.JythonDebugInterface.port = 6655
 net.floodlightcontroller.forwarding.Forwarding.idletimeout = 5
 net.floodlightcontroller.forwarding.Forwarding.hardtimeout = 0
 net.floodlightcontroller.onoslistener.OnosPublisher.dbconf = /tmp/cassandra.titan
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Constants.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Constants.java
deleted file mode 100644
index d1ef80b..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Constants.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("all") public class Constants {
-
-  public static final String VERSION = "0.1.0";
-
-}
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Message.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Message.java
deleted file mode 100644
index 8e4d989..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Message.java
+++ /dev/null
@@ -1,446 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("all") public class Message implements org.apache.thrift.TBase<Message, Message._Fields>, java.io.Serializable, Cloneable {
-  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Message");
-
-  private static final org.apache.thrift.protocol.TField SESSION_IDS_FIELD_DESC = new org.apache.thrift.protocol.TField("sessionIDs", org.apache.thrift.protocol.TType.LIST, (short)1);
-  private static final org.apache.thrift.protocol.TField PACKET_FIELD_DESC = new org.apache.thrift.protocol.TField("packet", org.apache.thrift.protocol.TType.STRUCT, (short)2);
-
-  public List<String> sessionIDs; // required
-  public Packet packet; // required
-
-  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-    SESSION_IDS((short)1, "sessionIDs"),
-    PACKET((short)2, "packet");
-
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-    static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
-        byName.put(field.getFieldName(), field);
-      }
-    }
-
-    /**
-     * Find the _Fields constant that matches fieldId, or null if its not found.
-     */
-    public static _Fields findByThriftId(int fieldId) {
-      switch(fieldId) {
-        case 1: // SESSION_IDS
-          return SESSION_IDS;
-        case 2: // PACKET
-          return PACKET;
-        default:
-          return null;
-      }
-    }
-
-    /**
-     * Find the _Fields constant that matches fieldId, throwing an exception
-     * if it is not found.
-     */
-    public static _Fields findByThriftIdOrThrow(int fieldId) {
-      _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-      return fields;
-    }
-
-    /**
-     * Find the _Fields constant that matches name, or null if its not found.
-     */
-    public static _Fields findByName(String name) {
-      return byName.get(name);
-    }
-
-    private final short _thriftId;
-    private final String _fieldName;
-
-    _Fields(short thriftId, String fieldName) {
-      _thriftId = thriftId;
-      _fieldName = fieldName;
-    }
-
-    public short getThriftFieldId() {
-      return _thriftId;
-    }
-
-    public String getFieldName() {
-      return _fieldName;
-    }
-  }
-
-  // isset id assignments
-
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-  static {
-    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-    tmpMap.put(_Fields.SESSION_IDS, new org.apache.thrift.meta_data.FieldMetaData("sessionIDs", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
-            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING))));
-    tmpMap.put(_Fields.PACKET, new org.apache.thrift.meta_data.FieldMetaData("packet", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Packet.class)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
-    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Message.class, metaDataMap);
-  }
-
-  public Message() {
-  }
-
-  public Message(
-    List<String> sessionIDs,
-    Packet packet)
-  {
-    this();
-    this.sessionIDs = sessionIDs;
-    this.packet = packet;
-  }
-
-  /**
-   * Performs a deep copy on <i>other</i>.
-   */
-  public Message(Message other) {
-    if (other.isSetSessionIDs()) {
-      List<String> __this__sessionIDs = new ArrayList<String>();
-      for (String other_element : other.sessionIDs) {
-        __this__sessionIDs.add(other_element);
-      }
-      this.sessionIDs = __this__sessionIDs;
-    }
-    if (other.isSetPacket()) {
-      this.packet = new Packet(other.packet);
-    }
-  }
-
-  public Message deepCopy() {
-    return new Message(this);
-  }
-
-  @Override
-  public void clear() {
-    this.sessionIDs = null;
-    this.packet = null;
-  }
-
-  public int getSessionIDsSize() {
-    return (this.sessionIDs == null) ? 0 : this.sessionIDs.size();
-  }
-
-  public java.util.Iterator<String> getSessionIDsIterator() {
-    return (this.sessionIDs == null) ? null : this.sessionIDs.iterator();
-  }
-
-  public void addToSessionIDs(String elem) {
-    if (this.sessionIDs == null) {
-      this.sessionIDs = new ArrayList<String>();
-    }
-    this.sessionIDs.add(elem);
-  }
-
-  public List<String> getSessionIDs() {
-    return this.sessionIDs;
-  }
-
-  public Message setSessionIDs(List<String> sessionIDs) {
-    this.sessionIDs = sessionIDs;
-    return this;
-  }
-
-  public void unsetSessionIDs() {
-    this.sessionIDs = null;
-  }
-
-  /** Returns true if field sessionIDs is set (has been assigned a value) and false otherwise */
-  public boolean isSetSessionIDs() {
-    return this.sessionIDs != null;
-  }
-
-  public void setSessionIDsIsSet(boolean value) {
-    if (!value) {
-      this.sessionIDs = null;
-    }
-  }
-
-  public Packet getPacket() {
-    return this.packet;
-  }
-
-  public Message setPacket(Packet packet) {
-    this.packet = packet;
-    return this;
-  }
-
-  public void unsetPacket() {
-    this.packet = null;
-  }
-
-  /** Returns true if field packet is set (has been assigned a value) and false otherwise */
-  public boolean isSetPacket() {
-    return this.packet != null;
-  }
-
-  public void setPacketIsSet(boolean value) {
-    if (!value) {
-      this.packet = null;
-    }
-  }
-
-  public void setFieldValue(_Fields field, Object value) {
-    switch (field) {
-    case SESSION_IDS:
-      if (value == null) {
-        unsetSessionIDs();
-      } else {
-        setSessionIDs((List<String>)value);
-      }
-      break;
-
-    case PACKET:
-      if (value == null) {
-        unsetPacket();
-      } else {
-        setPacket((Packet)value);
-      }
-      break;
-
-    }
-  }
-
-  public Object getFieldValue(_Fields field) {
-    switch (field) {
-    case SESSION_IDS:
-      return getSessionIDs();
-
-    case PACKET:
-      return getPacket();
-
-    }
-    throw new IllegalStateException();
-  }
-
-  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-  public boolean isSet(_Fields field) {
-    if (field == null) {
-      throw new IllegalArgumentException();
-    }
-
-    switch (field) {
-    case SESSION_IDS:
-      return isSetSessionIDs();
-    case PACKET:
-      return isSetPacket();
-    }
-    throw new IllegalStateException();
-  }
-
-  @Override
-  public boolean equals(Object that) {
-    if (that == null)
-      return false;
-    if (that instanceof Message)
-      return this.equals((Message)that);
-    return false;
-  }
-
-  public boolean equals(Message that) {
-    if (that == null)
-      return false;
-
-    boolean this_present_sessionIDs = true && this.isSetSessionIDs();
-    boolean that_present_sessionIDs = true && that.isSetSessionIDs();
-    if (this_present_sessionIDs || that_present_sessionIDs) {
-      if (!(this_present_sessionIDs && that_present_sessionIDs))
-        return false;
-      if (!this.sessionIDs.equals(that.sessionIDs))
-        return false;
-    }
-
-    boolean this_present_packet = true && this.isSetPacket();
-    boolean that_present_packet = true && that.isSetPacket();
-    if (this_present_packet || that_present_packet) {
-      if (!(this_present_packet && that_present_packet))
-        return false;
-      if (!this.packet.equals(that.packet))
-        return false;
-    }
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    return 0;
-  }
-
-  public int compareTo(Message other) {
-    if (!getClass().equals(other.getClass())) {
-      return getClass().getName().compareTo(other.getClass().getName());
-    }
-
-    int lastComparison = 0;
-    Message typedOther = (Message)other;
-
-    lastComparison = Boolean.valueOf(isSetSessionIDs()).compareTo(typedOther.isSetSessionIDs());
-    if (lastComparison != 0) {
-      return lastComparison;
-    }
-    if (isSetSessionIDs()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sessionIDs, typedOther.sessionIDs);
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-    }
-    lastComparison = Boolean.valueOf(isSetPacket()).compareTo(typedOther.isSetPacket());
-    if (lastComparison != 0) {
-      return lastComparison;
-    }
-    if (isSetPacket()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.packet, typedOther.packet);
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-    }
-    return 0;
-  }
-
-  public _Fields fieldForId(int fieldId) {
-    return _Fields.findByThriftId(fieldId);
-  }
-
-  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    org.apache.thrift.protocol.TField field;
-    iprot.readStructBegin();
-    while (true)
-    {
-      field = iprot.readFieldBegin();
-      if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-        break;
-      }
-      switch (field.id) {
-        case 1: // SESSION_IDS
-          if (field.type == org.apache.thrift.protocol.TType.LIST) {
-            {
-              org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
-              this.sessionIDs = new ArrayList<String>(_list0.size);
-              for (int _i1 = 0; _i1 < _list0.size; ++_i1)
-              {
-                String _elem2; // required
-                _elem2 = iprot.readString();
-                this.sessionIDs.add(_elem2);
-              }
-              iprot.readListEnd();
-            }
-          } else { 
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-          }
-          break;
-        case 2: // PACKET
-          if (field.type == org.apache.thrift.protocol.TType.STRUCT) {
-            this.packet = new Packet();
-            this.packet.read(iprot);
-          } else { 
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-          }
-          break;
-        default:
-          org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-      }
-      iprot.readFieldEnd();
-    }
-    iprot.readStructEnd();
-
-    // check for required fields of primitive type, which can't be checked in the validate method
-    validate();
-  }
-
-  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-    validate();
-
-    oprot.writeStructBegin(STRUCT_DESC);
-    if (this.sessionIDs != null) {
-      oprot.writeFieldBegin(SESSION_IDS_FIELD_DESC);
-      {
-        oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, this.sessionIDs.size()));
-        for (String _iter3 : this.sessionIDs)
-        {
-          oprot.writeString(_iter3);
-        }
-        oprot.writeListEnd();
-      }
-      oprot.writeFieldEnd();
-    }
-    if (this.packet != null) {
-      oprot.writeFieldBegin(PACKET_FIELD_DESC);
-      this.packet.write(oprot);
-      oprot.writeFieldEnd();
-    }
-    oprot.writeFieldStop();
-    oprot.writeStructEnd();
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("Message(");
-    boolean first = true;
-
-    sb.append("sessionIDs:");
-    if (this.sessionIDs == null) {
-      sb.append("null");
-    } else {
-      sb.append(this.sessionIDs);
-    }
-    first = false;
-    if (!first) sb.append(", ");
-    sb.append("packet:");
-    if (this.packet == null) {
-      sb.append("null");
-    } else {
-      sb.append(this.packet);
-    }
-    first = false;
-    sb.append(")");
-    return sb.toString();
-  }
-
-  public void validate() throws org.apache.thrift.TException {
-    // check for required fields
-  }
-
-  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-    try {
-      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-    } catch (org.apache.thrift.TException te) {
-      throw new java.io.IOException(te);
-    }
-  }
-
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-    try {
-      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-    } catch (org.apache.thrift.TException te) {
-      throw new java.io.IOException(te);
-    }
-  }
-
-}
-
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/OFMessageType.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/OFMessageType.java
deleted file mode 100644
index b9b2843..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/OFMessageType.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-
-import java.util.Map;
-import java.util.HashMap;
-import org.apache.thrift.TEnum;
-
-/**
- * OFMessage type
- * 
- */
-@SuppressWarnings("all") public enum OFMessageType implements org.apache.thrift.TEnum {
-  HELLO(0),
-  ERROR(1),
-  ECHO_REQUEST(2),
-  ECHO_REPLY(3),
-  VENDOR(4),
-  FEATURES_REQUEST(5),
-  FEATURES_REPLY(6),
-  GET_CONFIG_REQUEST(7),
-  GET_CONFIG_REPLY(8),
-  SET_CONFIG(9),
-  PACKET_IN(10),
-  FLOW_REMOVED(11),
-  PORT_STATUS(12),
-  PACKET_OUT(13),
-  FLOW_MOD(14),
-  PORT_MOD(15),
-  STATS_REQUEST(16),
-  STATS_REPLY(17),
-  BARRIER_REQUEST(18),
-  BARRIER_REPLY(19);
-
-  private final int value;
-
-  private OFMessageType(int value) {
-    this.value = value;
-  }
-
-  /**
-   * Get the integer value of this enum value, as defined in the Thrift IDL.
-   */
-  public int getValue() {
-    return value;
-  }
-
-  /**
-   * Find a the enum type by its integer value, as defined in the Thrift IDL.
-   * @return null if the value is not found.
-   */
-  public static OFMessageType findByValue(int value) { 
-    switch (value) {
-      case 0:
-        return HELLO;
-      case 1:
-        return ERROR;
-      case 2:
-        return ECHO_REQUEST;
-      case 3:
-        return ECHO_REPLY;
-      case 4:
-        return VENDOR;
-      case 5:
-        return FEATURES_REQUEST;
-      case 6:
-        return FEATURES_REPLY;
-      case 7:
-        return GET_CONFIG_REQUEST;
-      case 8:
-        return GET_CONFIG_REPLY;
-      case 9:
-        return SET_CONFIG;
-      case 10:
-        return PACKET_IN;
-      case 11:
-        return FLOW_REMOVED;
-      case 12:
-        return PORT_STATUS;
-      case 13:
-        return PACKET_OUT;
-      case 14:
-        return FLOW_MOD;
-      case 15:
-        return PORT_MOD;
-      case 16:
-        return STATS_REQUEST;
-      case 17:
-        return STATS_REPLY;
-      case 18:
-        return BARRIER_REQUEST;
-      case 19:
-        return BARRIER_REPLY;
-      default:
-        return null;
-    }
-  }
-}
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Packet.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Packet.java
deleted file mode 100644
index 65c140f..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Packet.java
+++ /dev/null
@@ -1,525 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("all") public class Packet implements org.apache.thrift.TBase<Packet, Packet._Fields>, java.io.Serializable, Cloneable {
-  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Packet");
-
-  private static final org.apache.thrift.protocol.TField MESSAGE_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("messageType", org.apache.thrift.protocol.TType.I32, (short)1);
-  private static final org.apache.thrift.protocol.TField SW_PORT_TUPLE_FIELD_DESC = new org.apache.thrift.protocol.TField("swPortTuple", org.apache.thrift.protocol.TType.STRUCT, (short)2);
-  private static final org.apache.thrift.protocol.TField DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("data", org.apache.thrift.protocol.TType.STRING, (short)3);
-
-  /**
-   * 
-   * @see OFMessageType
-   */
-  public OFMessageType messageType; // required
-  public SwitchPortTuple swPortTuple; // required
-  public ByteBuffer data; // required
-
-  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-    /**
-     * 
-     * @see OFMessageType
-     */
-    MESSAGE_TYPE((short)1, "messageType"),
-    SW_PORT_TUPLE((short)2, "swPortTuple"),
-    DATA((short)3, "data");
-
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-    static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
-        byName.put(field.getFieldName(), field);
-      }
-    }
-
-    /**
-     * Find the _Fields constant that matches fieldId, or null if its not found.
-     */
-    public static _Fields findByThriftId(int fieldId) {
-      switch(fieldId) {
-        case 1: // MESSAGE_TYPE
-          return MESSAGE_TYPE;
-        case 2: // SW_PORT_TUPLE
-          return SW_PORT_TUPLE;
-        case 3: // DATA
-          return DATA;
-        default:
-          return null;
-      }
-    }
-
-    /**
-     * Find the _Fields constant that matches fieldId, throwing an exception
-     * if it is not found.
-     */
-    public static _Fields findByThriftIdOrThrow(int fieldId) {
-      _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-      return fields;
-    }
-
-    /**
-     * Find the _Fields constant that matches name, or null if its not found.
-     */
-    public static _Fields findByName(String name) {
-      return byName.get(name);
-    }
-
-    private final short _thriftId;
-    private final String _fieldName;
-
-    _Fields(short thriftId, String fieldName) {
-      _thriftId = thriftId;
-      _fieldName = fieldName;
-    }
-
-    public short getThriftFieldId() {
-      return _thriftId;
-    }
-
-    public String getFieldName() {
-      return _fieldName;
-    }
-  }
-
-  // isset id assignments
-
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-  static {
-    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-    tmpMap.put(_Fields.MESSAGE_TYPE, new org.apache.thrift.meta_data.FieldMetaData("messageType", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, OFMessageType.class)));
-    tmpMap.put(_Fields.SW_PORT_TUPLE, new org.apache.thrift.meta_data.FieldMetaData("swPortTuple", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SwitchPortTuple.class)));
-    tmpMap.put(_Fields.DATA, new org.apache.thrift.meta_data.FieldMetaData("data", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
-    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Packet.class, metaDataMap);
-  }
-
-  public Packet() {
-  }
-
-  public Packet(
-    OFMessageType messageType,
-    SwitchPortTuple swPortTuple,
-    ByteBuffer data)
-  {
-    this();
-    this.messageType = messageType;
-    this.swPortTuple = swPortTuple;
-    this.data = data;
-  }
-
-  /**
-   * Performs a deep copy on <i>other</i>.
-   */
-  public Packet(Packet other) {
-    if (other.isSetMessageType()) {
-      this.messageType = other.messageType;
-    }
-    if (other.isSetSwPortTuple()) {
-      this.swPortTuple = new SwitchPortTuple(other.swPortTuple);
-    }
-    if (other.isSetData()) {
-      this.data = org.apache.thrift.TBaseHelper.copyBinary(other.data);
-;
-    }
-  }
-
-  public Packet deepCopy() {
-    return new Packet(this);
-  }
-
-  @Override
-  public void clear() {
-    this.messageType = null;
-    this.swPortTuple = null;
-    this.data = null;
-  }
-
-  /**
-   * 
-   * @see OFMessageType
-   */
-  public OFMessageType getMessageType() {
-    return this.messageType;
-  }
-
-  /**
-   * 
-   * @see OFMessageType
-   */
-  public Packet setMessageType(OFMessageType messageType) {
-    this.messageType = messageType;
-    return this;
-  }
-
-  public void unsetMessageType() {
-    this.messageType = null;
-  }
-
-  /** Returns true if field messageType is set (has been assigned a value) and false otherwise */
-  public boolean isSetMessageType() {
-    return this.messageType != null;
-  }
-
-  public void setMessageTypeIsSet(boolean value) {
-    if (!value) {
-      this.messageType = null;
-    }
-  }
-
-  public SwitchPortTuple getSwPortTuple() {
-    return this.swPortTuple;
-  }
-
-  public Packet setSwPortTuple(SwitchPortTuple swPortTuple) {
-    this.swPortTuple = swPortTuple;
-    return this;
-  }
-
-  public void unsetSwPortTuple() {
-    this.swPortTuple = null;
-  }
-
-  /** Returns true if field swPortTuple is set (has been assigned a value) and false otherwise */
-  public boolean isSetSwPortTuple() {
-    return this.swPortTuple != null;
-  }
-
-  public void setSwPortTupleIsSet(boolean value) {
-    if (!value) {
-      this.swPortTuple = null;
-    }
-  }
-
-  public byte[] getData() {
-    setData(org.apache.thrift.TBaseHelper.rightSize(data));
-    return data == null ? null : data.array();
-  }
-
-  public ByteBuffer bufferForData() {
-    return data;
-  }
-
-  public Packet setData(byte[] data) {
-    setData(data == null ? (ByteBuffer)null : ByteBuffer.wrap(data));
-    return this;
-  }
-
-  public Packet setData(ByteBuffer data) {
-    this.data = data;
-    return this;
-  }
-
-  public void unsetData() {
-    this.data = null;
-  }
-
-  /** Returns true if field data is set (has been assigned a value) and false otherwise */
-  public boolean isSetData() {
-    return this.data != null;
-  }
-
-  public void setDataIsSet(boolean value) {
-    if (!value) {
-      this.data = null;
-    }
-  }
-
-  public void setFieldValue(_Fields field, Object value) {
-    switch (field) {
-    case MESSAGE_TYPE:
-      if (value == null) {
-        unsetMessageType();
-      } else {
-        setMessageType((OFMessageType)value);
-      }
-      break;
-
-    case SW_PORT_TUPLE:
-      if (value == null) {
-        unsetSwPortTuple();
-      } else {
-        setSwPortTuple((SwitchPortTuple)value);
-      }
-      break;
-
-    case DATA:
-      if (value == null) {
-        unsetData();
-      } else {
-        setData((ByteBuffer)value);
-      }
-      break;
-
-    }
-  }
-
-  public Object getFieldValue(_Fields field) {
-    switch (field) {
-    case MESSAGE_TYPE:
-      return getMessageType();
-
-    case SW_PORT_TUPLE:
-      return getSwPortTuple();
-
-    case DATA:
-      return getData();
-
-    }
-    throw new IllegalStateException();
-  }
-
-  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-  public boolean isSet(_Fields field) {
-    if (field == null) {
-      throw new IllegalArgumentException();
-    }
-
-    switch (field) {
-    case MESSAGE_TYPE:
-      return isSetMessageType();
-    case SW_PORT_TUPLE:
-      return isSetSwPortTuple();
-    case DATA:
-      return isSetData();
-    }
-    throw new IllegalStateException();
-  }
-
-  @Override
-  public boolean equals(Object that) {
-    if (that == null)
-      return false;
-    if (that instanceof Packet)
-      return this.equals((Packet)that);
-    return false;
-  }
-
-  public boolean equals(Packet that) {
-    if (that == null)
-      return false;
-
-    boolean this_present_messageType = true && this.isSetMessageType();
-    boolean that_present_messageType = true && that.isSetMessageType();
-    if (this_present_messageType || that_present_messageType) {
-      if (!(this_present_messageType && that_present_messageType))
-        return false;
-      if (!this.messageType.equals(that.messageType))
-        return false;
-    }
-
-    boolean this_present_swPortTuple = true && this.isSetSwPortTuple();
-    boolean that_present_swPortTuple = true && that.isSetSwPortTuple();
-    if (this_present_swPortTuple || that_present_swPortTuple) {
-      if (!(this_present_swPortTuple && that_present_swPortTuple))
-        return false;
-      if (!this.swPortTuple.equals(that.swPortTuple))
-        return false;
-    }
-
-    boolean this_present_data = true && this.isSetData();
-    boolean that_present_data = true && that.isSetData();
-    if (this_present_data || that_present_data) {
-      if (!(this_present_data && that_present_data))
-        return false;
-      if (!this.data.equals(that.data))
-        return false;
-    }
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    return 0;
-  }
-
-  public int compareTo(Packet other) {
-    if (!getClass().equals(other.getClass())) {
-      return getClass().getName().compareTo(other.getClass().getName());
-    }
-
-    int lastComparison = 0;
-    Packet typedOther = (Packet)other;
-
-    lastComparison = Boolean.valueOf(isSetMessageType()).compareTo(typedOther.isSetMessageType());
-    if (lastComparison != 0) {
-      return lastComparison;
-    }
-    if (isSetMessageType()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.messageType, typedOther.messageType);
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-    }
-    lastComparison = Boolean.valueOf(isSetSwPortTuple()).compareTo(typedOther.isSetSwPortTuple());
-    if (lastComparison != 0) {
-      return lastComparison;
-    }
-    if (isSetSwPortTuple()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.swPortTuple, typedOther.swPortTuple);
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-    }
-    lastComparison = Boolean.valueOf(isSetData()).compareTo(typedOther.isSetData());
-    if (lastComparison != 0) {
-      return lastComparison;
-    }
-    if (isSetData()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, typedOther.data);
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-    }
-    return 0;
-  }
-
-  public _Fields fieldForId(int fieldId) {
-    return _Fields.findByThriftId(fieldId);
-  }
-
-  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    org.apache.thrift.protocol.TField field;
-    iprot.readStructBegin();
-    while (true)
-    {
-      field = iprot.readFieldBegin();
-      if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-        break;
-      }
-      switch (field.id) {
-        case 1: // MESSAGE_TYPE
-          if (field.type == org.apache.thrift.protocol.TType.I32) {
-            this.messageType = OFMessageType.findByValue(iprot.readI32());
-          } else { 
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-          }
-          break;
-        case 2: // SW_PORT_TUPLE
-          if (field.type == org.apache.thrift.protocol.TType.STRUCT) {
-            this.swPortTuple = new SwitchPortTuple();
-            this.swPortTuple.read(iprot);
-          } else { 
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-          }
-          break;
-        case 3: // DATA
-          if (field.type == org.apache.thrift.protocol.TType.STRING) {
-            this.data = iprot.readBinary();
-          } else { 
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-          }
-          break;
-        default:
-          org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-      }
-      iprot.readFieldEnd();
-    }
-    iprot.readStructEnd();
-
-    // check for required fields of primitive type, which can't be checked in the validate method
-    validate();
-  }
-
-  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-    validate();
-
-    oprot.writeStructBegin(STRUCT_DESC);
-    if (this.messageType != null) {
-      oprot.writeFieldBegin(MESSAGE_TYPE_FIELD_DESC);
-      oprot.writeI32(this.messageType.getValue());
-      oprot.writeFieldEnd();
-    }
-    if (this.swPortTuple != null) {
-      oprot.writeFieldBegin(SW_PORT_TUPLE_FIELD_DESC);
-      this.swPortTuple.write(oprot);
-      oprot.writeFieldEnd();
-    }
-    if (this.data != null) {
-      oprot.writeFieldBegin(DATA_FIELD_DESC);
-      oprot.writeBinary(this.data);
-      oprot.writeFieldEnd();
-    }
-    oprot.writeFieldStop();
-    oprot.writeStructEnd();
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("Packet(");
-    boolean first = true;
-
-    sb.append("messageType:");
-    if (this.messageType == null) {
-      sb.append("null");
-    } else {
-      sb.append(this.messageType);
-    }
-    first = false;
-    if (!first) sb.append(", ");
-    sb.append("swPortTuple:");
-    if (this.swPortTuple == null) {
-      sb.append("null");
-    } else {
-      sb.append(this.swPortTuple);
-    }
-    first = false;
-    if (!first) sb.append(", ");
-    sb.append("data:");
-    if (this.data == null) {
-      sb.append("null");
-    } else {
-      org.apache.thrift.TBaseHelper.toString(this.data, sb);
-    }
-    first = false;
-    sb.append(")");
-    return sb.toString();
-  }
-
-  public void validate() throws org.apache.thrift.TException {
-    // check for required fields
-  }
-
-  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-    try {
-      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-    } catch (org.apache.thrift.TException te) {
-      throw new java.io.IOException(te);
-    }
-  }
-
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-    try {
-      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-    } catch (org.apache.thrift.TException te) {
-      throw new java.io.IOException(te);
-    }
-  }
-
-}
-
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java
deleted file mode 100644
index f4e8ae5..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java
+++ /dev/null
@@ -1,2427 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@SuppressWarnings("all") public class PacketStreamer {
-
-  /**
-   * Packetstreamer API
-   */
-  public interface Iface {
-
-    /**
-     * Synchronous method to get packets for a given sessionid
-     * 
-     * @param sessionid
-     */
-    public List<ByteBuffer> getPackets(String sessionid) throws org.apache.thrift.TException;
-
-    /**
-     * Synchronous method to publish a packet.
-     * It ensure the order that the packets are pushed
-     * 
-     * @param packet
-     */
-    public int pushMessageSync(Message packet) throws org.apache.thrift.TException;
-
-    /**
-     * Asynchronous method to publish a packet.
-     * Order is not guaranteed.
-     * 
-     * @param packet
-     */
-    public void pushMessageAsync(Message packet) throws org.apache.thrift.TException;
-
-    /**
-     * Terminate a session
-     * 
-     * @param sessionid
-     */
-    public void terminateSession(String sessionid) throws org.apache.thrift.TException;
-
-  }
-
-  public interface AsyncIface {
-
-    public void getPackets(String sessionid, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.getPackets_call> resultHandler) throws org.apache.thrift.TException;
-
-    public void pushMessageSync(Message packet, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.pushMessageSync_call> resultHandler) throws org.apache.thrift.TException;
-
-    public void pushMessageAsync(Message packet, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.pushMessageAsync_call> resultHandler) throws org.apache.thrift.TException;
-
-    public void terminateSession(String sessionid, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.terminateSession_call> resultHandler) throws org.apache.thrift.TException;
-
-  }
-
-  public static class Client extends org.apache.thrift.TServiceClient implements Iface {
-    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
-      public Factory() {}
-      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
-        return new Client(prot);
-      }
-      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
-        return new Client(iprot, oprot);
-      }
-    }
-
-    public Client(org.apache.thrift.protocol.TProtocol prot)
-    {
-      super(prot, prot);
-    }
-
-    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
-      super(iprot, oprot);
-    }
-
-    public List<ByteBuffer> getPackets(String sessionid) throws org.apache.thrift.TException
-    {
-      send_getPackets(sessionid);
-      return recv_getPackets();
-    }
-
-    public void send_getPackets(String sessionid) throws org.apache.thrift.TException
-    {
-      getPackets_args args = new getPackets_args();
-      args.setSessionid(sessionid);
-      sendBase("getPackets", args);
-    }
-
-    public List<ByteBuffer> recv_getPackets() throws org.apache.thrift.TException
-    {
-      getPackets_result result = new getPackets_result();
-      receiveBase(result, "getPackets");
-      if (result.isSetSuccess()) {
-        return result.success;
-      }
-      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getPackets failed: unknown result");
-    }
-
-    public int pushMessageSync(Message packet) throws org.apache.thrift.TException
-    {
-      send_pushMessageSync(packet);
-      return recv_pushMessageSync();
-    }
-
-    public void send_pushMessageSync(Message packet) throws org.apache.thrift.TException
-    {
-      pushMessageSync_args args = new pushMessageSync_args();
-      args.setPacket(packet);
-      sendBase("pushMessageSync", args);
-    }
-
-    public int recv_pushMessageSync() throws org.apache.thrift.TException
-    {
-      pushMessageSync_result result = new pushMessageSync_result();
-      receiveBase(result, "pushMessageSync");
-      if (result.isSetSuccess()) {
-        return result.success;
-      }
-      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "pushMessageSync failed: unknown result");
-    }
-
-    public void pushMessageAsync(Message packet) throws org.apache.thrift.TException
-    {
-      send_pushMessageAsync(packet);
-    }
-
-    public void send_pushMessageAsync(Message packet) throws org.apache.thrift.TException
-    {
-      pushMessageAsync_args args = new pushMessageAsync_args();
-      args.setPacket(packet);
-      sendBase("pushMessageAsync", args);
-    }
-
-    public void terminateSession(String sessionid) throws org.apache.thrift.TException
-    {
-      send_terminateSession(sessionid);
-      recv_terminateSession();
-    }
-
-    public void send_terminateSession(String sessionid) throws org.apache.thrift.TException
-    {
-      terminateSession_args args = new terminateSession_args();
-      args.setSessionid(sessionid);
-      sendBase("terminateSession", args);
-    }
-
-    public void recv_terminateSession() throws org.apache.thrift.TException
-    {
-      terminateSession_result result = new terminateSession_result();
-      receiveBase(result, "terminateSession");
-      return;
-    }
-
-  }
-  public static class AsyncClient extends org.apache.thrift.async.TAsyncClient implements AsyncIface {
-    public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
-      private org.apache.thrift.async.TAsyncClientManager clientManager;
-      private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
-      public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
-        this.clientManager = clientManager;
-        this.protocolFactory = protocolFactory;
-      }
-      public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
-        return new AsyncClient(protocolFactory, clientManager, transport);
-      }
-    }
-
-    public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
-      super(protocolFactory, clientManager, transport);
-    }
-
-    public void getPackets(String sessionid, org.apache.thrift.async.AsyncMethodCallback<getPackets_call> resultHandler) throws org.apache.thrift.TException {
-      checkReady();
-      getPackets_call method_call = new getPackets_call(sessionid, resultHandler, this, ___protocolFactory, ___transport);
-      this.___currentMethod = method_call;
-      ___manager.call(method_call);
-    }
-
-    public static class getPackets_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String sessionid;
-      public getPackets_call(String sessionid, org.apache.thrift.async.AsyncMethodCallback<getPackets_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
-        super(client, protocolFactory, transport, resultHandler, false);
-        this.sessionid = sessionid;
-      }
-
-      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
-        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getPackets", org.apache.thrift.protocol.TMessageType.CALL, 0));
-        getPackets_args args = new getPackets_args();
-        args.setSessionid(sessionid);
-        args.write(prot);
-        prot.writeMessageEnd();
-      }
-
-      public List<ByteBuffer> getResult() throws org.apache.thrift.TException {
-        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
-        }
-        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
-        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
-        return (new Client(prot)).recv_getPackets();
-      }
-    }
-
-    public void pushMessageSync(Message packet, org.apache.thrift.async.AsyncMethodCallback<pushMessageSync_call> resultHandler) throws org.apache.thrift.TException {
-      checkReady();
-      pushMessageSync_call method_call = new pushMessageSync_call(packet, resultHandler, this, ___protocolFactory, ___transport);
-      this.___currentMethod = method_call;
-      ___manager.call(method_call);
-    }
-
-    public static class pushMessageSync_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private Message packet;
-      public pushMessageSync_call(Message packet, org.apache.thrift.async.AsyncMethodCallback<pushMessageSync_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
-        super(client, protocolFactory, transport, resultHandler, false);
-        this.packet = packet;
-      }
-
-      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
-        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pushMessageSync", org.apache.thrift.protocol.TMessageType.CALL, 0));
-        pushMessageSync_args args = new pushMessageSync_args();
-        args.setPacket(packet);
-        args.write(prot);
-        prot.writeMessageEnd();
-      }
-
-      public int getResult() throws org.apache.thrift.TException {
-        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
-        }
-        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
-        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
-        return (new Client(prot)).recv_pushMessageSync();
-      }
-    }
-
-    public void pushMessageAsync(Message packet, org.apache.thrift.async.AsyncMethodCallback<pushMessageAsync_call> resultHandler) throws org.apache.thrift.TException {
-      checkReady();
-      pushMessageAsync_call method_call = new pushMessageAsync_call(packet, resultHandler, this, ___protocolFactory, ___transport);
-      this.___currentMethod = method_call;
-      ___manager.call(method_call);
-    }
-
-    public static class pushMessageAsync_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private Message packet;
-      public pushMessageAsync_call(Message packet, org.apache.thrift.async.AsyncMethodCallback<pushMessageAsync_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
-        super(client, protocolFactory, transport, resultHandler, true);
-        this.packet = packet;
-      }
-
-      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
-        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pushMessageAsync", org.apache.thrift.protocol.TMessageType.CALL, 0));
-        pushMessageAsync_args args = new pushMessageAsync_args();
-        args.setPacket(packet);
-        args.write(prot);
-        prot.writeMessageEnd();
-      }
-
-      public void getResult() throws org.apache.thrift.TException {
-        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
-        }
-        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
-        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
-      }
-    }
-
-    public void terminateSession(String sessionid, org.apache.thrift.async.AsyncMethodCallback<terminateSession_call> resultHandler) throws org.apache.thrift.TException {
-      checkReady();
-      terminateSession_call method_call = new terminateSession_call(sessionid, resultHandler, this, ___protocolFactory, ___transport);
-      this.___currentMethod = method_call;
-      ___manager.call(method_call);
-    }
-
-    public static class terminateSession_call extends org.apache.thrift.async.TAsyncMethodCall {
-      private String sessionid;
-      public terminateSession_call(String sessionid, org.apache.thrift.async.AsyncMethodCallback<terminateSession_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
-        super(client, protocolFactory, transport, resultHandler, false);
-        this.sessionid = sessionid;
-      }
-
-      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
-        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("terminateSession", org.apache.thrift.protocol.TMessageType.CALL, 0));
-        terminateSession_args args = new terminateSession_args();
-        args.setSessionid(sessionid);
-        args.write(prot);
-        prot.writeMessageEnd();
-      }
-
-      public void getResult() throws org.apache.thrift.TException {
-        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
-          throw new IllegalStateException("Method call not finished!");
-        }
-        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
-        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
-        (new Client(prot)).recv_terminateSession();
-      }
-    }
-
-  }
-
-  public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor implements org.apache.thrift.TProcessor {
-    private static final Logger LOGGER = LoggerFactory.getLogger(Processor.class.getName());
-    public Processor(I iface) {
-      super(iface, getProcessMap(new HashMap<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
-    }
-
-    protected Processor(I iface, Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
-      super(iface, getProcessMap(processMap));
-    }
-
-    private static <I extends Iface> Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> getProcessMap(Map<String,  org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
-      processMap.put("getPackets", new getPackets());
-      processMap.put("pushMessageSync", new pushMessageSync());
-      processMap.put("pushMessageAsync", new pushMessageAsync());
-      processMap.put("terminateSession", new terminateSession());
-      return processMap;
-    }
-
-    private static class getPackets<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getPackets_args> {
-      public getPackets() {
-        super("getPackets");
-      }
-
-      protected getPackets_args getEmptyArgsInstance() {
-        return new getPackets_args();
-      }
-
-      protected getPackets_result getResult(I iface, getPackets_args args) throws org.apache.thrift.TException {
-        getPackets_result result = new getPackets_result();
-        result.success = iface.getPackets(args.sessionid);
-        return result;
-      }
-    }
-
-    private static class pushMessageSync<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pushMessageSync_args> {
-      public pushMessageSync() {
-        super("pushMessageSync");
-      }
-
-      protected pushMessageSync_args getEmptyArgsInstance() {
-        return new pushMessageSync_args();
-      }
-
-      protected pushMessageSync_result getResult(I iface, pushMessageSync_args args) throws org.apache.thrift.TException {
-        pushMessageSync_result result = new pushMessageSync_result();
-        result.success = iface.pushMessageSync(args.packet);
-        result.setSuccessIsSet(true);
-        return result;
-      }
-    }
-
-    private static class pushMessageAsync<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pushMessageAsync_args> {
-      public pushMessageAsync() {
-        super("pushMessageAsync");
-      }
-
-      protected pushMessageAsync_args getEmptyArgsInstance() {
-        return new pushMessageAsync_args();
-      }
-
-      protected org.apache.thrift.TBase getResult(I iface, pushMessageAsync_args args) throws org.apache.thrift.TException {
-        iface.pushMessageAsync(args.packet);
-        return null;
-      }
-    }
-
-    private static class terminateSession<I extends Iface> extends org.apache.thrift.ProcessFunction<I, terminateSession_args> {
-      public terminateSession() {
-        super("terminateSession");
-      }
-
-      protected terminateSession_args getEmptyArgsInstance() {
-        return new terminateSession_args();
-      }
-
-      protected terminateSession_result getResult(I iface, terminateSession_args args) throws org.apache.thrift.TException {
-        terminateSession_result result = new terminateSession_result();
-        iface.terminateSession(args.sessionid);
-        return result;
-      }
-    }
-
-  }
-
-  public static class getPackets_args implements org.apache.thrift.TBase<getPackets_args, getPackets_args._Fields>, java.io.Serializable, Cloneable   {
-    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getPackets_args");
-
-    private static final org.apache.thrift.protocol.TField SESSIONID_FIELD_DESC = new org.apache.thrift.protocol.TField("sessionid", org.apache.thrift.protocol.TType.STRING, (short)1);
-
-    public String sessionid; // required
-
-    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-      SESSIONID((short)1, "sessionid");
-
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-      static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
-          byName.put(field.getFieldName(), field);
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, or null if its not found.
-       */
-      public static _Fields findByThriftId(int fieldId) {
-        switch(fieldId) {
-          case 1: // SESSIONID
-            return SESSIONID;
-          default:
-            return null;
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, throwing an exception
-       * if it is not found.
-       */
-      public static _Fields findByThriftIdOrThrow(int fieldId) {
-        _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-        return fields;
-      }
-
-      /**
-       * Find the _Fields constant that matches name, or null if its not found.
-       */
-      public static _Fields findByName(String name) {
-        return byName.get(name);
-      }
-
-      private final short _thriftId;
-      private final String _fieldName;
-
-      _Fields(short thriftId, String fieldName) {
-        _thriftId = thriftId;
-        _fieldName = fieldName;
-      }
-
-      public short getThriftFieldId() {
-        return _thriftId;
-      }
-
-      public String getFieldName() {
-        return _fieldName;
-      }
-    }
-
-    // isset id assignments
-
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-    static {
-      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-      tmpMap.put(_Fields.SESSIONID, new org.apache.thrift.meta_data.FieldMetaData("sessionid", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
-      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getPackets_args.class, metaDataMap);
-    }
-
-    public getPackets_args() {
-    }
-
-    public getPackets_args(
-      String sessionid)
-    {
-      this();
-      this.sessionid = sessionid;
-    }
-
-    /**
-     * Performs a deep copy on <i>other</i>.
-     */
-    public getPackets_args(getPackets_args other) {
-      if (other.isSetSessionid()) {
-        this.sessionid = other.sessionid;
-      }
-    }
-
-    public getPackets_args deepCopy() {
-      return new getPackets_args(this);
-    }
-
-    @Override
-    public void clear() {
-      this.sessionid = null;
-    }
-
-    public String getSessionid() {
-      return this.sessionid;
-    }
-
-    public getPackets_args setSessionid(String sessionid) {
-      this.sessionid = sessionid;
-      return this;
-    }
-
-    public void unsetSessionid() {
-      this.sessionid = null;
-    }
-
-    /** Returns true if field sessionid is set (has been assigned a value) and false otherwise */
-    public boolean isSetSessionid() {
-      return this.sessionid != null;
-    }
-
-    public void setSessionidIsSet(boolean value) {
-      if (!value) {
-        this.sessionid = null;
-      }
-    }
-
-    public void setFieldValue(_Fields field, Object value) {
-      switch (field) {
-      case SESSIONID:
-        if (value == null) {
-          unsetSessionid();
-        } else {
-          setSessionid((String)value);
-        }
-        break;
-
-      }
-    }
-
-    public Object getFieldValue(_Fields field) {
-      switch (field) {
-      case SESSIONID:
-        return getSessionid();
-
-      }
-      throw new IllegalStateException();
-    }
-
-    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-    public boolean isSet(_Fields field) {
-      if (field == null) {
-        throw new IllegalArgumentException();
-      }
-
-      switch (field) {
-      case SESSIONID:
-        return isSetSessionid();
-      }
-      throw new IllegalStateException();
-    }
-
-    @Override
-    public boolean equals(Object that) {
-      if (that == null)
-        return false;
-      if (that instanceof getPackets_args)
-        return this.equals((getPackets_args)that);
-      return false;
-    }
-
-    public boolean equals(getPackets_args that) {
-      if (that == null)
-        return false;
-
-      boolean this_present_sessionid = true && this.isSetSessionid();
-      boolean that_present_sessionid = true && that.isSetSessionid();
-      if (this_present_sessionid || that_present_sessionid) {
-        if (!(this_present_sessionid && that_present_sessionid))
-          return false;
-        if (!this.sessionid.equals(that.sessionid))
-          return false;
-      }
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-
-    public int compareTo(getPackets_args other) {
-      if (!getClass().equals(other.getClass())) {
-        return getClass().getName().compareTo(other.getClass().getName());
-      }
-
-      int lastComparison = 0;
-      getPackets_args typedOther = (getPackets_args)other;
-
-      lastComparison = Boolean.valueOf(isSetSessionid()).compareTo(typedOther.isSetSessionid());
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-      if (isSetSessionid()) {
-        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sessionid, typedOther.sessionid);
-        if (lastComparison != 0) {
-          return lastComparison;
-        }
-      }
-      return 0;
-    }
-
-    public _Fields fieldForId(int fieldId) {
-      return _Fields.findByThriftId(fieldId);
-    }
-
-    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      org.apache.thrift.protocol.TField field;
-      iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-          break;
-        }
-        switch (field.id) {
-          case 1: // SESSIONID
-            if (field.type == org.apache.thrift.protocol.TType.STRING) {
-              this.sessionid = iprot.readString();
-            } else { 
-              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-
-      // check for required fields of primitive type, which can't be checked in the validate method
-      validate();
-    }
-
-    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-      validate();
-
-      oprot.writeStructBegin(STRUCT_DESC);
-      if (this.sessionid != null) {
-        oprot.writeFieldBegin(SESSIONID_FIELD_DESC);
-        oprot.writeString(this.sessionid);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getPackets_args(");
-      boolean first = true;
-
-      sb.append("sessionid:");
-      if (this.sessionid == null) {
-        sb.append("null");
-      } else {
-        sb.append(this.sessionid);
-      }
-      first = false;
-      sb.append(")");
-      return sb.toString();
-    }
-
-    public void validate() throws org.apache.thrift.TException {
-      // check for required fields
-    }
-
-    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-      try {
-        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-      try {
-        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-  }
-
-  public static class getPackets_result implements org.apache.thrift.TBase<getPackets_result, getPackets_result._Fields>, java.io.Serializable, Cloneable   {
-    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getPackets_result");
-
-    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
-
-    public List<ByteBuffer> success; // required
-
-    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-      SUCCESS((short)0, "success");
-
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-      static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
-          byName.put(field.getFieldName(), field);
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, or null if its not found.
-       */
-      public static _Fields findByThriftId(int fieldId) {
-        switch(fieldId) {
-          case 0: // SUCCESS
-            return SUCCESS;
-          default:
-            return null;
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, throwing an exception
-       * if it is not found.
-       */
-      public static _Fields findByThriftIdOrThrow(int fieldId) {
-        _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-        return fields;
-      }
-
-      /**
-       * Find the _Fields constant that matches name, or null if its not found.
-       */
-      public static _Fields findByName(String name) {
-        return byName.get(name);
-      }
-
-      private final short _thriftId;
-      private final String _fieldName;
-
-      _Fields(short thriftId, String fieldName) {
-        _thriftId = thriftId;
-        _fieldName = fieldName;
-      }
-
-      public short getThriftFieldId() {
-        return _thriftId;
-      }
-
-      public String getFieldName() {
-        return _fieldName;
-      }
-    }
-
-    // isset id assignments
-
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-    static {
-      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
-              new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING              , true))));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
-      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getPackets_result.class, metaDataMap);
-    }
-
-    public getPackets_result() {
-    }
-
-    public getPackets_result(
-      List<ByteBuffer> success)
-    {
-      this();
-      this.success = success;
-    }
-
-    /**
-     * Performs a deep copy on <i>other</i>.
-     */
-    public getPackets_result(getPackets_result other) {
-      if (other.isSetSuccess()) {
-        List<ByteBuffer> __this__success = new ArrayList<ByteBuffer>();
-        for (ByteBuffer other_element : other.success) {
-          ByteBuffer temp_binary_element = org.apache.thrift.TBaseHelper.copyBinary(other_element);
-;
-          __this__success.add(temp_binary_element);
-        }
-        this.success = __this__success;
-      }
-    }
-
-    public getPackets_result deepCopy() {
-      return new getPackets_result(this);
-    }
-
-    @Override
-    public void clear() {
-      this.success = null;
-    }
-
-    public int getSuccessSize() {
-      return (this.success == null) ? 0 : this.success.size();
-    }
-
-    public java.util.Iterator<ByteBuffer> getSuccessIterator() {
-      return (this.success == null) ? null : this.success.iterator();
-    }
-
-    public void addToSuccess(ByteBuffer elem) {
-      if (this.success == null) {
-        this.success = new ArrayList<ByteBuffer>();
-      }
-      this.success.add(elem);
-    }
-
-    public List<ByteBuffer> getSuccess() {
-      return this.success;
-    }
-
-    public getPackets_result setSuccess(List<ByteBuffer> success) {
-      this.success = success;
-      return this;
-    }
-
-    public void unsetSuccess() {
-      this.success = null;
-    }
-
-    /** Returns true if field success is set (has been assigned a value) and false otherwise */
-    public boolean isSetSuccess() {
-      return this.success != null;
-    }
-
-    public void setSuccessIsSet(boolean value) {
-      if (!value) {
-        this.success = null;
-      }
-    }
-
-    public void setFieldValue(_Fields field, Object value) {
-      switch (field) {
-      case SUCCESS:
-        if (value == null) {
-          unsetSuccess();
-        } else {
-          setSuccess((List<ByteBuffer>)value);
-        }
-        break;
-
-      }
-    }
-
-    public Object getFieldValue(_Fields field) {
-      switch (field) {
-      case SUCCESS:
-        return getSuccess();
-
-      }
-      throw new IllegalStateException();
-    }
-
-    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-    public boolean isSet(_Fields field) {
-      if (field == null) {
-        throw new IllegalArgumentException();
-      }
-
-      switch (field) {
-      case SUCCESS:
-        return isSetSuccess();
-      }
-      throw new IllegalStateException();
-    }
-
-    @Override
-    public boolean equals(Object that) {
-      if (that == null)
-        return false;
-      if (that instanceof getPackets_result)
-        return this.equals((getPackets_result)that);
-      return false;
-    }
-
-    public boolean equals(getPackets_result that) {
-      if (that == null)
-        return false;
-
-      boolean this_present_success = true && this.isSetSuccess();
-      boolean that_present_success = true && that.isSetSuccess();
-      if (this_present_success || that_present_success) {
-        if (!(this_present_success && that_present_success))
-          return false;
-        if (!this.success.equals(that.success))
-          return false;
-      }
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-
-    public int compareTo(getPackets_result other) {
-      if (!getClass().equals(other.getClass())) {
-        return getClass().getName().compareTo(other.getClass().getName());
-      }
-
-      int lastComparison = 0;
-      getPackets_result typedOther = (getPackets_result)other;
-
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-      if (isSetSuccess()) {
-        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
-        if (lastComparison != 0) {
-          return lastComparison;
-        }
-      }
-      return 0;
-    }
-
-    public _Fields fieldForId(int fieldId) {
-      return _Fields.findByThriftId(fieldId);
-    }
-
-    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      org.apache.thrift.protocol.TField field;
-      iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-          break;
-        }
-        switch (field.id) {
-          case 0: // SUCCESS
-            if (field.type == org.apache.thrift.protocol.TType.LIST) {
-              {
-                org.apache.thrift.protocol.TList _list4 = iprot.readListBegin();
-                this.success = new ArrayList<ByteBuffer>(_list4.size);
-                for (int _i5 = 0; _i5 < _list4.size; ++_i5)
-                {
-                  ByteBuffer _elem6; // required
-                  _elem6 = iprot.readBinary();
-                  this.success.add(_elem6);
-                }
-                iprot.readListEnd();
-              }
-            } else { 
-              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-
-      // check for required fields of primitive type, which can't be checked in the validate method
-      validate();
-    }
-
-    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-      oprot.writeStructBegin(STRUCT_DESC);
-
-      if (this.isSetSuccess()) {
-        oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
-        {
-          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, this.success.size()));
-          for (ByteBuffer _iter7 : this.success)
-          {
-            oprot.writeBinary(_iter7);
-          }
-          oprot.writeListEnd();
-        }
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("getPackets_result(");
-      boolean first = true;
-
-      sb.append("success:");
-      if (this.success == null) {
-        sb.append("null");
-      } else {
-        sb.append(this.success);
-      }
-      first = false;
-      sb.append(")");
-      return sb.toString();
-    }
-
-    public void validate() throws org.apache.thrift.TException {
-      // check for required fields
-    }
-
-    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-      try {
-        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-      try {
-        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-  }
-
-  public static class pushMessageSync_args implements org.apache.thrift.TBase<pushMessageSync_args, pushMessageSync_args._Fields>, java.io.Serializable, Cloneable   {
-    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pushMessageSync_args");
-
-    private static final org.apache.thrift.protocol.TField PACKET_FIELD_DESC = new org.apache.thrift.protocol.TField("packet", org.apache.thrift.protocol.TType.STRUCT, (short)1);
-
-    public Message packet; // required
-
-    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-      PACKET((short)1, "packet");
-
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-      static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
-          byName.put(field.getFieldName(), field);
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, or null if its not found.
-       */
-      public static _Fields findByThriftId(int fieldId) {
-        switch(fieldId) {
-          case 1: // PACKET
-            return PACKET;
-          default:
-            return null;
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, throwing an exception
-       * if it is not found.
-       */
-      public static _Fields findByThriftIdOrThrow(int fieldId) {
-        _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-        return fields;
-      }
-
-      /**
-       * Find the _Fields constant that matches name, or null if its not found.
-       */
-      public static _Fields findByName(String name) {
-        return byName.get(name);
-      }
-
-      private final short _thriftId;
-      private final String _fieldName;
-
-      _Fields(short thriftId, String fieldName) {
-        _thriftId = thriftId;
-        _fieldName = fieldName;
-      }
-
-      public short getThriftFieldId() {
-        return _thriftId;
-      }
-
-      public String getFieldName() {
-        return _fieldName;
-      }
-    }
-
-    // isset id assignments
-
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-    static {
-      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-      tmpMap.put(_Fields.PACKET, new org.apache.thrift.meta_data.FieldMetaData("packet", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Message.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
-      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pushMessageSync_args.class, metaDataMap);
-    }
-
-    public pushMessageSync_args() {
-    }
-
-    public pushMessageSync_args(
-      Message packet)
-    {
-      this();
-      this.packet = packet;
-    }
-
-    /**
-     * Performs a deep copy on <i>other</i>.
-     */
-    public pushMessageSync_args(pushMessageSync_args other) {
-      if (other.isSetPacket()) {
-        this.packet = new Message(other.packet);
-      }
-    }
-
-    public pushMessageSync_args deepCopy() {
-      return new pushMessageSync_args(this);
-    }
-
-    @Override
-    public void clear() {
-      this.packet = null;
-    }
-
-    public Message getPacket() {
-      return this.packet;
-    }
-
-    public pushMessageSync_args setPacket(Message packet) {
-      this.packet = packet;
-      return this;
-    }
-
-    public void unsetPacket() {
-      this.packet = null;
-    }
-
-    /** Returns true if field packet is set (has been assigned a value) and false otherwise */
-    public boolean isSetPacket() {
-      return this.packet != null;
-    }
-
-    public void setPacketIsSet(boolean value) {
-      if (!value) {
-        this.packet = null;
-      }
-    }
-
-    public void setFieldValue(_Fields field, Object value) {
-      switch (field) {
-      case PACKET:
-        if (value == null) {
-          unsetPacket();
-        } else {
-          setPacket((Message)value);
-        }
-        break;
-
-      }
-    }
-
-    public Object getFieldValue(_Fields field) {
-      switch (field) {
-      case PACKET:
-        return getPacket();
-
-      }
-      throw new IllegalStateException();
-    }
-
-    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-    public boolean isSet(_Fields field) {
-      if (field == null) {
-        throw new IllegalArgumentException();
-      }
-
-      switch (field) {
-      case PACKET:
-        return isSetPacket();
-      }
-      throw new IllegalStateException();
-    }
-
-    @Override
-    public boolean equals(Object that) {
-      if (that == null)
-        return false;
-      if (that instanceof pushMessageSync_args)
-        return this.equals((pushMessageSync_args)that);
-      return false;
-    }
-
-    public boolean equals(pushMessageSync_args that) {
-      if (that == null)
-        return false;
-
-      boolean this_present_packet = true && this.isSetPacket();
-      boolean that_present_packet = true && that.isSetPacket();
-      if (this_present_packet || that_present_packet) {
-        if (!(this_present_packet && that_present_packet))
-          return false;
-        if (!this.packet.equals(that.packet))
-          return false;
-      }
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-
-    public int compareTo(pushMessageSync_args other) {
-      if (!getClass().equals(other.getClass())) {
-        return getClass().getName().compareTo(other.getClass().getName());
-      }
-
-      int lastComparison = 0;
-      pushMessageSync_args typedOther = (pushMessageSync_args)other;
-
-      lastComparison = Boolean.valueOf(isSetPacket()).compareTo(typedOther.isSetPacket());
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-      if (isSetPacket()) {
-        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.packet, typedOther.packet);
-        if (lastComparison != 0) {
-          return lastComparison;
-        }
-      }
-      return 0;
-    }
-
-    public _Fields fieldForId(int fieldId) {
-      return _Fields.findByThriftId(fieldId);
-    }
-
-    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      org.apache.thrift.protocol.TField field;
-      iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-          break;
-        }
-        switch (field.id) {
-          case 1: // PACKET
-            if (field.type == org.apache.thrift.protocol.TType.STRUCT) {
-              this.packet = new Message();
-              this.packet.read(iprot);
-            } else { 
-              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-
-      // check for required fields of primitive type, which can't be checked in the validate method
-      validate();
-    }
-
-    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-      validate();
-
-      oprot.writeStructBegin(STRUCT_DESC);
-      if (this.packet != null) {
-        oprot.writeFieldBegin(PACKET_FIELD_DESC);
-        this.packet.write(oprot);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("pushMessageSync_args(");
-      boolean first = true;
-
-      sb.append("packet:");
-      if (this.packet == null) {
-        sb.append("null");
-      } else {
-        sb.append(this.packet);
-      }
-      first = false;
-      sb.append(")");
-      return sb.toString();
-    }
-
-    public void validate() throws org.apache.thrift.TException {
-      // check for required fields
-    }
-
-    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-      try {
-        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-      try {
-        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-  }
-
-  public static class pushMessageSync_result implements org.apache.thrift.TBase<pushMessageSync_result, pushMessageSync_result._Fields>, java.io.Serializable, Cloneable   {
-    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pushMessageSync_result");
-
-    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.I32, (short)0);
-
-    public int success; // required
-
-    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-      SUCCESS((short)0, "success");
-
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-      static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
-          byName.put(field.getFieldName(), field);
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, or null if its not found.
-       */
-      public static _Fields findByThriftId(int fieldId) {
-        switch(fieldId) {
-          case 0: // SUCCESS
-            return SUCCESS;
-          default:
-            return null;
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, throwing an exception
-       * if it is not found.
-       */
-      public static _Fields findByThriftIdOrThrow(int fieldId) {
-        _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-        return fields;
-      }
-
-      /**
-       * Find the _Fields constant that matches name, or null if its not found.
-       */
-      public static _Fields findByName(String name) {
-        return byName.get(name);
-      }
-
-      private final short _thriftId;
-      private final String _fieldName;
-
-      _Fields(short thriftId, String fieldName) {
-        _thriftId = thriftId;
-        _fieldName = fieldName;
-      }
-
-      public short getThriftFieldId() {
-        return _thriftId;
-      }
-
-      public String getFieldName() {
-        return _fieldName;
-      }
-    }
-
-    // isset id assignments
-    private static final int __SUCCESS_ISSET_ID = 0;
-    private BitSet __isset_bit_vector = new BitSet(1);
-
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-    static {
-      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
-      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pushMessageSync_result.class, metaDataMap);
-    }
-
-    public pushMessageSync_result() {
-    }
-
-    public pushMessageSync_result(
-      int success)
-    {
-      this();
-      this.success = success;
-      setSuccessIsSet(true);
-    }
-
-    /**
-     * Performs a deep copy on <i>other</i>.
-     */
-    public pushMessageSync_result(pushMessageSync_result other) {
-      __isset_bit_vector.clear();
-      __isset_bit_vector.or(other.__isset_bit_vector);
-      this.success = other.success;
-    }
-
-    public pushMessageSync_result deepCopy() {
-      return new pushMessageSync_result(this);
-    }
-
-    @Override
-    public void clear() {
-      setSuccessIsSet(false);
-      this.success = 0;
-    }
-
-    public int getSuccess() {
-      return this.success;
-    }
-
-    public pushMessageSync_result setSuccess(int success) {
-      this.success = success;
-      setSuccessIsSet(true);
-      return this;
-    }
-
-    public void unsetSuccess() {
-      __isset_bit_vector.clear(__SUCCESS_ISSET_ID);
-    }
-
-    /** Returns true if field success is set (has been assigned a value) and false otherwise */
-    public boolean isSetSuccess() {
-      return __isset_bit_vector.get(__SUCCESS_ISSET_ID);
-    }
-
-    public void setSuccessIsSet(boolean value) {
-      __isset_bit_vector.set(__SUCCESS_ISSET_ID, value);
-    }
-
-    public void setFieldValue(_Fields field, Object value) {
-      switch (field) {
-      case SUCCESS:
-        if (value == null) {
-          unsetSuccess();
-        } else {
-          setSuccess((Integer)value);
-        }
-        break;
-
-      }
-    }
-
-    public Object getFieldValue(_Fields field) {
-      switch (field) {
-      case SUCCESS:
-        return Integer.valueOf(getSuccess());
-
-      }
-      throw new IllegalStateException();
-    }
-
-    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-    public boolean isSet(_Fields field) {
-      if (field == null) {
-        throw new IllegalArgumentException();
-      }
-
-      switch (field) {
-      case SUCCESS:
-        return isSetSuccess();
-      }
-      throw new IllegalStateException();
-    }
-
-    @Override
-    public boolean equals(Object that) {
-      if (that == null)
-        return false;
-      if (that instanceof pushMessageSync_result)
-        return this.equals((pushMessageSync_result)that);
-      return false;
-    }
-
-    public boolean equals(pushMessageSync_result that) {
-      if (that == null)
-        return false;
-
-      boolean this_present_success = true;
-      boolean that_present_success = true;
-      if (this_present_success || that_present_success) {
-        if (!(this_present_success && that_present_success))
-          return false;
-        if (this.success != that.success)
-          return false;
-      }
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-
-    public int compareTo(pushMessageSync_result other) {
-      if (!getClass().equals(other.getClass())) {
-        return getClass().getName().compareTo(other.getClass().getName());
-      }
-
-      int lastComparison = 0;
-      pushMessageSync_result typedOther = (pushMessageSync_result)other;
-
-      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-      if (isSetSuccess()) {
-        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
-        if (lastComparison != 0) {
-          return lastComparison;
-        }
-      }
-      return 0;
-    }
-
-    public _Fields fieldForId(int fieldId) {
-      return _Fields.findByThriftId(fieldId);
-    }
-
-    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      org.apache.thrift.protocol.TField field;
-      iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-          break;
-        }
-        switch (field.id) {
-          case 0: // SUCCESS
-            if (field.type == org.apache.thrift.protocol.TType.I32) {
-              this.success = iprot.readI32();
-              setSuccessIsSet(true);
-            } else { 
-              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-
-      // check for required fields of primitive type, which can't be checked in the validate method
-      validate();
-    }
-
-    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-      oprot.writeStructBegin(STRUCT_DESC);
-
-      if (this.isSetSuccess()) {
-        oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
-        oprot.writeI32(this.success);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("pushMessageSync_result(");
-      boolean first = true;
-
-      sb.append("success:");
-      sb.append(this.success);
-      first = false;
-      sb.append(")");
-      return sb.toString();
-    }
-
-    public void validate() throws org.apache.thrift.TException {
-      // check for required fields
-    }
-
-    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-      try {
-        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-      try {
-        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
-        __isset_bit_vector = new BitSet(1);
-        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-  }
-
-  public static class pushMessageAsync_args implements org.apache.thrift.TBase<pushMessageAsync_args, pushMessageAsync_args._Fields>, java.io.Serializable, Cloneable   {
-    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pushMessageAsync_args");
-
-    private static final org.apache.thrift.protocol.TField PACKET_FIELD_DESC = new org.apache.thrift.protocol.TField("packet", org.apache.thrift.protocol.TType.STRUCT, (short)1);
-
-    public Message packet; // required
-
-    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-      PACKET((short)1, "packet");
-
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-      static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
-          byName.put(field.getFieldName(), field);
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, or null if its not found.
-       */
-      public static _Fields findByThriftId(int fieldId) {
-        switch(fieldId) {
-          case 1: // PACKET
-            return PACKET;
-          default:
-            return null;
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, throwing an exception
-       * if it is not found.
-       */
-      public static _Fields findByThriftIdOrThrow(int fieldId) {
-        _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-        return fields;
-      }
-
-      /**
-       * Find the _Fields constant that matches name, or null if its not found.
-       */
-      public static _Fields findByName(String name) {
-        return byName.get(name);
-      }
-
-      private final short _thriftId;
-      private final String _fieldName;
-
-      _Fields(short thriftId, String fieldName) {
-        _thriftId = thriftId;
-        _fieldName = fieldName;
-      }
-
-      public short getThriftFieldId() {
-        return _thriftId;
-      }
-
-      public String getFieldName() {
-        return _fieldName;
-      }
-    }
-
-    // isset id assignments
-
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-    static {
-      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-      tmpMap.put(_Fields.PACKET, new org.apache.thrift.meta_data.FieldMetaData("packet", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, Message.class)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
-      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pushMessageAsync_args.class, metaDataMap);
-    }
-
-    public pushMessageAsync_args() {
-    }
-
-    public pushMessageAsync_args(
-      Message packet)
-    {
-      this();
-      this.packet = packet;
-    }
-
-    /**
-     * Performs a deep copy on <i>other</i>.
-     */
-    public pushMessageAsync_args(pushMessageAsync_args other) {
-      if (other.isSetPacket()) {
-        this.packet = new Message(other.packet);
-      }
-    }
-
-    public pushMessageAsync_args deepCopy() {
-      return new pushMessageAsync_args(this);
-    }
-
-    @Override
-    public void clear() {
-      this.packet = null;
-    }
-
-    public Message getPacket() {
-      return this.packet;
-    }
-
-    public pushMessageAsync_args setPacket(Message packet) {
-      this.packet = packet;
-      return this;
-    }
-
-    public void unsetPacket() {
-      this.packet = null;
-    }
-
-    /** Returns true if field packet is set (has been assigned a value) and false otherwise */
-    public boolean isSetPacket() {
-      return this.packet != null;
-    }
-
-    public void setPacketIsSet(boolean value) {
-      if (!value) {
-        this.packet = null;
-      }
-    }
-
-    public void setFieldValue(_Fields field, Object value) {
-      switch (field) {
-      case PACKET:
-        if (value == null) {
-          unsetPacket();
-        } else {
-          setPacket((Message)value);
-        }
-        break;
-
-      }
-    }
-
-    public Object getFieldValue(_Fields field) {
-      switch (field) {
-      case PACKET:
-        return getPacket();
-
-      }
-      throw new IllegalStateException();
-    }
-
-    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-    public boolean isSet(_Fields field) {
-      if (field == null) {
-        throw new IllegalArgumentException();
-      }
-
-      switch (field) {
-      case PACKET:
-        return isSetPacket();
-      }
-      throw new IllegalStateException();
-    }
-
-    @Override
-    public boolean equals(Object that) {
-      if (that == null)
-        return false;
-      if (that instanceof pushMessageAsync_args)
-        return this.equals((pushMessageAsync_args)that);
-      return false;
-    }
-
-    public boolean equals(pushMessageAsync_args that) {
-      if (that == null)
-        return false;
-
-      boolean this_present_packet = true && this.isSetPacket();
-      boolean that_present_packet = true && that.isSetPacket();
-      if (this_present_packet || that_present_packet) {
-        if (!(this_present_packet && that_present_packet))
-          return false;
-        if (!this.packet.equals(that.packet))
-          return false;
-      }
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-
-    public int compareTo(pushMessageAsync_args other) {
-      if (!getClass().equals(other.getClass())) {
-        return getClass().getName().compareTo(other.getClass().getName());
-      }
-
-      int lastComparison = 0;
-      pushMessageAsync_args typedOther = (pushMessageAsync_args)other;
-
-      lastComparison = Boolean.valueOf(isSetPacket()).compareTo(typedOther.isSetPacket());
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-      if (isSetPacket()) {
-        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.packet, typedOther.packet);
-        if (lastComparison != 0) {
-          return lastComparison;
-        }
-      }
-      return 0;
-    }
-
-    public _Fields fieldForId(int fieldId) {
-      return _Fields.findByThriftId(fieldId);
-    }
-
-    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      org.apache.thrift.protocol.TField field;
-      iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-          break;
-        }
-        switch (field.id) {
-          case 1: // PACKET
-            if (field.type == org.apache.thrift.protocol.TType.STRUCT) {
-              this.packet = new Message();
-              this.packet.read(iprot);
-            } else { 
-              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-
-      // check for required fields of primitive type, which can't be checked in the validate method
-      validate();
-    }
-
-    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-      validate();
-
-      oprot.writeStructBegin(STRUCT_DESC);
-      if (this.packet != null) {
-        oprot.writeFieldBegin(PACKET_FIELD_DESC);
-        this.packet.write(oprot);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("pushMessageAsync_args(");
-      boolean first = true;
-
-      sb.append("packet:");
-      if (this.packet == null) {
-        sb.append("null");
-      } else {
-        sb.append(this.packet);
-      }
-      first = false;
-      sb.append(")");
-      return sb.toString();
-    }
-
-    public void validate() throws org.apache.thrift.TException {
-      // check for required fields
-    }
-
-    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-      try {
-        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-      try {
-        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-  }
-
-  public static class terminateSession_args implements org.apache.thrift.TBase<terminateSession_args, terminateSession_args._Fields>, java.io.Serializable, Cloneable   {
-    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("terminateSession_args");
-
-    private static final org.apache.thrift.protocol.TField SESSIONID_FIELD_DESC = new org.apache.thrift.protocol.TField("sessionid", org.apache.thrift.protocol.TType.STRING, (short)1);
-
-    public String sessionid; // required
-
-    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-      SESSIONID((short)1, "sessionid");
-
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-      static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
-          byName.put(field.getFieldName(), field);
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, or null if its not found.
-       */
-      public static _Fields findByThriftId(int fieldId) {
-        switch(fieldId) {
-          case 1: // SESSIONID
-            return SESSIONID;
-          default:
-            return null;
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, throwing an exception
-       * if it is not found.
-       */
-      public static _Fields findByThriftIdOrThrow(int fieldId) {
-        _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-        return fields;
-      }
-
-      /**
-       * Find the _Fields constant that matches name, or null if its not found.
-       */
-      public static _Fields findByName(String name) {
-        return byName.get(name);
-      }
-
-      private final short _thriftId;
-      private final String _fieldName;
-
-      _Fields(short thriftId, String fieldName) {
-        _thriftId = thriftId;
-        _fieldName = fieldName;
-      }
-
-      public short getThriftFieldId() {
-        return _thriftId;
-      }
-
-      public String getFieldName() {
-        return _fieldName;
-      }
-    }
-
-    // isset id assignments
-
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-    static {
-      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-      tmpMap.put(_Fields.SESSIONID, new org.apache.thrift.meta_data.FieldMetaData("sessionid", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
-      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(terminateSession_args.class, metaDataMap);
-    }
-
-    public terminateSession_args() {
-    }
-
-    public terminateSession_args(
-      String sessionid)
-    {
-      this();
-      this.sessionid = sessionid;
-    }
-
-    /**
-     * Performs a deep copy on <i>other</i>.
-     */
-    public terminateSession_args(terminateSession_args other) {
-      if (other.isSetSessionid()) {
-        this.sessionid = other.sessionid;
-      }
-    }
-
-    public terminateSession_args deepCopy() {
-      return new terminateSession_args(this);
-    }
-
-    @Override
-    public void clear() {
-      this.sessionid = null;
-    }
-
-    public String getSessionid() {
-      return this.sessionid;
-    }
-
-    public terminateSession_args setSessionid(String sessionid) {
-      this.sessionid = sessionid;
-      return this;
-    }
-
-    public void unsetSessionid() {
-      this.sessionid = null;
-    }
-
-    /** Returns true if field sessionid is set (has been assigned a value) and false otherwise */
-    public boolean isSetSessionid() {
-      return this.sessionid != null;
-    }
-
-    public void setSessionidIsSet(boolean value) {
-      if (!value) {
-        this.sessionid = null;
-      }
-    }
-
-    public void setFieldValue(_Fields field, Object value) {
-      switch (field) {
-      case SESSIONID:
-        if (value == null) {
-          unsetSessionid();
-        } else {
-          setSessionid((String)value);
-        }
-        break;
-
-      }
-    }
-
-    public Object getFieldValue(_Fields field) {
-      switch (field) {
-      case SESSIONID:
-        return getSessionid();
-
-      }
-      throw new IllegalStateException();
-    }
-
-    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-    public boolean isSet(_Fields field) {
-      if (field == null) {
-        throw new IllegalArgumentException();
-      }
-
-      switch (field) {
-      case SESSIONID:
-        return isSetSessionid();
-      }
-      throw new IllegalStateException();
-    }
-
-    @Override
-    public boolean equals(Object that) {
-      if (that == null)
-        return false;
-      if (that instanceof terminateSession_args)
-        return this.equals((terminateSession_args)that);
-      return false;
-    }
-
-    public boolean equals(terminateSession_args that) {
-      if (that == null)
-        return false;
-
-      boolean this_present_sessionid = true && this.isSetSessionid();
-      boolean that_present_sessionid = true && that.isSetSessionid();
-      if (this_present_sessionid || that_present_sessionid) {
-        if (!(this_present_sessionid && that_present_sessionid))
-          return false;
-        if (!this.sessionid.equals(that.sessionid))
-          return false;
-      }
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-
-    public int compareTo(terminateSession_args other) {
-      if (!getClass().equals(other.getClass())) {
-        return getClass().getName().compareTo(other.getClass().getName());
-      }
-
-      int lastComparison = 0;
-      terminateSession_args typedOther = (terminateSession_args)other;
-
-      lastComparison = Boolean.valueOf(isSetSessionid()).compareTo(typedOther.isSetSessionid());
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-      if (isSetSessionid()) {
-        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sessionid, typedOther.sessionid);
-        if (lastComparison != 0) {
-          return lastComparison;
-        }
-      }
-      return 0;
-    }
-
-    public _Fields fieldForId(int fieldId) {
-      return _Fields.findByThriftId(fieldId);
-    }
-
-    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      org.apache.thrift.protocol.TField field;
-      iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-          break;
-        }
-        switch (field.id) {
-          case 1: // SESSIONID
-            if (field.type == org.apache.thrift.protocol.TType.STRING) {
-              this.sessionid = iprot.readString();
-            } else { 
-              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-            }
-            break;
-          default:
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-
-      // check for required fields of primitive type, which can't be checked in the validate method
-      validate();
-    }
-
-    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-      validate();
-
-      oprot.writeStructBegin(STRUCT_DESC);
-      if (this.sessionid != null) {
-        oprot.writeFieldBegin(SESSIONID_FIELD_DESC);
-        oprot.writeString(this.sessionid);
-        oprot.writeFieldEnd();
-      }
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("terminateSession_args(");
-      boolean first = true;
-
-      sb.append("sessionid:");
-      if (this.sessionid == null) {
-        sb.append("null");
-      } else {
-        sb.append(this.sessionid);
-      }
-      first = false;
-      sb.append(")");
-      return sb.toString();
-    }
-
-    public void validate() throws org.apache.thrift.TException {
-      // check for required fields
-    }
-
-    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-      try {
-        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-      try {
-        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-  }
-
-  public static class terminateSession_result implements org.apache.thrift.TBase<terminateSession_result, terminateSession_result._Fields>, java.io.Serializable, Cloneable   {
-    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("terminateSession_result");
-
-
-
-    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-;
-
-      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-      static {
-        for (_Fields field : EnumSet.allOf(_Fields.class)) {
-          byName.put(field.getFieldName(), field);
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, or null if its not found.
-       */
-      public static _Fields findByThriftId(int fieldId) {
-        switch(fieldId) {
-          default:
-            return null;
-        }
-      }
-
-      /**
-       * Find the _Fields constant that matches fieldId, throwing an exception
-       * if it is not found.
-       */
-      public static _Fields findByThriftIdOrThrow(int fieldId) {
-        _Fields fields = findByThriftId(fieldId);
-        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-        return fields;
-      }
-
-      /**
-       * Find the _Fields constant that matches name, or null if its not found.
-       */
-      public static _Fields findByName(String name) {
-        return byName.get(name);
-      }
-
-      private final short _thriftId;
-      private final String _fieldName;
-
-      _Fields(short thriftId, String fieldName) {
-        _thriftId = thriftId;
-        _fieldName = fieldName;
-      }
-
-      public short getThriftFieldId() {
-        return _thriftId;
-      }
-
-      public String getFieldName() {
-        return _fieldName;
-      }
-    }
-    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-    static {
-      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-      metaDataMap = Collections.unmodifiableMap(tmpMap);
-      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(terminateSession_result.class, metaDataMap);
-    }
-
-    public terminateSession_result() {
-    }
-
-    /**
-     * Performs a deep copy on <i>other</i>.
-     */
-    public terminateSession_result(terminateSession_result other) {
-    }
-
-    public terminateSession_result deepCopy() {
-      return new terminateSession_result(this);
-    }
-
-    @Override
-    public void clear() {
-    }
-
-    public void setFieldValue(_Fields field, Object value) {
-      switch (field) {
-      }
-    }
-
-    public Object getFieldValue(_Fields field) {
-      switch (field) {
-      }
-      throw new IllegalStateException();
-    }
-
-    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-    public boolean isSet(_Fields field) {
-      if (field == null) {
-        throw new IllegalArgumentException();
-      }
-
-      switch (field) {
-      }
-      throw new IllegalStateException();
-    }
-
-    @Override
-    public boolean equals(Object that) {
-      if (that == null)
-        return false;
-      if (that instanceof terminateSession_result)
-        return this.equals((terminateSession_result)that);
-      return false;
-    }
-
-    public boolean equals(terminateSession_result that) {
-      if (that == null)
-        return false;
-
-      return true;
-    }
-
-    @Override
-    public int hashCode() {
-      return 0;
-    }
-
-    public int compareTo(terminateSession_result other) {
-      if (!getClass().equals(other.getClass())) {
-        return getClass().getName().compareTo(other.getClass().getName());
-      }
-
-      int lastComparison = 0;
-      terminateSession_result typedOther = (terminateSession_result)other;
-
-      return 0;
-    }
-
-    public _Fields fieldForId(int fieldId) {
-      return _Fields.findByThriftId(fieldId);
-    }
-
-    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-      org.apache.thrift.protocol.TField field;
-      iprot.readStructBegin();
-      while (true)
-      {
-        field = iprot.readFieldBegin();
-        if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-          break;
-        }
-        switch (field.id) {
-          default:
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-        }
-        iprot.readFieldEnd();
-      }
-      iprot.readStructEnd();
-
-      // check for required fields of primitive type, which can't be checked in the validate method
-      validate();
-    }
-
-    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-      oprot.writeStructBegin(STRUCT_DESC);
-
-      oprot.writeFieldStop();
-      oprot.writeStructEnd();
-    }
-
-    @Override
-    public String toString() {
-      StringBuilder sb = new StringBuilder("terminateSession_result(");
-      boolean first = true;
-
-      sb.append(")");
-      return sb.toString();
-    }
-
-    public void validate() throws org.apache.thrift.TException {
-      // check for required fields
-    }
-
-    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-      try {
-        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-      try {
-        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-      } catch (org.apache.thrift.TException te) {
-        throw new java.io.IOException(te);
-      }
-    }
-
-  }
-
-}
diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/SwitchPortTuple.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/SwitchPortTuple.java
deleted file mode 100644
index 8fe8191..0000000
--- a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/SwitchPortTuple.java
+++ /dev/null
@@ -1,406 +0,0 @@
-/**
- * Autogenerated by Thrift Compiler (0.7.0)
- *
- * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
- */
-package net.floodlightcontroller.packetstreamer.thrift;
-
-import java.util.List;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.EnumMap;
-import java.util.Set;
-import java.util.HashSet;
-import java.util.EnumSet;
-import java.util.Collections;
-import java.util.BitSet;
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * A struct that defines switch port tuple
- */
-@SuppressWarnings("all") public class SwitchPortTuple implements org.apache.thrift.TBase<SwitchPortTuple, SwitchPortTuple._Fields>, java.io.Serializable, Cloneable {
-  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("SwitchPortTuple");
-
-  private static final org.apache.thrift.protocol.TField DPID_FIELD_DESC = new org.apache.thrift.protocol.TField("dpid", org.apache.thrift.protocol.TType.I64, (short)1);
-  private static final org.apache.thrift.protocol.TField PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("port", org.apache.thrift.protocol.TType.I16, (short)2);
-
-  public long dpid; // required
-  public short port; // required
-
-  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
-  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
-    DPID((short)1, "dpid"),
-    PORT((short)2, "port");
-
-    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
-
-    static {
-      for (_Fields field : EnumSet.allOf(_Fields.class)) {
-        byName.put(field.getFieldName(), field);
-      }
-    }
-
-    /**
-     * Find the _Fields constant that matches fieldId, or null if its not found.
-     */
-    public static _Fields findByThriftId(int fieldId) {
-      switch(fieldId) {
-        case 1: // DPID
-          return DPID;
-        case 2: // PORT
-          return PORT;
-        default:
-          return null;
-      }
-    }
-
-    /**
-     * Find the _Fields constant that matches fieldId, throwing an exception
-     * if it is not found.
-     */
-    public static _Fields findByThriftIdOrThrow(int fieldId) {
-      _Fields fields = findByThriftId(fieldId);
-      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
-      return fields;
-    }
-
-    /**
-     * Find the _Fields constant that matches name, or null if its not found.
-     */
-    public static _Fields findByName(String name) {
-      return byName.get(name);
-    }
-
-    private final short _thriftId;
-    private final String _fieldName;
-
-    _Fields(short thriftId, String fieldName) {
-      _thriftId = thriftId;
-      _fieldName = fieldName;
-    }
-
-    public short getThriftFieldId() {
-      return _thriftId;
-    }
-
-    public String getFieldName() {
-      return _fieldName;
-    }
-  }
-
-  // isset id assignments
-  private static final int __DPID_ISSET_ID = 0;
-  private static final int __PORT_ISSET_ID = 1;
-  private BitSet __isset_bit_vector = new BitSet(2);
-
-  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
-  static {
-    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
-    tmpMap.put(_Fields.DPID, new org.apache.thrift.meta_data.FieldMetaData("dpid", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
-    tmpMap.put(_Fields.PORT, new org.apache.thrift.meta_data.FieldMetaData("port", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I16)));
-    metaDataMap = Collections.unmodifiableMap(tmpMap);
-    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(SwitchPortTuple.class, metaDataMap);
-  }
-
-  public SwitchPortTuple() {
-  }
-
-  public SwitchPortTuple(
-    long dpid,
-    short port)
-  {
-    this();
-    this.dpid = dpid;
-    setDpidIsSet(true);
-    this.port = port;
-    setPortIsSet(true);
-  }
-
-  /**
-   * Performs a deep copy on <i>other</i>.
-   */
-  public SwitchPortTuple(SwitchPortTuple other) {
-    __isset_bit_vector.clear();
-    __isset_bit_vector.or(other.__isset_bit_vector);
-    this.dpid = other.dpid;
-    this.port = other.port;
-  }
-
-  public SwitchPortTuple deepCopy() {
-    return new SwitchPortTuple(this);
-  }
-
-  @Override
-  public void clear() {
-    setDpidIsSet(false);
-    this.dpid = 0;
-    setPortIsSet(false);
-    this.port = 0;
-  }
-
-  public long getDpid() {
-    return this.dpid;
-  }
-
-  public SwitchPortTuple setDpid(long dpid) {
-    this.dpid = dpid;
-    setDpidIsSet(true);
-    return this;
-  }
-
-  public void unsetDpid() {
-    __isset_bit_vector.clear(__DPID_ISSET_ID);
-  }
-
-  /** Returns true if field dpid is set (has been assigned a value) and false otherwise */
-  public boolean isSetDpid() {
-    return __isset_bit_vector.get(__DPID_ISSET_ID);
-  }
-
-  public void setDpidIsSet(boolean value) {
-    __isset_bit_vector.set(__DPID_ISSET_ID, value);
-  }
-
-  public short getPort() {
-    return this.port;
-  }
-
-  public SwitchPortTuple setPort(short port) {
-    this.port = port;
-    setPortIsSet(true);
-    return this;
-  }
-
-  public void unsetPort() {
-    __isset_bit_vector.clear(__PORT_ISSET_ID);
-  }
-
-  /** Returns true if field port is set (has been assigned a value) and false otherwise */
-  public boolean isSetPort() {
-    return __isset_bit_vector.get(__PORT_ISSET_ID);
-  }
-
-  public void setPortIsSet(boolean value) {
-    __isset_bit_vector.set(__PORT_ISSET_ID, value);
-  }
-
-  public void setFieldValue(_Fields field, Object value) {
-    switch (field) {
-    case DPID:
-      if (value == null) {
-        unsetDpid();
-      } else {
-        setDpid((Long)value);
-      }
-      break;
-
-    case PORT:
-      if (value == null) {
-        unsetPort();
-      } else {
-        setPort((Short)value);
-      }
-      break;
-
-    }
-  }
-
-  public Object getFieldValue(_Fields field) {
-    switch (field) {
-    case DPID:
-      return Long.valueOf(getDpid());
-
-    case PORT:
-      return Short.valueOf(getPort());
-
-    }
-    throw new IllegalStateException();
-  }
-
-  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
-  public boolean isSet(_Fields field) {
-    if (field == null) {
-      throw new IllegalArgumentException();
-    }
-
-    switch (field) {
-    case DPID:
-      return isSetDpid();
-    case PORT:
-      return isSetPort();
-    }
-    throw new IllegalStateException();
-  }
-
-  @Override
-  public boolean equals(Object that) {
-    if (that == null)
-      return false;
-    if (that instanceof SwitchPortTuple)
-      return this.equals((SwitchPortTuple)that);
-    return false;
-  }
-
-  public boolean equals(SwitchPortTuple that) {
-    if (that == null)
-      return false;
-
-    boolean this_present_dpid = true;
-    boolean that_present_dpid = true;
-    if (this_present_dpid || that_present_dpid) {
-      if (!(this_present_dpid && that_present_dpid))
-        return false;
-      if (this.dpid != that.dpid)
-        return false;
-    }
-
-    boolean this_present_port = true;
-    boolean that_present_port = true;
-    if (this_present_port || that_present_port) {
-      if (!(this_present_port && that_present_port))
-        return false;
-      if (this.port != that.port)
-        return false;
-    }
-
-    return true;
-  }
-
-  @Override
-  public int hashCode() {
-    return 0;
-  }
-
-  public int compareTo(SwitchPortTuple other) {
-    if (!getClass().equals(other.getClass())) {
-      return getClass().getName().compareTo(other.getClass().getName());
-    }
-
-    int lastComparison = 0;
-    SwitchPortTuple typedOther = (SwitchPortTuple)other;
-
-    lastComparison = Boolean.valueOf(isSetDpid()).compareTo(typedOther.isSetDpid());
-    if (lastComparison != 0) {
-      return lastComparison;
-    }
-    if (isSetDpid()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dpid, typedOther.dpid);
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-    }
-    lastComparison = Boolean.valueOf(isSetPort()).compareTo(typedOther.isSetPort());
-    if (lastComparison != 0) {
-      return lastComparison;
-    }
-    if (isSetPort()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.port, typedOther.port);
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-    }
-    return 0;
-  }
-
-  public _Fields fieldForId(int fieldId) {
-    return _Fields.findByThriftId(fieldId);
-  }
-
-  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
-    org.apache.thrift.protocol.TField field;
-    iprot.readStructBegin();
-    while (true)
-    {
-      field = iprot.readFieldBegin();
-      if (field.type == org.apache.thrift.protocol.TType.STOP) { 
-        break;
-      }
-      switch (field.id) {
-        case 1: // DPID
-          if (field.type == org.apache.thrift.protocol.TType.I64) {
-            this.dpid = iprot.readI64();
-            setDpidIsSet(true);
-          } else { 
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-          }
-          break;
-        case 2: // PORT
-          if (field.type == org.apache.thrift.protocol.TType.I16) {
-            this.port = iprot.readI16();
-            setPortIsSet(true);
-          } else { 
-            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-          }
-          break;
-        default:
-          org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
-      }
-      iprot.readFieldEnd();
-    }
-    iprot.readStructEnd();
-
-    // check for required fields of primitive type, which can't be checked in the validate method
-    validate();
-  }
-
-  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
-    validate();
-
-    oprot.writeStructBegin(STRUCT_DESC);
-    oprot.writeFieldBegin(DPID_FIELD_DESC);
-    oprot.writeI64(this.dpid);
-    oprot.writeFieldEnd();
-    oprot.writeFieldBegin(PORT_FIELD_DESC);
-    oprot.writeI16(this.port);
-    oprot.writeFieldEnd();
-    oprot.writeFieldStop();
-    oprot.writeStructEnd();
-  }
-
-  @Override
-  public String toString() {
-    StringBuilder sb = new StringBuilder("SwitchPortTuple(");
-    boolean first = true;
-
-    sb.append("dpid:");
-    sb.append(this.dpid);
-    first = false;
-    if (!first) sb.append(", ");
-    sb.append("port:");
-    sb.append(this.port);
-    first = false;
-    sb.append(")");
-    return sb.toString();
-  }
-
-  public void validate() throws org.apache.thrift.TException {
-    // check for required fields
-  }
-
-  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
-    try {
-      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
-    } catch (org.apache.thrift.TException te) {
-      throw new java.io.IOException(te);
-    }
-  }
-
-  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
-    try {
-      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
-      __isset_bit_vector = new BitSet(1);
-      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
-    } catch (org.apache.thrift.TException te) {
-      throw new java.io.IOException(te);
-    }
-  }
-
-}
-
diff --git a/pom.xml b/pom.xml
index 7484de0..0957c42 100644
--- a/pom.xml
+++ b/pom.xml
@@ -90,7 +90,7 @@
         <executions>
         </executions>
       </plugin>
-      <plugin>
+      <!--<plugin>
         <groupId>org.codehaus.mojo</groupId>
         <artifactId>build-helper-maven-plugin</artifactId>
         <version>1.7</version>
@@ -108,7 +108,7 @@
             </configuration>
           </execution>
         </executions>
-      </plugin>
+      </plugin>-->
     </plugins>
   </build>
   <!-- for getting visualization reporting   -->
@@ -231,16 +231,16 @@
       <artifactId>concurrentlinkedhashmap-lru</artifactId>
       <version>1.3</version>
     </dependency>
-    <dependency>
+    <!--<dependency>
       <groupId>org.python</groupId>
       <artifactId>jython-standalone</artifactId>
       <version>2.5.2</version>
-    </dependency>
-    <dependency>
+    </dependency>-->
+    <!--<dependency>
       <groupId>org.apache.thrift</groupId>
       <artifactId>libthrift</artifactId>
       <version>0.7.0</version>
-    </dependency>
+    </dependency>-->
     <dependency>
       <groupId>com.google.inject</groupId>
       <artifactId>guice</artifactId>
diff --git a/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java b/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java
deleted file mode 100644
index 36b5be3..0000000
--- a/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package net.floodlightcontroller.core;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public interface IOFMessageFilterManagerService extends IFloodlightService {
-    // empty for now
-}
diff --git a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
deleted file mode 100644
index 391c002..0000000
--- a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java
+++ /dev/null
@@ -1,529 +0,0 @@
-/**
- *    Copyright 2011, Big Switch Networks, Inc.
- *    Originally created by David Erickson, Stanford University
- *
- *    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 net.floodlightcontroller.core;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Timer;
-import java.util.TimerTask;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ScheduledExecutorService;
-
-import org.jboss.netty.buffer.ChannelBuffer;
-import org.jboss.netty.buffer.ChannelBuffers;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFType;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.List;
-import java.util.ArrayList;
-import org.apache.thrift.TException;
-import org.apache.thrift.transport.TFramedTransport;
-import org.apache.thrift.transport.TTransport;
-import org.apache.thrift.transport.TSocket;
-import org.apache.thrift.protocol.TBinaryProtocol;
-import org.apache.thrift.protocol.TProtocol;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packetstreamer.thrift.*;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-
-@LogMessageCategory("OpenFlow Message Tracing")
-public class OFMessageFilterManager 
-        implements IOFMessageListener, IFloodlightModule, IOFMessageFilterManagerService {
-
-    /**
-     * @author Srini
-     */
-    protected static Logger log = LoggerFactory.getLogger(OFMessageFilterManager.class);
-
-    // The port and client reference for packet streaming
-    protected int serverPort = 9090;
-    protected final int MaxRetry = 1;
-    protected static TTransport transport = null;
-    protected static PacketStreamer.Client packetClient = null;
-
-    protected IFloodlightProviderService floodlightProvider = null;
-    protected IThreadPoolService threadPool = null;
-    // filter List is a key value pair.  Key is the session id, 
-    // value is the filter rules.
-    protected ConcurrentHashMap<String, 
-                                ConcurrentHashMap<String,
-                                                  String>> filterMap = null;
-    protected ConcurrentHashMap<String, Long> filterTimeoutMap = null;
-    protected Timer timer = null;
-
-    protected int MAX_FILTERS=5;
-    protected long MAX_FILTER_TIME= 300000; // maximum filter time is 5 minutes.
-    protected int TIMER_INTERVAL = 1000;  // 1 second time interval.
-
-    public static final String SUCCESS                     = "0";
-    public static final String FILTER_SETUP_FAILED         = "-1001"; 
-    public static final String FILTER_NOT_FOUND            = "-1002";
-    public static final String FILTER_LIMIT_REACHED        = "-1003";
-    public static final String FILTER_SESSION_ID_NOT_FOUND = "-1004";
-    public static final String SERVICE_UNAVAILABLE         = "-1005";
-
-    public enum FilterResult {
-        /*
-         * FILTER_NOT_DEFINED: Filter is not defined
-         * FILTER_NO_MATCH:    Filter is defined and the packet doesn't 
-         *                     match the filter
-         * FILTER_MATCH:       Filter is defined and the packet matches
-         *                     the filter
-         */
-        FILTER_NOT_DEFINED, FILTER_NO_MATCH, FILTER_MATCH
-    }
-
-    protected String addFilter(ConcurrentHashMap<String,String> f, long delta) {
-
-        // Create unique session ID.  
-        int prime = 33791;
-        String s = null;
-        int i;
-
-        if ((filterMap == null) || (filterTimeoutMap == null))
-            return  String.format("%d", FILTER_SETUP_FAILED);
-
-        for (i=0; i<MAX_FILTERS; ++i) {
-            Integer x = prime + i;
-            s = String.format("%d", x.hashCode());
-            // implies you can use this key for session id.    
-            if (!filterMap.containsKey(s)) break; 
-        }
-
-        if (i==MAX_FILTERS) {
-            return FILTER_LIMIT_REACHED;
-        }
-
-        filterMap.put(s, f);
-        if (filterTimeoutMap.containsKey(s))  filterTimeoutMap.remove(s);
-        filterTimeoutMap.put(s, delta);
-
-        // set the timer as there will be no existing timers. 
-        if (filterMap.size() == 1) { 
-            TimeoutFilterTask task = new TimeoutFilterTask(this);
-            Timer timer = new Timer();
-            timer.schedule (task, TIMER_INTERVAL);                
-            // Keep the listeners to avoid race condition
-            //startListening();
-        }   
-        return s;  // the return string is the session ID.
-    }
-
-    public String setupFilter(String sid, 
-                              ConcurrentHashMap<String,String> f, 
-                              int deltaInMilliSeconds) {
-
-        if (sid == null) {
-            // Delta in filter needs to be milliseconds
-            log.debug("Adding new filter: {} for {} ms", f, deltaInMilliSeconds);
-            return addFilter(f, deltaInMilliSeconds);
-        } else {// this is the session id.
-            // we will ignore the hash map features.
-            if (deltaInMilliSeconds > 0)  
-                return refreshFilter(sid, deltaInMilliSeconds);
-            else 
-                return deleteFilter(sid);
-        }
-    }
-
-    public int timeoutFilters() {                
-        Iterator<String> i = filterTimeoutMap.keySet().iterator();
-
-        while(i.hasNext()) {
-            String s = i.next();
-
-            Long t = filterTimeoutMap.get(s);
-            if (t != null) {
-                i.remove();
-                t -= TIMER_INTERVAL;
-                if (t > 0) {
-                    filterTimeoutMap.put(s, t);
-                } else deleteFilter(s);
-            } else deleteFilter(s);
-        }
-        return filterMap.size();
-    }
-
-    protected String refreshFilter(String s, int delta) {
-        Long t = filterTimeoutMap.get(s);
-        if (t != null) {
-            filterTimeoutMap.remove(s);
-            t += delta;  // time is in milliseconds
-            if (t > MAX_FILTER_TIME) t = MAX_FILTER_TIME;
-            filterTimeoutMap.put(s, t);
-            return SUCCESS;
-        } else return FILTER_SESSION_ID_NOT_FOUND;
-    }
-
-    @LogMessageDoc(level="ERROR",
-                   message="Error while terminating packet " +
-                           "filter session",
-                   explanation="An unknown error occurred while terminating " +
-                   		"a packet filter session.",
-                   recommendation=LogMessageDoc.GENERIC_ACTION)
-    protected String deleteFilter(String sessionId) {
-
-        if (filterMap.containsKey(sessionId)) {
-            filterMap.remove(sessionId);
-            try {
-                if (packetClient != null)
-                    packetClient.terminateSession(sessionId);
-            } catch (TException e) {
-                log.error("Error while terminating packet " +
-                		  "filter session", e);
-            }
-            log.debug("Deleted Filter {}.  # of filters" +
-            		 " remaining: {}", sessionId, filterMap.size());
-            return SUCCESS;
-        } else return FILTER_SESSION_ID_NOT_FOUND;
-    }
-
-    public HashSet<String> getMatchedFilters(OFMessage m, FloodlightContext cntx) {  
-
-        HashSet<String> matchedFilters = new HashSet<String>();
-
-        // This default function is written to match on packet ins and 
-        // packet outs.
-        Ethernet eth = null;
-
-        if (m.getType() == OFType.PACKET_IN) {
-            eth = IFloodlightProviderService.bcStore.get(cntx, 
-                    IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-        } else if (m.getType() == OFType.PACKET_OUT) {
-            eth = new Ethernet();
-            OFPacketOut p = (OFPacketOut) m;
-            
-            // No MAC match if packetOut doesn't have the packet.
-            if (p.getPacketData() == null) return null;
-            
-            eth.deserialize(p.getPacketData(), 0, p.getPacketData().length);
-        } else if (m.getType() == OFType.FLOW_MOD) {
-            // flow-mod can't be matched by mac.
-            return null;
-        }
-
-        if (eth == null) return null;
-
-        Iterator<String> filterIt = filterMap.keySet().iterator();
-        while (filterIt.hasNext()) {   // for every filter
-            boolean filterMatch = false;
-            String filterSessionId = filterIt.next();
-            Map<String,String> filter = filterMap.get(filterSessionId);
-
-            // If the filter has empty fields, then it is not considered as a match.
-            if (filter == null || filter.isEmpty()) continue;                  
-            Iterator<String> fieldIt = filter.keySet().iterator();
-            while (fieldIt.hasNext()) {   
-                String filterFieldType = fieldIt.next();
-                String filterFieldValue = filter.get(filterFieldType);
-                if (filterFieldType.equals("mac")) {
-
-                    String srcMac = HexString.toHexString(eth.getSourceMACAddress());
-                    String dstMac = HexString.toHexString(eth.getDestinationMACAddress());
-                    log.debug("srcMac: {}, dstMac: {}", srcMac, dstMac);
-
-                    if (filterFieldValue.equals(srcMac) || 
-                            filterFieldValue.equals(dstMac)){
-                        filterMatch = true; 
-                    } else {
-                        filterMatch = false;
-                        break;
-                    }
-                }
-            }
-            if (filterMatch) {
-                matchedFilters.add(filterSessionId);
-            }
-        }
-
-        if (matchedFilters.isEmpty())
-            return null;    
-        else 
-            return matchedFilters;
-    }
-    
-    @LogMessageDoc(level="ERROR",
-                   message="Failed to establish connection with the " +
-                           "packetstreamer server.",
-                   explanation="The message tracing server is not running " +
-                   		"or otherwise unavailable.",
-                   recommendation=LogMessageDoc.CHECK_CONTROLLER)
-    public boolean connectToPSServer() {
-        int numRetries = 0;
-        if (transport != null && transport.isOpen()) {
-            return true;
-        }
-
-        while (numRetries++ < MaxRetry) {
-            try {
-                transport = new TFramedTransport(new TSocket("localhost", 
-                                                             serverPort));
-                transport.open();
-
-                TProtocol protocol = new  TBinaryProtocol(transport);
-                packetClient = new PacketStreamer.Client(protocol);
-
-                log.debug("Have a connection to packetstreamer server " +
-                		  "localhost:{}", serverPort);
-                break;
-            } catch (TException x) {
-                try {
-                    // Wait for 1 second before retry
-                    if (numRetries < MaxRetry) {
-                        Thread.sleep(1000);
-                    }
-                } catch (Exception e) {}
-            } 
-        }
-
-        if (numRetries > MaxRetry) {
-            log.error("Failed to establish connection with the " +
-            		  "packetstreamer server.");
-            return false;
-        }
-        return true;
-    }
-
-    public void disconnectFromPSServer() {
-        if (transport != null && transport.isOpen()) {
-            log.debug("Close the connection to packetstreamer server" +
-            		  " localhost:{}", serverPort);
-            transport.close();
-        }
-    }
-
-    @Override
-    public String getName() {
-        return "messageFilterManager";
-    }
-
-    @Override
-    public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        return (type == OFType.PACKET_IN && name.equals("devicemanager"));
-    }
-
-    @Override
-    public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        return (type == OFType.PACKET_IN && name.equals("learningswitch"));
-    }
-
-    @Override
-    @LogMessageDoc(level="ERROR",
-                   message="Error while sending packet",
-                   explanation="Failed to send a message to the message " +
-                   		"tracing server",
-                   recommendation=LogMessageDoc.CHECK_CONTROLLER)
-    public Command receive(IOFSwitch sw, OFMessage msg, 
-                           FloodlightContext cntx) {
-
-        if (filterMap == null || filterMap.isEmpty()) return Command.CONTINUE;
-
-        HashSet<String> matchedFilters = null;
-        if (log.isDebugEnabled()) {
-            log.debug("Received packet {} from switch {}", 
-                      msg, sw.getStringId());
-        }
-
-        matchedFilters = getMatchedFilters(msg, cntx);
-        if (matchedFilters == null) {
-            return Command.CONTINUE;
-        } else {
-            try {
-                sendPacket(matchedFilters, sw, msg, cntx, true);
-            } catch (Exception e) {
-                log.error("Error while sending packet", e);
-            }
-        }
-        
-        return Command.CONTINUE;
-    }
-
-
-    public class TimeoutFilterTask extends TimerTask {
-
-        OFMessageFilterManager filterManager;
-        ScheduledExecutorService ses = threadPool.getScheduledExecutor();
-
-        public TimeoutFilterTask(OFMessageFilterManager manager) {
-            filterManager = manager;
-        }
-
-        public void run() {
-            int x = filterManager.timeoutFilters();
-
-            if (x > 0) {  // there's at least one filter still active.
-                Timer timer = new Timer();
-                timer.schedule(new TimeoutFilterTask(filterManager), 
-                               TIMER_INTERVAL);
-            } else {
-                // Don't stop the listener to avoid race condition
-                //stopListening();
-            }
-        }
-    }
-
-    public int getNumberOfFilters() {
-        return filterMap.size();
-    }
-
-    public int getMaxFilterSize() {
-        return MAX_FILTERS;
-    }
-
-    protected void sendPacket(HashSet<String> matchedFilters, IOFSwitch sw, 
-            OFMessage msg, FloodlightContext cntx, boolean sync) 
-                    throws TException {
-        Message sendMsg = new Message();
-        Packet packet = new Packet();
-        ChannelBuffer bb;
-        sendMsg.setPacket(packet);
-
-        List<String> sids = new ArrayList<String>(matchedFilters);
-
-        sendMsg.setSessionIDs(sids);
-        packet.setMessageType(OFMessageType.findByValue((msg.getType().ordinal())));
-
-        switch (msg.getType()) {
-            case PACKET_IN:
-                OFPacketIn pktIn = (OFPacketIn)msg;
-                packet.setSwPortTuple(new SwitchPortTuple(sw.getId(), 
-                                                          pktIn.getInPort()));
-                bb = ChannelBuffers.buffer(pktIn.getLength());
-                pktIn.writeTo(bb);
-                packet.setData(OFMessage.getData(sw, msg, cntx));
-                break;
-            case PACKET_OUT:
-                OFPacketOut pktOut = (OFPacketOut)msg;
-                packet.setSwPortTuple(new SwitchPortTuple(sw.getId(), 
-                                                          pktOut.getInPort()));
-                bb = ChannelBuffers.buffer(pktOut.getLength());
-                pktOut.writeTo(bb);
-                packet.setData(OFMessage.getData(sw, msg, cntx));
-                break;
-            case FLOW_MOD:
-                OFFlowMod offlowMod = (OFFlowMod)msg;
-                packet.setSwPortTuple(new SwitchPortTuple(sw.getId(), 
-                                                          offlowMod.
-                                                          getOutPort()));
-                bb = ChannelBuffers.buffer(offlowMod.getLength());
-                offlowMod.writeTo(bb);
-                packet.setData(OFMessage.getData(sw, msg, cntx));
-                break;
-            default:
-                packet.setSwPortTuple(new SwitchPortTuple(sw.getId(), 
-                                                          (short)0));
-                String strData = "Unknown packet";
-                packet.setData(strData.getBytes());
-                break;
-        }
-
-        try {
-            if (transport == null || 
-                !transport.isOpen() || 
-                packetClient == null) {
-                if (!connectToPSServer()) {
-                    // No need to sendPacket if can't make connection to 
-                    // the server
-                    return;
-                }
-            }
-            if (sync) {
-                log.debug("Send packet sync: {}", packet.toString());
-                packetClient.pushMessageSync(sendMsg);
-            } else {
-                log.debug("Send packet sync: ", packet.toString());
-                packetClient.pushMessageAsync(sendMsg);
-            }
-        } catch (Exception e) {
-            log.error("Error while sending packet", e);
-            disconnectFromPSServer();
-            connectToPSServer();
-        }
-    }
-
-    // IFloodlightModule methods
-    
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IOFMessageFilterManagerService.class);
-        return l;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService>
-            getServiceImpls() {
-        Map<Class<? extends IFloodlightService>,
-        IFloodlightService> m = 
-            new HashMap<Class<? extends IFloodlightService>,
-                        IFloodlightService>();
-        // We are the class that implements the service
-        m.put(IOFMessageFilterManagerService.class, this);
-        return m;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFloodlightProviderService.class);
-        l.add(IThreadPoolService.class);
-        return l;
-    }
-
-    @Override
-    public void init(FloodlightModuleContext context) 
-            throws FloodlightModuleException {
-        this.floodlightProvider = 
-                context.getServiceImpl(IFloodlightProviderService.class);
-        this.threadPool =
-                context.getServiceImpl(IThreadPoolService.class);
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-        // This is our 'constructor'
-        
-        filterMap = new ConcurrentHashMap<String, ConcurrentHashMap<String,String>>();
-        filterTimeoutMap = new ConcurrentHashMap<String, Long>();
-        serverPort = 
-                Integer.parseInt(System.getProperty("net.floodlightcontroller." +
-                		"packetstreamer.port", "9090"));
-        
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-        floodlightProvider.addOFMessageListener(OFType.PACKET_OUT, this);
-        floodlightProvider.addOFMessageListener(OFType.FLOW_MOD, this);
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
index 2bb39ef..00b692f 100644
--- a/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
+++ b/src/main/java/net/floodlightcontroller/core/web/CoreWebRoutable.java
@@ -49,7 +49,6 @@
         router.attach("/counter/{switchId}/{counterName}/json", SwitchCounterResource.class);
         router.attach("/counter/categories/{switchId}/{counterName}/{layer}/json", SwitchCounterCategoriesResource.class);
         router.attach("/memory/json", ControllerMemoryResource.class);
-        router.attach("/packettrace/json", PacketTraceResource.class);
         // Get the last {count} events from the event histories
         router.attach("/event-history/topology-switch/{count}/json",
                 EventHistoryTopologySwitchResource.class);
diff --git a/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java b/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java
deleted file mode 100644
index 85da942..0000000
--- a/src/main/java/net/floodlightcontroller/core/web/PacketTraceResource.java
+++ /dev/null
@@ -1,118 +0,0 @@
-package net.floodlightcontroller.core.web;
-
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.restlet.data.Status;
-import org.restlet.resource.Post;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.OFMessageFilterManager;
-
-public class PacketTraceResource extends ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(PacketTraceResource.class);
-    
-    public static class FilterParameters {
-
-        protected String sessionId = null;
-        protected String mac = null;
-        protected Integer period = null;
-        protected String direction = null;
-        protected String output = null;
-        
-        public String getSessionId() {
-            return sessionId;
-        }
-        public void setSessionId(String sessionId) {
-            this.sessionId = sessionId;
-        }
-        public String getMac() {
-            return mac;
-        }
-        public void setMac(String mac) {
-            this.mac = mac;
-        }
-        public Integer getPeriod() {
-            return period;
-        }
-        public void setPeriod(Integer period) {
-            this.period = period;
-        }
-        public String getDirection() {
-            return direction;
-        }
-        public void setDirection(String direction) {
-            this.direction = direction;
-        }
-        public String getOutput() {
-            return output;
-        }
-        public void setOutput(String output) {
-            this.output = output;
-        }
-
-        public String toString() {
-            return "SessionID: " + sessionId +
-                   "\tmac" + mac +
-                   "\tperiod" + period +
-                   "\tdirection" + direction +
-                   "\toutput" + output;
-        }
-    }
-    
-    public static class PacketTraceOutput {
-        protected String sessionId = null;
-
-        public String getSessionId() {
-            return sessionId;
-        }
-
-        public void setSessionId(String sessionId) {
-            this.sessionId = sessionId;
-        }
-    }
-    
-    @Post("json")
-    public PacketTraceOutput packettrace(FilterParameters fp) {
-        
-        ConcurrentHashMap <String,String> filter = new ConcurrentHashMap<String,String> ();
-        String sid = null;
-        PacketTraceOutput output = new PacketTraceOutput();
-        OFMessageFilterManager manager = 
-                (OFMessageFilterManager)getContext()
-                    .getAttributes().
-                        get(OFMessageFilterManager.class.getCanonicalName());
-
-        if (manager == null) {
-            sid = null;
-            setStatus(Status.SERVER_ERROR_SERVICE_UNAVAILABLE);
-        }
-        
-        if (fp.getSessionId() != null) {
-            filter.put("sessionId", fp.getSessionId());
-        }
-        if (fp.getMac() != null) {
-            filter.put("mac", fp.getMac());
-        }
-        if (fp.getDirection() != null) {
-            filter.put("direction", fp.getDirection());
-        }
-        
-        if (filter.isEmpty()) {
-            setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
-        } else {
-            if (log.isDebugEnabled()) {
-                log.debug ("Call setupFilter: sid:{} filter:{}, period:{}", 
-                           new Object[] {fp.getSessionId(), filter, 
-                                         fp.getPeriod()*1000});
-            }
-            sid = manager.setupFilter(fp.getSessionId(), filter, 
-                                      fp.getPeriod()*1000);
-            output.setSessionId(sid);
-            setStatus(Status.SUCCESS_OK);
-        }
-        
-        return output;
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/Firewall.java b/src/main/java/net/floodlightcontroller/firewall/Firewall.java
deleted file mode 100644
index 3f8ff6c..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/Firewall.java
+++ /dev/null
@@ -1,667 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-
-import java.util.ArrayList;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.routing.IRoutingDecision;
-import net.floodlightcontroller.routing.RoutingDecision;
-import net.floodlightcontroller.storage.IResultSet;
-import net.floodlightcontroller.storage.IStorageSourceService;
-import net.floodlightcontroller.storage.StorageException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Stateless firewall implemented as a Google Summer of Code project.
- * Configuration done through REST API
- * 
- * @author Amer Tahir
- * @edited KC Wang
- */
-public class Firewall implements IFirewallService, IOFMessageListener,
-        IFloodlightModule {
-
-    // service modules needed
-    protected IFloodlightProviderService floodlightProvider;
-    protected IStorageSourceService storageSource;
-    protected IRestApiService restApi;
-    protected static Logger logger;
-
-    protected List<FirewallRule> rules; // protected by synchronized
-    protected boolean enabled;
-    protected int subnet_mask = IPv4.toIPv4Address("255.255.255.0");
-
-    // constant strings for storage/parsing
-    public static final String TABLE_NAME = "controller_firewallrules";
-    public static final String COLUMN_RULEID = "ruleid";
-    public static final String COLUMN_DPID = "dpid";
-    public static final String COLUMN_IN_PORT = "in_port";
-    public static final String COLUMN_DL_SRC = "dl_src";
-    public static final String COLUMN_DL_DST = "dl_dst";
-    public static final String COLUMN_DL_TYPE = "dl_type";
-    public static final String COLUMN_NW_SRC_PREFIX = "nw_src_prefix";
-    public static final String COLUMN_NW_SRC_MASKBITS = "nw_src_maskbits";
-    public static final String COLUMN_NW_DST_PREFIX = "nw_dst_prefix";
-    public static final String COLUMN_NW_DST_MASKBITS = "nw_dst_maskbits";
-    public static final String COLUMN_NW_PROTO = "nw_proto";
-    public static final String COLUMN_TP_SRC = "tp_src";
-    public static final String COLUMN_TP_DST = "tp_dst";
-    public static final String COLUMN_WILDCARD_DPID = "wildcard_dpid";
-    public static final String COLUMN_WILDCARD_IN_PORT = "wildcard_in_port";
-    public static final String COLUMN_WILDCARD_DL_SRC = "wildcard_dl_src";
-    public static final String COLUMN_WILDCARD_DL_DST = "wildcard_dl_dst";
-    public static final String COLUMN_WILDCARD_DL_TYPE = "wildcard_dl_type";
-    public static final String COLUMN_WILDCARD_NW_SRC = "wildcard_nw_src";
-    public static final String COLUMN_WILDCARD_NW_DST = "wildcard_nw_dst";
-    public static final String COLUMN_WILDCARD_NW_PROTO = "wildcard_nw_proto";
-    public static final String COLUMN_WILDCARD_TP_SRC = "wildcard_tp_src";
-    public static final String COLUMN_WILDCARD_TP_DST = "wildcard_tp_dst";
-    public static final String COLUMN_PRIORITY = "priority";
-    public static final String COLUMN_ACTION = "action";
-    public static String ColumnNames[] = { COLUMN_RULEID, COLUMN_DPID,
-            COLUMN_IN_PORT, COLUMN_DL_SRC, COLUMN_DL_DST, COLUMN_DL_TYPE,
-            COLUMN_NW_SRC_PREFIX, COLUMN_NW_SRC_MASKBITS, COLUMN_NW_DST_PREFIX,
-            COLUMN_NW_DST_MASKBITS, COLUMN_NW_PROTO, COLUMN_TP_SRC,
-            COLUMN_TP_DST, COLUMN_WILDCARD_DPID, COLUMN_WILDCARD_IN_PORT,
-            COLUMN_WILDCARD_DL_SRC, COLUMN_WILDCARD_DL_DST,
-            COLUMN_WILDCARD_DL_TYPE, COLUMN_WILDCARD_NW_SRC,
-            COLUMN_WILDCARD_NW_DST, COLUMN_WILDCARD_NW_PROTO, COLUMN_PRIORITY,
-            COLUMN_ACTION };
-
-    @Override
-    public String getName() {
-        return "firewall";
-    }
-
-    @Override
-    public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        // no prereq
-        return false;
-    }
-
-    @Override
-    public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        return (type.equals(OFType.PACKET_IN) && name.equals("forwarding"));
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFirewallService.class);
-        return l;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
-        Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>();
-        // We are the class that implements the service
-        m.put(IFirewallService.class, this);
-        return m;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFloodlightProviderService.class);
-        l.add(IStorageSourceService.class);
-        l.add(IRestApiService.class);
-        return l;
-    }
-
-    /**
-     * Reads the rules from the storage and creates a sorted arraylist of
-     * FirewallRule from them.
-     * 
-     * Similar to getStorageRules(), which only reads contents for REST GET and
-     * does no parsing, checking, nor putting into FirewallRule objects
-     * 
-     * @return the sorted arraylist of FirewallRule instances (rules from
-     *         storage)
-     */
-    protected ArrayList<FirewallRule> readRulesFromStorage() {
-        ArrayList<FirewallRule> l = new ArrayList<FirewallRule>();
-
-        try {
-            Map<String, Object> row;
-
-            // (..., null, null) for no predicate, no ordering
-            IResultSet resultSet = storageSource.executeQuery(TABLE_NAME,
-                    ColumnNames, null, null);
-
-            // put retrieved rows into FirewallRules
-            for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
-                row = it.next().getRow();
-                // now, parse row
-                FirewallRule r = new FirewallRule();
-                if (!row.containsKey(COLUMN_RULEID)
-                        || !row.containsKey(COLUMN_DPID)) {
-                    logger.error(
-                            "skipping entry with missing required 'ruleid' or 'switchid' entry: {}",
-                            row);
-                    return l;
-                }
-                try {
-                    r.ruleid = Integer
-                            .parseInt((String) row.get(COLUMN_RULEID));
-                    r.dpid = Long.parseLong((String) row.get(COLUMN_DPID));
-
-                    for (String key : row.keySet()) {
-                        if (row.get(key) == null)
-                            continue;
-                        if (key.equals(COLUMN_RULEID)
-                                || key.equals(COLUMN_DPID)
-                                || key.equals("id")) {
-                            continue; // already handled
-                        } 
-                        
-                        else if (key.equals(COLUMN_IN_PORT)) {
-                            r.in_port = Short.parseShort((String) row
-                                    .get(COLUMN_IN_PORT));
-                        } 
-                        
-                        else if (key.equals(COLUMN_DL_SRC)) {
-                            r.dl_src = Long.parseLong((String) row
-                                    .get(COLUMN_DL_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_DL_DST)) {
-                            r.dl_dst = Long.parseLong((String) row
-                                    .get(COLUMN_DL_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_DL_TYPE)) {
-                            r.dl_type = Short.parseShort((String) row
-                                    .get(COLUMN_DL_TYPE));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_SRC_PREFIX)) {
-                            r.nw_src_prefix = Integer.parseInt((String) row
-                                    .get(COLUMN_NW_SRC_PREFIX));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_SRC_MASKBITS)) {
-                            r.nw_src_maskbits = Integer.parseInt((String) row
-                                    .get(COLUMN_NW_SRC_MASKBITS));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_DST_PREFIX)) {
-                            r.nw_dst_prefix = Integer.parseInt((String) row
-                                    .get(COLUMN_NW_DST_PREFIX));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_DST_MASKBITS)) {
-                            r.nw_dst_maskbits = Integer.parseInt((String) row
-                                    .get(COLUMN_NW_DST_MASKBITS));
-                        } 
-                        
-                        else if (key.equals(COLUMN_NW_PROTO)) {
-                            r.nw_proto = Short.parseShort((String) row
-                                    .get(COLUMN_NW_PROTO));
-                        } 
-                        
-                        else if (key.equals(COLUMN_TP_SRC)) {
-                            r.tp_src = Short.parseShort((String) row
-                                    .get(COLUMN_TP_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_TP_DST)) {
-                            r.tp_dst = Short.parseShort((String) row
-                                    .get(COLUMN_TP_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DPID)) {
-                            r.wildcard_dpid = Boolean.parseBoolean((String) row
-                                    .get(COLUMN_WILDCARD_DPID));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_IN_PORT)) {
-                            r.wildcard_in_port = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_IN_PORT));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DL_SRC)) {
-                            r.wildcard_dl_src = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_DL_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DL_DST)) {
-                            r.wildcard_dl_dst = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_DL_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_DL_TYPE)) {
-                            r.wildcard_dl_type = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_DL_TYPE));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_NW_SRC)) {
-                            r.wildcard_nw_src = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_NW_SRC));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_NW_DST)) {
-                            r.wildcard_nw_dst = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_NW_DST));
-                        } 
-                        
-                        else if (key.equals(COLUMN_WILDCARD_NW_PROTO)) {
-                            r.wildcard_nw_proto = Boolean
-                                    .parseBoolean((String) row
-                                            .get(COLUMN_WILDCARD_NW_PROTO));
-                        } 
-                        
-                        else if (key.equals(COLUMN_PRIORITY)) {
-                            r.priority = Integer.parseInt((String) row
-                                    .get(COLUMN_PRIORITY));
-                        } 
-                        
-                        else if (key.equals(COLUMN_ACTION)) {
-                            int tmp = Integer.parseInt((String) row.get(COLUMN_ACTION));
-                            if (tmp == FirewallRule.FirewallAction.DENY.ordinal())
-                                r.action = FirewallRule.FirewallAction.DENY;
-                            else if (tmp == FirewallRule.FirewallAction.ALLOW.ordinal())
-                                r.action = FirewallRule.FirewallAction.ALLOW;
-                            else {
-                                r.action = null;
-                                logger.error("action not recognized");
-                            }
-                        }
-                    }
-                } catch (ClassCastException e) {
-                    logger.error(
-                            "skipping rule {} with bad data : "
-                                    + e.getMessage(), r.ruleid);
-                }
-                if (r.action != null)
-                    l.add(r);
-            }
-        } catch (StorageException e) {
-            logger.error("failed to access storage: {}", e.getMessage());
-            // if the table doesn't exist, then wait to populate later via
-            // setStorageSource()
-        }
-
-        // now, sort the list based on priorities
-        Collections.sort(l);
-
-        return l;
-    }
-
-    @Override
-    public void init(FloodlightModuleContext context)
-            throws FloodlightModuleException {
-        floodlightProvider = context
-                .getServiceImpl(IFloodlightProviderService.class);
-        storageSource = context.getServiceImpl(IStorageSourceService.class);
-        restApi = context.getServiceImpl(IRestApiService.class);
-        rules = new ArrayList<FirewallRule>();
-        logger = LoggerFactory.getLogger(Firewall.class);
-
-        // start disabled
-        enabled = false;
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-        // register REST interface
-        restApi.addRestletRoutable(new FirewallWebRoutable());
-
-        // always place firewall in pipeline at bootup
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-
-        // storage, create table and read rules
-        storageSource.createTable(TABLE_NAME, null);
-        storageSource.setTablePrimaryKeyName(TABLE_NAME, COLUMN_RULEID);
-        synchronized (rules) {
-            this.rules = readRulesFromStorage();
-        }
-    }
-
-    @Override
-    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-        if (!this.enabled)
-            return Command.CONTINUE;
-
-        switch (msg.getType()) {
-        case PACKET_IN:
-            IRoutingDecision decision = null;
-            if (cntx != null) {
-                decision = IRoutingDecision.rtStore.get(cntx,
-                        IRoutingDecision.CONTEXT_DECISION);
-
-                return this.processPacketInMessage(sw, (OFPacketIn) msg,
-                        decision, cntx);
-            }
-            break;
-        default:
-            break;
-        }
-
-        return Command.CONTINUE;
-    }
-
-    @Override
-    public void enableFirewall(boolean enabled) {
-        logger.info("Setting firewall to {}", enabled);
-        this.enabled = enabled;
-    }
-
-    @Override
-    public List<FirewallRule> getRules() {
-        return this.rules;
-    }
-
-    // Only used to serve REST GET
-    // Similar to readRulesFromStorage(), which actually checks and stores
-    // record into FirewallRule list
-    @Override
-    public List<Map<String, Object>> getStorageRules() {
-        ArrayList<Map<String, Object>> l = new ArrayList<Map<String, Object>>();
-        try {
-            // null1=no predicate, null2=no ordering
-            IResultSet resultSet = storageSource.executeQuery(TABLE_NAME,
-                    ColumnNames, null, null);
-            for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
-                l.add(it.next().getRow());
-            }
-        } catch (StorageException e) {
-            logger.error("failed to access storage: {}", e.getMessage());
-            // if the table doesn't exist, then wait to populate later via
-            // setStorageSource()
-        }
-        return l;
-    }
-
-    @Override
-    public String getSubnetMask() {
-        return IPv4.fromIPv4Address(this.subnet_mask);
-    }
-
-    @Override
-    public void setSubnetMask(String newMask) {
-        if (newMask.trim().isEmpty())
-            return;
-        this.subnet_mask = IPv4.toIPv4Address(newMask.trim());
-    }
-
-    @Override
-    public synchronized void addRule(FirewallRule rule) {
-        
-        // generate random ruleid for each newly created rule
-        // may want to return to caller if useful
-        // may want to check conflict
-        rule.ruleid = rule.genID();
-        
-        int i = 0;
-        // locate the position of the new rule in the sorted arraylist
-        for (i = 0; i < this.rules.size(); i++) {
-            if (this.rules.get(i).priority >= rule.priority)
-                break;
-        }
-        // now, add rule to the list
-        if (i <= this.rules.size()) {
-            this.rules.add(i, rule);
-        } else {
-            this.rules.add(rule);
-        }
-        // add rule to database
-        Map<String, Object> entry = new HashMap<String, Object>();
-        entry.put(COLUMN_RULEID, Integer.toString(rule.ruleid));
-        entry.put(COLUMN_DPID, Long.toString(rule.dpid));
-        entry.put(COLUMN_IN_PORT, Short.toString(rule.in_port));
-        entry.put(COLUMN_DL_SRC, Long.toString(rule.dl_src));
-        entry.put(COLUMN_DL_DST, Long.toString(rule.dl_dst));
-        entry.put(COLUMN_DL_TYPE, Short.toString(rule.dl_type));
-        entry.put(COLUMN_NW_SRC_PREFIX, Integer.toString(rule.nw_src_prefix));
-        entry.put(COLUMN_NW_SRC_MASKBITS, Integer.toString(rule.nw_src_maskbits));
-        entry.put(COLUMN_NW_DST_PREFIX, Integer.toString(rule.nw_dst_prefix));
-        entry.put(COLUMN_NW_DST_MASKBITS, Integer.toString(rule.nw_dst_maskbits));
-        entry.put(COLUMN_NW_PROTO, Short.toString(rule.nw_proto));
-        entry.put(COLUMN_TP_SRC, Integer.toString(rule.tp_src));
-        entry.put(COLUMN_TP_DST, Integer.toString(rule.tp_dst));
-        entry.put(COLUMN_WILDCARD_DPID,
-                Boolean.toString(rule.wildcard_dpid));
-        entry.put(COLUMN_WILDCARD_IN_PORT,
-                Boolean.toString(rule.wildcard_in_port));
-        entry.put(COLUMN_WILDCARD_DL_SRC,
-                Boolean.toString(rule.wildcard_dl_src));
-        entry.put(COLUMN_WILDCARD_DL_DST,
-                Boolean.toString(rule.wildcard_dl_dst));
-        entry.put(COLUMN_WILDCARD_DL_TYPE,
-                Boolean.toString(rule.wildcard_dl_type));
-        entry.put(COLUMN_WILDCARD_NW_SRC,
-                Boolean.toString(rule.wildcard_nw_src));
-        entry.put(COLUMN_WILDCARD_NW_DST,
-                Boolean.toString(rule.wildcard_nw_dst));
-        entry.put(COLUMN_WILDCARD_NW_PROTO,
-                Boolean.toString(rule.wildcard_nw_proto));
-        entry.put(COLUMN_WILDCARD_TP_SRC,
-                Boolean.toString(rule.wildcard_tp_src));
-        entry.put(COLUMN_WILDCARD_TP_DST,
-                Boolean.toString(rule.wildcard_tp_dst));
-        entry.put(COLUMN_PRIORITY, Integer.toString(rule.priority));
-        entry.put(COLUMN_ACTION, Integer.toString(rule.action.ordinal()));
-        storageSource.insertRow(TABLE_NAME, entry);
-    }
-
-    @Override
-    public synchronized void deleteRule(int ruleid) {
-        Iterator<FirewallRule> iter = this.rules.iterator();
-        while (iter.hasNext()) {
-            FirewallRule r = iter.next();
-            if (r.ruleid == ruleid) {
-                // found the rule, now remove it
-                iter.remove();
-                break;
-            }
-        }
-        // delete from database
-        storageSource.deleteRow(TABLE_NAME, Integer.toString(ruleid));
-    }
-
-    /**
-     * Iterates over the firewall rules and tries to match them with the
-     * incoming packet (flow). Uses the FirewallRule class's matchWithFlow
-     * method to perform matching. It maintains a pair of wildcards (allow and
-     * deny) which are assigned later to the firewall's decision, where 'allow'
-     * wildcards are applied if the matched rule turns out to be an ALLOW rule
-     * and 'deny' wildcards are applied otherwise. Wildcards are applied to
-     * firewall decision to optimize flows in the switch, ensuring least number
-     * of flows per firewall rule. So, if a particular field is not "ANY" (i.e.
-     * not wildcarded) in a higher priority rule, then if a lower priority rule
-     * matches the packet and wildcards it, it can't be wildcarded in the
-     * switch's flow entry, because otherwise some packets matching the higher
-     * priority rule might escape the firewall. The reason for keeping different
-     * two different wildcards is that if a field is not wildcarded in a higher
-     * priority allow rule, the same field shouldn't be wildcarded for packets
-     * matching the lower priority deny rule (non-wildcarded fields in higher
-     * priority rules override the wildcarding of those fields in lower priority
-     * rules of the opposite type). So, to ensure that wildcards are
-     * appropriately set for different types of rules (allow vs. deny), separate
-     * wildcards are maintained. Iteration is performed on the sorted list of
-     * rules (sorted in decreasing order of priority).
-     * 
-     * @param sw
-     *            the switch instance
-     * @param pi
-     *            the incoming packet data structure
-     * @param cntx
-     *            the floodlight context
-     * @return an instance of RuleWildcardsPair that specify rule that matches
-     *         and the wildcards for the firewall decision
-     */
-    protected RuleWildcardsPair matchWithRule(IOFSwitch sw, OFPacketIn pi,
-            FloodlightContext cntx) {
-        FirewallRule matched_rule = null;
-        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-        WildcardsPair wildcards = new WildcardsPair();
-
-        synchronized (rules) {
-            Iterator<FirewallRule> iter = this.rules.iterator();
-            FirewallRule rule = null;
-            // iterate through list to find a matching firewall rule
-            while (iter.hasNext()) {
-                // get next rule from list
-                rule = iter.next();
-
-                // check if rule matches
-                if (rule.matchesFlow(sw.getId(), pi.getInPort(), eth, wildcards) == true) {
-                    matched_rule = rule;
-                    break;
-                }
-            }
-        }
-
-        // make a pair of rule and wildcards, then return it
-        RuleWildcardsPair ret = new RuleWildcardsPair();
-        ret.rule = matched_rule;
-        if (matched_rule == null || matched_rule.action == FirewallRule.FirewallAction.DENY) {
-            ret.wildcards = wildcards.drop;
-        } else {
-            ret.wildcards = wildcards.allow;
-        }
-        return ret;
-    }
-
-    /**
-     * Checks whether an IP address is a broadcast address or not (determines
-     * using subnet mask)
-     * 
-     * @param IPAddress
-     *            the IP address to check
-     * @return true if it is a broadcast address, false otherwise
-     */
-    protected boolean IPIsBroadcast(int IPAddress) {
-        // inverted subnet mask
-        int inv_subnet_mask = ~this.subnet_mask;
-        return ((IPAddress & inv_subnet_mask) == inv_subnet_mask);
-    }
-
-    public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi,
-            IRoutingDecision decision, FloodlightContext cntx) {
-        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx,
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-
-        // Allowing L2 broadcast + ARP broadcast request (also deny malformed
-        // broadcasts -> L2 broadcast + L3 unicast)
-        if (eth.isBroadcast() == true) {
-            boolean allowBroadcast = true;
-            // the case to determine if we have L2 broadcast + L3 unicast
-            // don't allow this broadcast packet if such is the case (malformed
-            // packet)
-            if (eth.getEtherType() == Ethernet.TYPE_IPv4
-                    && this.IPIsBroadcast(((IPv4) eth.getPayload())
-                            .getDestinationAddress()) == false) {
-                allowBroadcast = false;
-            }
-            if (allowBroadcast == true) {
-                if (logger.isTraceEnabled())
-                    logger.trace("Allowing broadcast traffic for PacketIn={}",
-                            pi);
-                                        
-                decision = new RoutingDecision(sw.getId(), pi.getInPort()
-                		, IDeviceService.fcStore.
-                        get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
-                        IRoutingDecision.RoutingAction.MULTICAST);
-                decision.addToContext(cntx);
-            } else {
-                if (logger.isTraceEnabled())
-                    logger.trace(
-                            "Blocking malformed broadcast traffic for PacketIn={}",
-                            pi);
-
-                decision = new RoutingDecision(sw.getId(), pi.getInPort()
-                		, IDeviceService.fcStore.
-                        get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
-                        IRoutingDecision.RoutingAction.DROP);
-                decision.addToContext(cntx);
-            }
-            return Command.CONTINUE;
-        }
-        /*
-         * ARP response (unicast) can be let through without filtering through
-         * rules by uncommenting the code below
-         */
-        /*
-         * else if (eth.getEtherType() == Ethernet.TYPE_ARP) {
-         * logger.info("allowing ARP traffic"); decision = new
-         * FirewallDecision(IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-         * decision.addToContext(cntx); return Command.CONTINUE; }
-         */
-
-        // check if we have a matching rule for this packet/flow
-        // and no decision is taken yet
-        if (decision == null) {
-            RuleWildcardsPair match_ret = this.matchWithRule(sw, pi, cntx);
-            FirewallRule rule = match_ret.rule;
-
-            if (rule == null || rule.action == FirewallRule.FirewallAction.DENY) {
-                decision = new RoutingDecision(sw.getId(), pi.getInPort()
-                		, IDeviceService.fcStore.
-                        get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
-                        IRoutingDecision.RoutingAction.DROP);
-                decision.setWildcards(match_ret.wildcards);
-                decision.addToContext(cntx);
-                if (logger.isTraceEnabled()) {
-                    if (rule == null)
-                        logger.trace(
-                                "No firewall rule found for PacketIn={}, blocking flow",
-                                pi);
-                    else if (rule.action == FirewallRule.FirewallAction.DENY) {
-                        logger.trace("Deny rule={} match for PacketIn={}",
-                                rule, pi);
-                    }
-                }
-            } else {
-                decision = new RoutingDecision(sw.getId(), pi.getInPort()
-                		, IDeviceService.fcStore.
-                        get(cntx, IDeviceService.CONTEXT_SRC_DEVICE),
-                        IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-                decision.setWildcards(match_ret.wildcards);
-                decision.addToContext(cntx);
-                if (logger.isTraceEnabled())
-                    logger.trace("Allow rule={} match for PacketIn={}", rule,
-                            pi);
-            }
-        }
-
-        return Command.CONTINUE;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return enabled;
-    }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java
deleted file mode 100644
index 1f4d71a..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallResource.java
+++ /dev/null
@@ -1,125 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.io.IOException;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.restlet.resource.Post;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class FirewallResource extends ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(FirewallResource.class);
-    
-    @Get("json")
-    public Object handleRequest() {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        String op = (String) getRequestAttributes().get("op");
-
-        // REST API check status
-        if (op.equalsIgnoreCase("status")) {
-            if (firewall.isEnabled())
-                return "{\"result\" : \"firewall enabled\"}";
-            else
-                return "{\"result\" : \"firewall disabled\"}";
-        }
-
-        // REST API enable firewall
-        if (op.equalsIgnoreCase("enable")) {
-            firewall.enableFirewall(true);
-            return "{\"status\" : \"success\", \"details\" : \"firewall running\"}";
-        } 
-        
-        // REST API disable firewall
-        if (op.equalsIgnoreCase("disable")) {
-            firewall.enableFirewall(false);
-            return "{\"status\" : \"success\", \"details\" : \"firewall stopped\"}";
-        } 
-        
-        // REST API retrieving rules from storage
-        // currently equivalent to /wm/firewall/rules/json
-        if (op.equalsIgnoreCase("storageRules")) {
-            return firewall.getStorageRules();
-        } 
-        
-        // REST API set local subnet mask -- this only makes sense for one subnet
-        // will remove later
-        if (op.equalsIgnoreCase("subnet-mask")) {
-            return firewall.getSubnetMask();
-        }
-
-        // no known options found
-        return "{\"status\" : \"failure\", \"details\" : \"invalid operation\"}";
-    }
-    
-    /**
-     * Allows setting of subnet mask
-     * @param fmJson The Subnet Mask in JSON format.
-     * @return A string status message
-     */
-    @Post
-    public String handlePost(String fmJson) {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        String newMask;
-        try {
-            newMask = jsonExtractSubnetMask(fmJson);
-        } catch (IOException e) {
-            log.error("Error parsing new subnet mask: " + fmJson, e);
-            e.printStackTrace();
-            return "{\"status\" : \"Error! Could not parse new subnet mask, see log for details.\"}";
-        }
-        firewall.setSubnetMask(newMask);
-        return ("{\"status\" : \"subnet mask set\"}");
-    }
-    
-    /**
-     * Extracts subnet mask from a JSON string
-     * @param fmJson The JSON formatted string
-     * @return The subnet mask
-     * @throws IOException If there was an error parsing the JSON
-     */
-    public static String jsonExtractSubnetMask(String fmJson) throws IOException {
-        String subnet_mask = "";
-        MappingJsonFactory f = new MappingJsonFactory();
-        JsonParser jp;
-
-        try {
-            jp = f.createJsonParser(fmJson);
-        } catch (JsonParseException e) {
-            throw new IOException(e);
-        }
-
-        jp.nextToken();
-        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
-            throw new IOException("Expected START_OBJECT");
-        }
-
-        while (jp.nextToken() != JsonToken.END_OBJECT) {
-            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
-                throw new IOException("Expected FIELD_NAME");
-            }
-
-            String n = jp.getCurrentName();
-            jp.nextToken();
-            if (jp.getText().equals("")) 
-                continue;
-
-            if (n == "subnet-mask") {
-                subnet_mask = jp.getText();
-                break;
-            }
-        }
-
-        return subnet_mask;
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
deleted file mode 100644
index d9b2612..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRule.java
+++ /dev/null
@@ -1,392 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import org.openflow.protocol.OFMatch;
-
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.TCP;
-import net.floodlightcontroller.packet.UDP;
-
-public class FirewallRule implements Comparable<FirewallRule> {
-    public int ruleid;
-
-    public long dpid; 
-    public short in_port; 
-    public long dl_src; 
-    public long dl_dst; 
-    public short dl_type; 
-    public int nw_src_prefix; 
-    public int nw_src_maskbits;
-    public int nw_dst_prefix;
-    public int nw_dst_maskbits;
-    public short nw_proto;
-    public short tp_src;
-    public short tp_dst;
-
-    public boolean wildcard_dpid;
-    public boolean wildcard_in_port; 
-    public boolean wildcard_dl_src;
-    public boolean wildcard_dl_dst;
-    public boolean wildcard_dl_type;
-    public boolean wildcard_nw_src;
-    public boolean wildcard_nw_dst;
-    public boolean wildcard_nw_proto;
-    public boolean wildcard_tp_src;
-    public boolean wildcard_tp_dst;
-
-    public int priority = 0;
-
-    public FirewallAction action;
-
-    public enum FirewallAction {
-        /*
-         * DENY: Deny rule
-         * ALLOW: Allow rule
-         */
-        DENY, ALLOW
-    }
-
-    public FirewallRule() {
-        this.in_port = 0; 
-        this.dl_src = 0;
-        this.nw_src_prefix = 0;
-        this.nw_src_maskbits = 0; 
-        this.dl_dst = 0;
-        this.nw_proto = 0;
-        this.tp_src = 0;
-        this.tp_dst = 0;
-        this.dl_dst = 0;
-        this.nw_dst_prefix = 0;
-        this.nw_dst_maskbits = 0; 
-        this.dpid = -1;
-        this.wildcard_dpid = true; 
-        this.wildcard_in_port = true; 
-        this.wildcard_dl_src = true; 
-        this.wildcard_dl_dst = true; 
-        this.wildcard_dl_type = true; 
-        this.wildcard_nw_src = true; 
-        this.wildcard_nw_dst = true; 
-        this.wildcard_nw_proto = true; 
-        this.wildcard_tp_src = true; 
-        this.wildcard_tp_dst = true; 
-        this.priority = 0; 
-        this.action = FirewallAction.ALLOW; 
-        this.ruleid = 0; 
-    }
-
-    /**
-     * Generates a unique ID for the instance
-     * 
-     * @return int representing the unique id
-     */
-    public int genID() {
-        int uid = this.hashCode();
-        if (uid < 0) {
-            uid = Math.abs(uid);
-            uid = uid * 15551;
-        }
-        return uid;
-    }
-
-    /**
-     * Comparison method for Collections.sort method
-     * 
-     * @param rule
-     *            the rule to compare with
-     * @return number representing the result of comparison 0 if equal negative
-     *         if less than 'rule' greater than zero if greater priority rule
-     *         than 'rule'
-     */
-    @Override
-    public int compareTo(FirewallRule rule) {
-        return this.priority - rule.priority;
-    }
-
-    /**
-     * Determines if this instance matches an existing rule instance
-     * 
-     * @param r
-     *            : the FirewallRule instance to compare with
-     * @return boolean: true if a match is found
-     **/
-    public boolean isSameAs(FirewallRule r) {
-        if (this.action != r.action
-                || this.wildcard_dl_type != r.wildcard_dl_type
-                || (this.wildcard_dl_type == false && this.dl_type == r.dl_type)
-                || this.wildcard_tp_src != r.wildcard_tp_src
-                || (this.wildcard_tp_src == false && this.tp_src != r.tp_src)
-                || this.wildcard_tp_dst != r.wildcard_tp_dst
-                || (this.wildcard_tp_dst == false &&this.tp_dst != r.tp_dst)
-                || this.wildcard_dpid != r.wildcard_dpid
-                || (this.wildcard_dpid == false && this.dpid != r.dpid)
-                || this.wildcard_in_port != r.wildcard_in_port
-                || (this.wildcard_in_port == false && this.in_port != r.in_port)
-                || this.wildcard_nw_src != r.wildcard_nw_src
-                || (this.wildcard_nw_src == false && (this.nw_src_prefix != r.nw_src_prefix || this.nw_src_maskbits != r.nw_src_maskbits))
-                || this.wildcard_dl_src != r.wildcard_dl_src
-                || (this.wildcard_dl_src == false && this.dl_src != r.dl_src)
-                || this.wildcard_nw_proto != r.wildcard_nw_proto
-                || (this.wildcard_nw_proto == false && this.nw_proto != r.nw_proto)
-                || this.wildcard_nw_dst != r.wildcard_nw_dst
-                || (this.wildcard_nw_dst == false && (this.nw_dst_prefix != r.nw_dst_prefix || this.nw_dst_maskbits != r.nw_dst_maskbits))
-                || this.wildcard_dl_dst != r.wildcard_dl_dst                
-                || (this.wildcard_dl_dst == false && this.dl_dst != r.dl_dst)) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Matches this rule to a given flow - incoming packet
-     * 
-     * @param switchDpid
-     *            the Id of the connected switch
-     * @param inPort
-     *            the switch port where the packet originated from
-     * @param packet
-     *            the Ethernet packet that arrives at the switch
-     * @param wildcards
-     *            the pair of wildcards (allow and deny) given by Firewall
-     *            module that is used by the Firewall module's matchWithRule
-     *            method to derive wildcards for the decision to be taken
-     * @return true if the rule matches the given packet-in, false otherwise
-     */
-    public boolean matchesFlow(long switchDpid, short inPort, Ethernet packet,
-            WildcardsPair wildcards) {
-        IPacket pkt = packet.getPayload();
-
-        // dl_type type
-        IPv4 pkt_ip = null;
-
-        // nw_proto types
-        TCP pkt_tcp = null;
-        UDP pkt_udp = null;
-
-        // tp_src and tp_dst (tp port numbers)
-        short pkt_tp_src = 0;
-        short pkt_tp_dst = 0;
-
-        // switchID matches?
-        if (wildcard_dpid == false && dpid != switchDpid)
-            return false;
-
-        // in_port matches?
-        if (wildcard_in_port == false && in_port != inPort)
-            return false;
-        if (action == FirewallRule.FirewallAction.DENY) {
-            wildcards.drop &= ~OFMatch.OFPFW_IN_PORT;
-        } else {
-            wildcards.allow &= ~OFMatch.OFPFW_IN_PORT;
-        }
-
-        // mac address (src and dst) match?
-        if (wildcard_dl_src == false
-                && dl_src != packet.getSourceMAC().toLong())
-            return false;
-        if (action == FirewallRule.FirewallAction.DENY) {
-            wildcards.drop &= ~OFMatch.OFPFW_DL_SRC;
-        } else {
-            wildcards.allow &= ~OFMatch.OFPFW_DL_SRC;
-        }
-
-        if (wildcard_dl_dst == false
-                && dl_dst != packet.getDestinationMAC().toLong())
-            return false;
-        if (action == FirewallRule.FirewallAction.DENY) {
-            wildcards.drop &= ~OFMatch.OFPFW_DL_DST;
-        } else {
-            wildcards.allow &= ~OFMatch.OFPFW_DL_DST;
-        }
-
-        // dl_type check: ARP, IP
-
-        // if this is not an ARP rule but the pkt is ARP,
-        // return false match - no need to continue protocol specific check
-        if (wildcard_dl_type == false) {
-            if (dl_type == Ethernet.TYPE_ARP) {
-                if (packet.getEtherType() != Ethernet.TYPE_ARP)
-                    return false;
-                else {
-                    if (action == FirewallRule.FirewallAction.DENY) {
-                        wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
-                    } else {
-                        wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
-                    }
-                }
-            } else if (dl_type == Ethernet.TYPE_IPv4) {
-                if (packet.getEtherType() != Ethernet.TYPE_IPv4)
-                    return false;
-                else {
-                    if (action == FirewallRule.FirewallAction.DENY) {
-                        wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
-                    } else {
-                        wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
-                    }
-                    // IP packets, proceed with ip address check
-                    pkt_ip = (IPv4) pkt;
-
-                    // IP addresses (src and dst) match?
-                    if (wildcard_nw_src == false
-                            && this.matchIPAddress(nw_src_prefix,
-                                    nw_src_maskbits, pkt_ip.getSourceAddress()) == false)
-                        return false;
-                    if (action == FirewallRule.FirewallAction.DENY) {
-                        wildcards.drop &= ~OFMatch.OFPFW_NW_SRC_ALL;
-                        wildcards.drop |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
-                    } else {
-                        wildcards.allow &= ~OFMatch.OFPFW_NW_SRC_ALL;
-                        wildcards.allow |= (nw_src_maskbits << OFMatch.OFPFW_NW_SRC_SHIFT);
-                    }
-
-                    if (wildcard_nw_dst == false
-                            && this.matchIPAddress(nw_dst_prefix,
-                                    nw_dst_maskbits,
-                                    pkt_ip.getDestinationAddress()) == false)
-                        return false;
-                    if (action == FirewallRule.FirewallAction.DENY) {
-                        wildcards.drop &= ~OFMatch.OFPFW_NW_DST_ALL;
-                        wildcards.drop |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
-                    } else {
-                        wildcards.allow &= ~OFMatch.OFPFW_NW_DST_ALL;
-                        wildcards.allow |= (nw_dst_maskbits << OFMatch.OFPFW_NW_DST_SHIFT);
-                    }
-
-                    // nw_proto check
-                    if (wildcard_nw_proto == false) {
-                        if (nw_proto == IPv4.PROTOCOL_TCP) {
-                            if (pkt_ip.getProtocol() != IPv4.PROTOCOL_TCP)
-                                return false;
-                            else {
-                                pkt_tcp = (TCP) pkt_ip.getPayload();
-                                pkt_tp_src = pkt_tcp.getSourcePort();
-                                pkt_tp_dst = pkt_tcp.getDestinationPort();
-                            }
-                        } else if (nw_proto == IPv4.PROTOCOL_UDP) {
-                            if (pkt_ip.getProtocol() != IPv4.PROTOCOL_UDP)
-                                return false;
-                            else {
-                                pkt_udp = (UDP) pkt_ip.getPayload();
-                                pkt_tp_src = pkt_udp.getSourcePort();
-                                pkt_tp_dst = pkt_udp.getDestinationPort();
-                            }
-                        } else if (nw_proto == IPv4.PROTOCOL_ICMP) {
-                            if (pkt_ip.getProtocol() != IPv4.PROTOCOL_ICMP)
-                                return false;
-                            else {
-                                // nothing more needed for ICMP
-                            }
-                        }
-                        if (action == FirewallRule.FirewallAction.DENY) {
-                            wildcards.drop &= ~OFMatch.OFPFW_NW_PROTO;
-                        } else {
-                            wildcards.allow &= ~OFMatch.OFPFW_NW_PROTO;
-                        }
-
-                        // TCP/UDP source and destination ports match?
-                        if (pkt_tcp != null || pkt_udp != null) {
-                            // does the source port match?
-                            if (tp_src != 0 && tp_src != pkt_tp_src)
-                                return false;
-                            if (action == FirewallRule.FirewallAction.DENY) {
-                                wildcards.drop &= ~OFMatch.OFPFW_TP_SRC;
-                            } else {
-                                wildcards.allow &= ~OFMatch.OFPFW_TP_SRC;
-                            }
-
-                            // does the destination port match?
-                            if (tp_dst != 0 && tp_dst != pkt_tp_dst)
-                                return false;
-                            if (action == FirewallRule.FirewallAction.DENY) {
-                                wildcards.drop &= ~OFMatch.OFPFW_TP_DST;
-                            } else {
-                                wildcards.allow &= ~OFMatch.OFPFW_TP_DST;
-                            }
-                        }
-                    }
-
-                }
-            } else {
-                // non-IP packet - not supported - report no match
-                return false;
-            }
-        }
-        if (action == FirewallRule.FirewallAction.DENY) {
-            wildcards.drop &= ~OFMatch.OFPFW_DL_TYPE;
-        } else {
-            wildcards.allow &= ~OFMatch.OFPFW_DL_TYPE;
-        }
-
-        // all applicable checks passed
-        return true;
-    }
-
-    /**
-     * Determines if rule's CIDR address matches IP address of the packet
-     * 
-     * @param rulePrefix
-     *            prefix part of the CIDR address
-     * @param ruleBits
-     *            the size of mask of the CIDR address
-     * @param packetAddress
-     *            the IP address of the incoming packet to match with
-     * @return true if CIDR address matches the packet's IP address, false
-     *         otherwise
-     */
-    protected boolean matchIPAddress(int rulePrefix, int ruleBits,
-            int packetAddress) {
-        boolean matched = true;
-
-        int rule_iprng = 32 - ruleBits;
-        int rule_ipint = rulePrefix;
-        int pkt_ipint = packetAddress;
-        // if there's a subnet range (bits to be wildcarded > 0)
-        if (rule_iprng > 0) {
-            // right shift bits to remove rule_iprng of LSB that are to be
-            // wildcarded
-            rule_ipint = rule_ipint >> rule_iprng;
-            pkt_ipint = pkt_ipint >> rule_iprng;
-            // now left shift to return to normal range, except that the
-            // rule_iprng number of LSB
-            // are now zeroed
-            rule_ipint = rule_ipint << rule_iprng;
-            pkt_ipint = pkt_ipint << rule_iprng;
-        }
-        // check if we have a match
-        if (rule_ipint != pkt_ipint)
-            matched = false;
-
-        return matched;
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 2521;
-        int result = super.hashCode();
-        result = prime * result + (int) dpid;
-        result = prime * result + in_port;
-        result = prime * result + (int) dl_src;
-        result = prime * result + (int) dl_dst;
-        result = prime * result + dl_type;
-        result = prime * result + nw_src_prefix;
-        result = prime * result + nw_src_maskbits;
-        result = prime * result + nw_dst_prefix;
-        result = prime * result + nw_dst_maskbits;
-        result = prime * result + nw_proto;
-        result = prime * result + tp_src;
-        result = prime * result + tp_dst;
-        result = prime * result + action.ordinal();
-        result = prime * result + priority;
-        result = prime * result + (new Boolean(wildcard_dpid)).hashCode();
-        result = prime * result + (new Boolean(wildcard_in_port)).hashCode();
-        result = prime * result + (new Boolean(wildcard_dl_src)).hashCode();
-        result = prime * result + (new Boolean(wildcard_dl_dst)).hashCode();
-        result = prime * result + (new Boolean(wildcard_dl_type)).hashCode();
-        result = prime * result + (new Boolean(wildcard_nw_src)).hashCode();
-        result = prime * result + (new Boolean(wildcard_nw_dst)).hashCode();
-        result = prime * result + (new Boolean(wildcard_nw_proto)).hashCode();
-        result = prime * result + (new Boolean(wildcard_tp_src)).hashCode();
-        result = prime * result + (new Boolean(wildcard_tp_dst)).hashCode();
-        return result;
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java b/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java
deleted file mode 100644
index 7a31d38..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallRulesResource.java
+++ /dev/null
@@ -1,292 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.io.IOException;
-import java.util.Iterator;
-import java.util.List;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.openflow.util.HexString;
-import org.restlet.resource.Delete;
-import org.restlet.resource.Post;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPv4;
-
-public class FirewallRulesResource extends ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(FirewallRulesResource.class);
-
-    @Get("json")
-    public Object handleRequest() {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        return firewall.getRules();
-    }
-
-    /**
-     * Takes a Firewall Rule string in JSON format and parses it into
-     * our firewall rule data structure, then adds it to the firewall.
-     * @param fmJson The Firewall rule entry in JSON format.
-     * @return A string status message
-     */
-    @Post
-    public String store(String fmJson) {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        FirewallRule rule;
-        try {
-            rule = jsonToFirewallRule(fmJson);
-        } catch (IOException e) {
-            log.error("Error parsing firewall rule: " + fmJson, e);
-            e.printStackTrace();
-            return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
-        }
-        String status = null;
-        if (checkRuleExists(rule, firewall.getRules())) {
-            status = "Error! A similar firewall rule already exists.";
-            log.error(status);
-        } else {
-            // add rule to firewall
-            firewall.addRule(rule);
-            status = "Rule added";
-        }
-        return ("{\"status\" : \"" + status + "\"}");
-    }
-
-    /**
-     * Takes a Firewall Rule string in JSON format and parses it into
-     * our firewall rule data structure, then deletes it from the firewall.
-     * @param fmJson The Firewall rule entry in JSON format.
-     * @return A string status message
-     */
-    
-    @Delete
-    public String remove(String fmJson) {
-        IFirewallService firewall = 
-                (IFirewallService)getContext().getAttributes().
-                get(IFirewallService.class.getCanonicalName());
-
-        FirewallRule rule;
-        try {
-            rule = jsonToFirewallRule(fmJson);
-        } catch (IOException e) {
-            log.error("Error parsing firewall rule: " + fmJson, e);
-            e.printStackTrace();
-            return "{\"status\" : \"Error! Could not parse firewall rule, see log for details.\"}";
-        }
-        String status = null;
-        boolean exists = false;
-        Iterator<FirewallRule> iter = firewall.getRules().iterator();
-        while (iter.hasNext()) {
-            FirewallRule r = iter.next();
-            if (r.ruleid == rule.ruleid) {
-                exists = true;
-                break;
-            }
-        }
-        if (!exists) {
-            status = "Error! Can't delete, a rule with this ID doesn't exist.";
-            log.error(status);
-        } else {
-            // delete rule from firewall
-            firewall.deleteRule(rule.ruleid);
-            status = "Rule deleted";
-        }
-        return ("{\"status\" : \"" + status + "\"}");
-    }
-
-    /**
-     * Turns a JSON formatted Firewall Rule string into a FirewallRule instance
-     * @param fmJson The JSON formatted static firewall rule
-     * @return The FirewallRule instance
-     * @throws IOException If there was an error parsing the JSON
-     */
-     
-    public static FirewallRule jsonToFirewallRule(String fmJson) throws IOException {
-        FirewallRule rule = new FirewallRule();
-        MappingJsonFactory f = new MappingJsonFactory();
-        JsonParser jp;
-
-        try {
-            jp = f.createJsonParser(fmJson);
-        } catch (JsonParseException e) {
-            throw new IOException(e);
-        }
-
-        jp.nextToken();
-        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
-            throw new IOException("Expected START_OBJECT");
-        }
-
-        while (jp.nextToken() != JsonToken.END_OBJECT) {
-            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
-                throw new IOException("Expected FIELD_NAME");
-            }
-
-            String n = jp.getCurrentName();
-            jp.nextToken();
-            if (jp.getText().equals("")) 
-                continue;
-
-            String tmp;
-            
-            // This is currently only applicable for remove().  In store(), ruleid takes a random number
-            if (n == "ruleid") {
-                rule.ruleid = Integer.parseInt((String)jp.getText());
-            }
-            
-            // This assumes user having dpid info for involved switches
-            else if (n == "switchid") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("-1") == false) {
-                    // user inputs hex format dpid 
-                    rule.dpid = HexString.toLong(tmp);                    
-                    rule.wildcard_dpid = false;
-                }
-            } 
-            
-            else if (n == "src-inport") {
-                rule.in_port = Short.parseShort(jp.getText());
-                rule.wildcard_in_port = false;
-            } 
-            
-            else if (n == "src-mac") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ANY") == false) {
-                    rule.wildcard_dl_src = false;
-                    rule.dl_src = Ethernet.toLong(Ethernet.toMACAddress(tmp));
-                }
-            } 
-            
-            else if (n == "dst-mac") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ANY") == false) {
-                    rule.wildcard_dl_dst = false;
-                    rule.dl_dst = Ethernet.toLong(Ethernet.toMACAddress(tmp));
-                }
-            } 
-            
-            else if (n == "dl-type") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ARP")) {
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_ARP;
-                }
-            } 
-            
-            else if (n == "src-ip") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ANY") == false) {
-                    rule.wildcard_nw_src = false;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                    int[] cidr = IPCIDRToPrefixBits(tmp);
-                    rule.nw_src_prefix = cidr[0];
-                    rule.nw_src_maskbits = cidr[1];
-                }
-            } 
-            
-            else if (n == "dst-ip") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("ANY") == false) {
-                    rule.wildcard_nw_dst = false;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                    int[] cidr = IPCIDRToPrefixBits(tmp);
-                    rule.nw_dst_prefix = cidr[0];
-                    rule.nw_dst_maskbits = cidr[1];
-                }
-            } 
-            
-            else if (n == "nw-proto") {
-                tmp = jp.getText();
-                if (tmp.equalsIgnoreCase("TCP")) {
-                    rule.wildcard_nw_proto = false;
-                    rule.nw_proto = IPv4.PROTOCOL_TCP;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                } else if (tmp.equalsIgnoreCase("UDP")) {
-                    rule.wildcard_nw_proto = false;
-                    rule.nw_proto = IPv4.PROTOCOL_UDP;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                } else if (tmp.equalsIgnoreCase("ICMP")) {
-                    rule.wildcard_nw_proto = false;
-                    rule.nw_proto = IPv4.PROTOCOL_ICMP;
-                    rule.wildcard_dl_type = false;
-                    rule.dl_type = Ethernet.TYPE_IPv4;
-                } 
-            } 
-            
-            else if (n == "tp-src") {
-                rule.wildcard_tp_src = false;
-                rule.tp_src = Short.parseShort(jp.getText());
-            } 
-            
-            else if (n == "tp-dst") {
-                rule.wildcard_tp_dst = false;
-                rule.tp_dst = Short.parseShort(jp.getText());
-            } 
-            
-            else if (n == "priority") {
-                rule.priority = Integer.parseInt(jp.getText());
-            } 
-            
-            else if (n == "action") {
-                if (jp.getText().equalsIgnoreCase("allow") == true) {
-                    rule.action = FirewallRule.FirewallAction.ALLOW;
-                } else if (jp.getText().equalsIgnoreCase("deny") == true) {
-                    rule.action = FirewallRule.FirewallAction.DENY;
-                }
-            }
-        }
-
-        return rule;
-    }
-
-    public static int[] IPCIDRToPrefixBits(String cidr) {
-        int ret[] = new int[2];
-
-        // as IP can also be a prefix rather than an absolute address
-        // split it over "/" to get the bit range
-        String[] parts = cidr.split("/");
-        String cidr_prefix = parts[0].trim();
-        int cidr_bits = 0;
-        if (parts.length == 2) {
-            try {
-                cidr_bits = Integer.parseInt(parts[1].trim());
-            } catch (Exception exp) {
-                cidr_bits = 32;
-            }
-        }
-        ret[0] = IPv4.toIPv4Address(cidr_prefix);
-        ret[1] = cidr_bits;
-
-        return ret;
-    }
-
-    public static boolean checkRuleExists(FirewallRule rule, List<FirewallRule> rules) {
-        Iterator<FirewallRule> iter = rules.iterator();
-        while (iter.hasNext()) {
-            FirewallRule r = iter.next();
-
-            // check if we find a similar rule
-            if (rule.isSameAs(r)) {
-                return true;
-            }
-        }
-
-        // no rule matched, so it doesn't exist in the rules
-        return false;
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/FirewallWebRoutable.java b/src/main/java/net/floodlightcontroller/firewall/FirewallWebRoutable.java
deleted file mode 100644
index 3a9beab..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/FirewallWebRoutable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-import org.restlet.Context;
-import org.restlet.routing.Router;
-
-public class FirewallWebRoutable implements RestletRoutable {
-    /**
-     * Create the Restlet router and bind to the proper resources.
-     */
-    @Override
-    public Router getRestlet(Context context) {
-        Router router = new Router(context);
-        router.attach("/module/{op}/json", FirewallResource.class);
-        router.attach("/rules/json", FirewallRulesResource.class);
-        return router;
-    }
-
-    /**
-     * Set the base path for the Firewall
-     */
-    @Override
-    public String basePath() {
-        return "/wm/firewall";
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/IFirewallService.java b/src/main/java/net/floodlightcontroller/firewall/IFirewallService.java
deleted file mode 100644
index ae9d89f..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/IFirewallService.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public interface IFirewallService extends IFloodlightService {
-
-    /**
-     * Enables/disables the firewall.
-     * @param enable Whether to enable or disable the firewall.
-     */
-    public void enableFirewall(boolean enable);
-
-    /**
-     * Returns operational status of the firewall
-     * @return boolean enabled;
-     */
-    public boolean isEnabled();
- 
-    /**
-     * Returns all of the firewall rules
-     * @return List of all rules
-     */
-    public List<FirewallRule> getRules();
-    
-    /**
-     * Returns the subnet mask
-     * @return subnet mask
-     */
-    public String getSubnetMask();
-    
-    /**
-     * Sets the subnet mask
-     * @param newMask The new subnet mask
-     */
-    public void setSubnetMask(String newMask);
-
-    /**
-     * Returns all of the firewall rules in storage
-     * for debugging and unit-testing purposes
-     * @return List of all rules in storage
-     */
-    public List<Map<String, Object>> getStorageRules();
-
-    /**
-     * Adds a new Firewall rule
-     */
-    public void addRule(FirewallRule rule);
-
-    /**
-     * Deletes a Firewall rule
-     */
-    public void deleteRule(int ruleid);
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/RuleWildcardsPair.java b/src/main/java/net/floodlightcontroller/firewall/RuleWildcardsPair.java
deleted file mode 100644
index 3fab409..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/RuleWildcardsPair.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import org.openflow.protocol.OFMatch;
-
-public class RuleWildcardsPair {
-    public FirewallRule rule;
-    public int wildcards = OFMatch.OFPFW_ALL;
-}
diff --git a/src/main/java/net/floodlightcontroller/firewall/WildcardsPair.java b/src/main/java/net/floodlightcontroller/firewall/WildcardsPair.java
deleted file mode 100644
index 2e5f123..0000000
--- a/src/main/java/net/floodlightcontroller/firewall/WildcardsPair.java
+++ /dev/null
@@ -1,8 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import org.openflow.protocol.OFMatch;
-
-public class WildcardsPair {
-    public int allow = OFMatch.OFPFW_ALL;
-    public int drop = OFMatch.OFPFW_ALL;
-}
diff --git a/src/main/java/net/floodlightcontroller/hub/Hub.java b/src/main/java/net/floodlightcontroller/hub/Hub.java
deleted file mode 100644
index 3618351..0000000
--- a/src/main/java/net/floodlightcontroller/hub/Hub.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    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 net.floodlightcontroller.hub;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Map;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.util.U16;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu) - 04/04/10
- */
-public class Hub implements IFloodlightModule, IOFMessageListener {
-    protected static Logger log = LoggerFactory.getLogger(Hub.class);
-
-    protected IFloodlightProviderService floodlightProvider;
-
-    /**
-     * @param floodlightProvider the floodlightProvider to set
-     */
-    public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
-        this.floodlightProvider = floodlightProvider;
-    }
-
-    @Override
-    public String getName() {
-        return Hub.class.getPackage().getName();
-    }
-
-    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-        OFPacketIn pi = (OFPacketIn) msg;
-        OFPacketOut po = (OFPacketOut) floodlightProvider.getOFMessageFactory()
-                .getMessage(OFType.PACKET_OUT);
-        po.setBufferId(pi.getBufferId())
-            .setInPort(pi.getInPort());
-
-        // set actions
-        OFActionOutput action = new OFActionOutput()
-            .setPort((short) OFPort.OFPP_FLOOD.getValue());
-        po.setActions(Collections.singletonList((OFAction)action));
-        po.setActionsLength((short) OFActionOutput.MINIMUM_LENGTH);
-
-        // set data if is is included in the packetin
-        if (pi.getBufferId() == 0xffffffff) {
-            byte[] packetData = pi.getPacketData();
-            po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH
-                    + po.getActionsLength() + packetData.length));
-            po.setPacketData(packetData);
-        } else {
-            po.setLength(U16.t(OFPacketOut.MINIMUM_LENGTH
-                    + po.getActionsLength()));
-        }
-        try {
-            sw.write(po, cntx);
-        } catch (IOException e) {
-            log.error("Failure writing PacketOut", e);
-        }
-
-        return Command.CONTINUE;
-    }
-
-    @Override
-    public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        return false;
-    }
-
-    @Override
-    public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        return false;
-    }
-
-    // IFloodlightModule
-    
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        // We don't provide any services, return null
-        return null;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService>
-            getServiceImpls() {
-        // We don't provide any services, return null
-        return null;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>>
-            getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFloodlightProviderService.class);
-        return l;
-    }
-
-    @Override
-    public void init(FloodlightModuleContext context)
-            throws FloodlightModuleException {
-        floodlightProvider =
-                context.getServiceImpl(IFloodlightProviderService.class);
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/jython/JythonDebugInterface.java b/src/main/java/net/floodlightcontroller/jython/JythonDebugInterface.java
deleted file mode 100644
index 19a97b5..0000000
--- a/src/main/java/net/floodlightcontroller/jython/JythonDebugInterface.java
+++ /dev/null
@@ -1,68 +0,0 @@
-package net.floodlightcontroller.jython;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public class JythonDebugInterface implements IFloodlightModule {
-    protected static Logger log = LoggerFactory.getLogger(JythonDebugInterface.class);
-    protected JythonServer debug_server;
-    protected static int JYTHON_PORT = 6655;
-    
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        // We don't export services
-        return null;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService>
-            getServiceImpls() {
-        // We don't export services
-        return null;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>>
-            getModuleDependencies() {
-        // We don't have any dependencies
-        return null;
-    }
-
-    @Override
-    public void init(FloodlightModuleContext context)
-             throws FloodlightModuleException {
-        // no-op
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-        Map<String, Object> locals = new HashMap<String, Object>();     
-        // add all existing module references to the debug server
-        for (Class<? extends IFloodlightService> s : context.getAllServices()) {
-            // Put only the last part of the name
-            String[] bits = s.getCanonicalName().split("\\.");
-            String name = bits[bits.length-1];
-            locals.put(name, context.getServiceImpl(s));
-        }
-        
-        // read our config options
-        Map<String, String> configOptions = context.getConfigParams(this);
-        int port = JYTHON_PORT;
-        String portNum = configOptions.get("port");
-        if (portNum != null) {
-            port = Integer.parseInt(portNum);
-        }
-        
-        JythonServer debug_server = new JythonServer(port, locals);
-        debug_server.start();
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/jython/JythonServer.java b/src/main/java/net/floodlightcontroller/jython/JythonServer.java
deleted file mode 100644
index fc35b15..0000000
--- a/src/main/java/net/floodlightcontroller/jython/JythonServer.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package net.floodlightcontroller.jython;
-
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.python.util.PythonInterpreter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * This class starts a thread that runs a jython interpreter that
- * can be used for debug (or even development).
- *
- * @author mandeepdhami
- *
- */
-public class JythonServer extends Thread {
-    protected static Logger log = LoggerFactory.getLogger(JythonServer.class);
-
-	int port;
-	Map<String, Object> locals;
-	
-	/**
-	 * @param port_ Port to use for jython server
-	 * @param locals_ Locals to add to the interpreters top level name space
-	 */
-	public JythonServer(int port_, Map<String, Object> locals_) {
-		this.port = port_ ;
-		this.locals = locals_;
-		if (this.locals == null) {
-			this.locals = new HashMap<String, Object>();
-		}
-		this.locals.put("log", JythonServer.log);
-		this.setName("debugserver");
-	}
-
-    /**
-     * The main thread for this class invoked by Thread.run()
-     *
-     * @see java.lang.Thread#run()
-     */
-    public void run() {
-        PythonInterpreter p = new PythonInterpreter();
-        for (String name : this.locals.keySet()) {
-            p.set(name, this.locals.get(name));
-        }
-
-        URL jarUrl = JythonServer.class.getProtectionDomain().getCodeSource().getLocation();
-        String jarPath = jarUrl.getPath();
-        if (jarUrl.getProtocol().equals("file")) {
-            // If URL is of type file, assume that we are in dev env and set path to python dir.
-            // else use the jar file as is
-            jarPath = jarPath + "../../src/main/python/";
-        }
-
-        p.exec("import sys");
-        p.exec("sys.path.append('" + jarPath + "')");
-        p.exec("from debugserver import run_server");
-        p.exec("run_server(" + this.port + ", '0.0.0.0', locals())");
-    }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/ILearningSwitchService.java b/src/main/java/net/floodlightcontroller/learningswitch/ILearningSwitchService.java
deleted file mode 100644
index 71f6625..0000000
--- a/src/main/java/net/floodlightcontroller/learningswitch/ILearningSwitchService.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package net.floodlightcontroller.learningswitch;
-
-import java.util.Map;
-
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.types.MacVlanPair;
-
-public interface ILearningSwitchService extends IFloodlightService {
-    /**
-     * Returns the LearningSwitch's learned host table
-     * @return The learned host table
-     */
-    public Map<IOFSwitch, Map<MacVlanPair,Short>> getTable();
-}
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
deleted file mode 100644
index 005708d..0000000
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java
+++ /dev/null
@@ -1,508 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    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.
-**/
-
-/**
- * Floodlight
- * A BSD licensed, Java based OpenFlow controller
- *
- * Floodlight is a Java based OpenFlow controller originally written by David Erickson at Stanford
- * University. It is available under the BSD license.
- *
- * For documentation, forums, issue tracking and more visit:
- *
- * http://www.openflowhub.org/display/Floodlight/Floodlight+Home
- **/
-
-package net.floodlightcontroller.learningswitch;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.types.MacVlanPair;
-import net.floodlightcontroller.counter.ICounterStoreService;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.restserver.IRestApiService;
-
-import org.openflow.protocol.OFError;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFFlowRemoved;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.util.HexString;
-import org.openflow.util.LRULinkedHashMap;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class LearningSwitch 
-    implements IFloodlightModule, ILearningSwitchService, IOFMessageListener {
-    protected static Logger log = LoggerFactory.getLogger(LearningSwitch.class);
-    
-    // Module dependencies
-    protected IFloodlightProviderService floodlightProvider;
-    protected ICounterStoreService counterStore;
-    protected IRestApiService restApi;
-    
-    // Stores the learned state for each switch
-    protected Map<IOFSwitch, Map<MacVlanPair,Short>> macVlanToSwitchPortMap;
-
-    // flow-mod - for use in the cookie
-    public static final int LEARNING_SWITCH_APP_ID = 1;
-    // LOOK! This should probably go in some class that encapsulates
-    // the app cookie management
-    public static final int APP_ID_BITS = 12;
-    public static final int APP_ID_SHIFT = (64 - APP_ID_BITS);
-    public static final long LEARNING_SWITCH_COOKIE = (long) (LEARNING_SWITCH_APP_ID & ((1 << APP_ID_BITS) - 1)) << APP_ID_SHIFT;
-    
-    // more flow-mod defaults 
-    protected static final short IDLE_TIMEOUT_DEFAULT = 5;
-    protected static final short HARD_TIMEOUT_DEFAULT = 0;
-    protected static final short PRIORITY_DEFAULT = 100;
-    
-    // for managing our map sizes
-    protected static final int MAX_MACS_PER_SWITCH  = 1000;    
-
-    // normally, setup reverse flow as well. Disable only for using cbench for comparison with NOX etc.
-    protected static final boolean LEARNING_SWITCH_REVERSE_FLOW = true;
-    
-    /**
-     * @param floodlightProvider the floodlightProvider to set
-     */
-    public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
-        this.floodlightProvider = floodlightProvider;
-    }
-    
-    @Override
-    public String getName() {
-        return "learningswitch";
-    }
-
-    /**
-     * Adds a host to the MAC/VLAN->SwitchPort mapping
-     * @param sw The switch to add the mapping to
-     * @param mac The MAC address of the host to add
-     * @param vlan The VLAN that the host is on
-     * @param portVal The switchport that the host is on
-     */
-    protected void addToPortMap(IOFSwitch sw, long mac, short vlan, short portVal) {
-        Map<MacVlanPair,Short> swMap = macVlanToSwitchPortMap.get(sw);
-        
-        if (vlan == (short) 0xffff) {
-            // OFMatch.loadFromPacket sets VLAN ID to 0xffff if the packet contains no VLAN tag;
-            // for our purposes that is equivalent to the default VLAN ID 0
-            vlan = 0;
-        }
-        
-        if (swMap == null) {
-            // May be accessed by REST API so we need to make it thread safe
-            swMap = Collections.synchronizedMap(new LRULinkedHashMap<MacVlanPair,Short>(MAX_MACS_PER_SWITCH));
-            macVlanToSwitchPortMap.put(sw, swMap);
-        }
-        swMap.put(new MacVlanPair(mac, vlan), portVal);
-    }
-    
-    /**
-     * Removes a host from the MAC/VLAN->SwitchPort mapping
-     * @param sw The switch to remove the mapping from
-     * @param mac The MAC address of the host to remove
-     * @param vlan The VLAN that the host is on
-     */
-    protected void removeFromPortMap(IOFSwitch sw, long mac, short vlan) {
-        if (vlan == (short) 0xffff) {
-            vlan = 0;
-        }
-        Map<MacVlanPair,Short> swMap = macVlanToSwitchPortMap.get(sw);
-        if (swMap != null)
-            swMap.remove(new MacVlanPair(mac, vlan));
-    }
-
-    /**
-     * Get the port that a MAC/VLAN pair is associated with
-     * @param sw The switch to get the mapping from
-     * @param mac The MAC address to get
-     * @param vlan The VLAN number to get
-     * @return The port the host is on
-     */
-    public Short getFromPortMap(IOFSwitch sw, long mac, short vlan) {
-        if (vlan == (short) 0xffff) {
-            vlan = 0;
-        }
-        Map<MacVlanPair,Short> swMap = macVlanToSwitchPortMap.get(sw);
-        if (swMap != null)
-            return swMap.get(new MacVlanPair(mac, vlan));
-        
-        // if none found
-        return null;
-    }
-    
-    /**
-     * Clears the MAC/VLAN -> SwitchPort map for all switches
-     */
-    public void clearLearnedTable() {
-        macVlanToSwitchPortMap.clear();
-    }
-    
-    /**
-     * Clears the MAC/VLAN -> SwitchPort map for a single switch
-     * @param sw The switch to clear the mapping for
-     */
-    public void clearLearnedTable(IOFSwitch sw) {
-        Map<MacVlanPair, Short> swMap = macVlanToSwitchPortMap.get(sw);
-        if (swMap != null)
-            swMap.clear();
-    }
-    
-    @Override
-    public synchronized Map<IOFSwitch, Map<MacVlanPair,Short>> getTable() {
-        return macVlanToSwitchPortMap;
-    }
-    
-    /**
-     * Writes a OFFlowMod to a switch.
-     * @param sw The switch tow rite the flowmod to.
-     * @param command The FlowMod actions (add, delete, etc).
-     * @param bufferId The buffer ID if the switch has buffered the packet.
-     * @param match The OFMatch structure to write.
-     * @param outPort The switch port to output it to.
-     */
-    private void writeFlowMod(IOFSwitch sw, short command, int bufferId,
-            OFMatch match, short outPort) {
-        // from openflow 1.0 spec - need to set these on a struct ofp_flow_mod:
-        // struct ofp_flow_mod {
-        //    struct ofp_header header;
-        //    struct ofp_match match; /* Fields to match */
-        //    uint64_t cookie; /* Opaque controller-issued identifier. */
-        //
-        //    /* Flow actions. */
-        //    uint16_t command; /* One of OFPFC_*. */
-        //    uint16_t idle_timeout; /* Idle time before discarding (seconds). */
-        //    uint16_t hard_timeout; /* Max time before discarding (seconds). */
-        //    uint16_t priority; /* Priority level of flow entry. */
-        //    uint32_t buffer_id; /* Buffered packet to apply to (or -1).
-        //                           Not meaningful for OFPFC_DELETE*. */
-        //    uint16_t out_port; /* For OFPFC_DELETE* commands, require
-        //                          matching entries to include this as an
-        //                          output port. A value of OFPP_NONE
-        //                          indicates no restriction. */
-        //    uint16_t flags; /* One of OFPFF_*. */
-        //    struct ofp_action_header actions[0]; /* The action length is inferred
-        //                                            from the length field in the
-        //                                            header. */
-        //    };
-           
-        OFFlowMod flowMod = (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
-        flowMod.setMatch(match);
-        flowMod.setCookie(LearningSwitch.LEARNING_SWITCH_COOKIE);
-        flowMod.setCommand(command);
-        flowMod.setIdleTimeout(LearningSwitch.IDLE_TIMEOUT_DEFAULT);
-        flowMod.setHardTimeout(LearningSwitch.HARD_TIMEOUT_DEFAULT);
-        flowMod.setPriority(LearningSwitch.PRIORITY_DEFAULT);
-        flowMod.setBufferId(bufferId);
-        flowMod.setOutPort((command == OFFlowMod.OFPFC_DELETE) ? outPort : OFPort.OFPP_NONE.getValue());
-        flowMod.setFlags((command == OFFlowMod.OFPFC_DELETE) ? 0 : (short) (1 << 0)); // OFPFF_SEND_FLOW_REM
-
-        // set the ofp_action_header/out actions:
-        // from the openflow 1.0 spec: need to set these on a struct ofp_action_output:
-        // uint16_t type; /* OFPAT_OUTPUT. */
-        // uint16_t len; /* Length is 8. */
-        // uint16_t port; /* Output port. */
-        // uint16_t max_len; /* Max length to send to controller. */
-        // type/len are set because it is OFActionOutput,
-        // and port, max_len are arguments to this constructor
-        flowMod.setActions(Arrays.asList((OFAction) new OFActionOutput(outPort, (short) 0xffff)));
-        flowMod.setLength((short) (OFFlowMod.MINIMUM_LENGTH + OFActionOutput.MINIMUM_LENGTH));
-
-        if (log.isTraceEnabled()) {
-            log.trace("{} {} flow mod {}", 
-                      new Object[]{ sw, (command == OFFlowMod.OFPFC_DELETE) ? "deleting" : "adding", flowMod });
-        }
-
-        counterStore.updatePktOutFMCounterStore(sw, flowMod);
-        
-        // and write it out
-        try {
-            sw.write(flowMod, null);
-        } catch (IOException e) {
-            log.error("Failed to write {} to switch {}", new Object[]{ flowMod, sw }, e);
-        }
-    }
-    
-    /**
-     * Writes an OFPacketOut message to a switch.
-     * @param sw The switch to write the PacketOut to.
-     * @param packetInMessage The corresponding PacketIn.
-     * @param egressPort The switchport to output the PacketOut.
-     */
-    private void writePacketOutForPacketIn(IOFSwitch sw, 
-                                          OFPacketIn packetInMessage, 
-                                          short egressPort) {
-        // from openflow 1.0 spec - need to set these on a struct ofp_packet_out:
-        // uint32_t buffer_id; /* ID assigned by datapath (-1 if none). */
-        // uint16_t in_port; /* Packet's input port (OFPP_NONE if none). */
-        // uint16_t actions_len; /* Size of action array in bytes. */
-        // struct ofp_action_header actions[0]; /* Actions. */
-        /* uint8_t data[0]; */ /* Packet data. The length is inferred
-                                  from the length field in the header.
-                                  (Only meaningful if buffer_id == -1.) */
-        
-        OFPacketOut packetOutMessage = (OFPacketOut) floodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT);
-        short packetOutLength = (short)OFPacketOut.MINIMUM_LENGTH; // starting length
-
-        // Set buffer_id, in_port, actions_len
-        packetOutMessage.setBufferId(packetInMessage.getBufferId());
-        packetOutMessage.setInPort(packetInMessage.getInPort());
-        packetOutMessage.setActionsLength((short)OFActionOutput.MINIMUM_LENGTH);
-        packetOutLength += OFActionOutput.MINIMUM_LENGTH;
-        
-        // set actions
-        List<OFAction> actions = new ArrayList<OFAction>(1);      
-        actions.add(new OFActionOutput(egressPort, (short) 0));
-        packetOutMessage.setActions(actions);
-
-        // set data - only if buffer_id == -1
-        if (packetInMessage.getBufferId() == OFPacketOut.BUFFER_ID_NONE) {
-            byte[] packetData = packetInMessage.getPacketData();
-            packetOutMessage.setPacketData(packetData); 
-            packetOutLength += (short)packetData.length;
-        }
-        
-        // finally, set the total length
-        packetOutMessage.setLength(packetOutLength);              
-            
-        // and write it out
-        try {
-        	counterStore.updatePktOutFMCounterStore(sw, packetOutMessage);
-            sw.write(packetOutMessage, null);
-        } catch (IOException e) {
-            log.error("Failed to write {} to switch {}: {}", new Object[]{ packetOutMessage, sw, e });
-        }
-    }
-    
-    /**
-     * Processes a OFPacketIn message. If the switch has learned the MAC/VLAN to port mapping
-     * for the pair it will write a FlowMod for. If the mapping has not been learned the 
-     * we will flood the packet.
-     * @param sw
-     * @param pi
-     * @param cntx
-     * @return
-     */
-    private Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
-        // Read in packet data headers by using OFMatch
-        OFMatch match = new OFMatch();
-        match.loadFromPacket(pi.getPacketData(), pi.getInPort());
-        Long sourceMac = Ethernet.toLong(match.getDataLayerSource());
-        Long destMac = Ethernet.toLong(match.getDataLayerDestination());
-        Short vlan = match.getDataLayerVirtualLan();
-        if ((destMac & 0xfffffffffff0L) == 0x0180c2000000L) {
-            if (log.isTraceEnabled()) {
-                log.trace("ignoring packet addressed to 802.1D/Q reserved addr: switch {} vlan {} dest MAC {}",
-                          new Object[]{ sw, vlan, HexString.toHexString(destMac) });
-            }
-            return Command.STOP;
-        }
-        if ((sourceMac & 0x010000000000L) == 0) {
-            // If source MAC is a unicast address, learn the port for this MAC/VLAN
-            this.addToPortMap(sw, sourceMac, vlan, pi.getInPort());
-        }
-        
-        // Now output flow-mod and/or packet
-        Short outPort = getFromPortMap(sw, destMac, vlan);
-        if (outPort == null) {
-            // If we haven't learned the port for the dest MAC/VLAN, flood it
-            // Don't flood broadcast packets if the broadcast is disabled.
-            // XXX For LearningSwitch this doesn't do much. The sourceMac is removed
-            //     from port map whenever a flow expires, so you would still see
-            //     a lot of floods.
-            this.writePacketOutForPacketIn(sw, pi, OFPort.OFPP_FLOOD.getValue());
-        } else if (outPort == match.getInputPort()) {
-            log.trace("ignoring packet that arrived on same port as learned destination:"
-                    + " switch {} vlan {} dest MAC {} port {}",
-                    new Object[]{ sw, vlan, HexString.toHexString(destMac), outPort });
-        } else {
-            // Add flow table entry matching source MAC, dest MAC, VLAN and input port
-            // that sends to the port we previously learned for the dest MAC/VLAN.  Also
-            // add a flow table entry with source and destination MACs reversed, and
-            // input and output ports reversed.  When either entry expires due to idle
-            // timeout, remove the other one.  This ensures that if a device moves to
-            // a different port, a constant stream of packets headed to the device at
-            // its former location does not keep the stale entry alive forever.
-            // FIXME: current HP switches ignore DL_SRC and DL_DST fields, so we have to match on
-            // NW_SRC and NW_DST as well
-            match.setWildcards(((Integer)sw.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).intValue()
-                    & ~OFMatch.OFPFW_IN_PORT
-                    & ~OFMatch.OFPFW_DL_VLAN & ~OFMatch.OFPFW_DL_SRC & ~OFMatch.OFPFW_DL_DST
-                    & ~OFMatch.OFPFW_NW_SRC_MASK & ~OFMatch.OFPFW_NW_DST_MASK);
-            this.writeFlowMod(sw, OFFlowMod.OFPFC_ADD, pi.getBufferId(), match, outPort);
-            if (LEARNING_SWITCH_REVERSE_FLOW) {
-                this.writeFlowMod(sw, OFFlowMod.OFPFC_ADD, -1, match.clone()
-                    .setDataLayerSource(match.getDataLayerDestination())
-                    .setDataLayerDestination(match.getDataLayerSource())
-                    .setNetworkSource(match.getNetworkDestination())
-                    .setNetworkDestination(match.getNetworkSource())
-                    .setTransportSource(match.getTransportDestination())
-                    .setTransportDestination(match.getTransportSource())
-                    .setInputPort(outPort),
-                    match.getInputPort());
-            }
-        }
-        return Command.CONTINUE;
-    }
-
-    /**
-     * Processes a flow removed message. We will delete the learned MAC/VLAN mapping from
-     * the switch's table.
-     * @param sw The switch that sent the flow removed message.
-     * @param flowRemovedMessage The flow removed message.
-     * @return Whether to continue processing this message or stop.
-     */
-    private Command processFlowRemovedMessage(IOFSwitch sw, OFFlowRemoved flowRemovedMessage) {
-        if (flowRemovedMessage.getCookie() != LearningSwitch.LEARNING_SWITCH_COOKIE) {
-            return Command.CONTINUE;
-        }
-        if (log.isTraceEnabled()) {
-            log.trace("{} flow entry removed {}", sw, flowRemovedMessage);
-        }
-        OFMatch match = flowRemovedMessage.getMatch();
-        // When a flow entry expires, it means the device with the matching source
-        // MAC address and VLAN either stopped sending packets or moved to a different
-        // port.  If the device moved, we can't know where it went until it sends
-        // another packet, allowing us to re-learn its port.  Meanwhile we remove
-        // it from the macVlanToPortMap to revert to flooding packets to this device.
-        this.removeFromPortMap(sw, Ethernet.toLong(match.getDataLayerSource()),
-            match.getDataLayerVirtualLan());
-        
-        // Also, if packets keep coming from another device (e.g. from ping), the
-        // corresponding reverse flow entry will never expire on its own and will
-        // send the packets to the wrong port (the matching input port of the
-        // expired flow entry), so we must delete the reverse entry explicitly.
-        this.writeFlowMod(sw, OFFlowMod.OFPFC_DELETE, -1, match.clone()
-                .setWildcards(((Integer)sw.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).intValue()
-                        & ~OFMatch.OFPFW_DL_VLAN & ~OFMatch.OFPFW_DL_SRC & ~OFMatch.OFPFW_DL_DST
-                        & ~OFMatch.OFPFW_NW_SRC_MASK & ~OFMatch.OFPFW_NW_DST_MASK)
-                .setDataLayerSource(match.getDataLayerDestination())
-                .setDataLayerDestination(match.getDataLayerSource())
-                .setNetworkSource(match.getNetworkDestination())
-                .setNetworkDestination(match.getNetworkSource())
-                .setTransportSource(match.getTransportDestination())
-                .setTransportDestination(match.getTransportSource()),
-                match.getInputPort());
-        return Command.CONTINUE;
-    }
-    
-    // IOFMessageListener
-    
-    @Override
-    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-        switch (msg.getType()) {
-            case PACKET_IN:
-                return this.processPacketInMessage(sw, (OFPacketIn) msg, cntx);
-            case FLOW_REMOVED:
-                return this.processFlowRemovedMessage(sw, (OFFlowRemoved) msg);
-            case ERROR:
-                log.info("received an error {} from switch {}", (OFError) msg, sw);
-                return Command.CONTINUE;
-            default:
-            	break;
-        }
-        log.error("received an unexpected message {} from switch {}", msg, sw);
-        return Command.CONTINUE;
-    }
-
-    @Override
-    public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        return false;
-    }
-
-    @Override
-    public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        return false;
-    }
-
-    // IFloodlightModule
-    
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(ILearningSwitchService.class);
-        return l;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService>
-            getServiceImpls() {
-        Map<Class<? extends IFloodlightService>,
-            IFloodlightService> m = 
-                new HashMap<Class<? extends IFloodlightService>,
-                    IFloodlightService>();
-        m.put(ILearningSwitchService.class, this);
-        return m;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>>
-            getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFloodlightProviderService.class);
-        l.add(ICounterStoreService.class);
-        l.add(IRestApiService.class);
-        return l;
-    }
-
-    @Override
-    public void init(FloodlightModuleContext context)
-            throws FloodlightModuleException {
-        macVlanToSwitchPortMap = 
-                new ConcurrentHashMap<IOFSwitch, Map<MacVlanPair,Short>>();
-        floodlightProvider =
-                context.getServiceImpl(IFloodlightProviderService.class);
-        counterStore =
-                context.getServiceImpl(ICounterStoreService.class);
-        restApi =
-                context.getServiceImpl(IRestApiService.class);
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-        floodlightProvider.addOFMessageListener(OFType.FLOW_REMOVED, this);
-        floodlightProvider.addOFMessageListener(OFType.ERROR, this);
-        restApi.addRestletRoutable(new LearningSwitchWebRoutable());
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchTable.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchTable.java
deleted file mode 100644
index 19f8bf5..0000000
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchTable.java
+++ /dev/null
@@ -1,69 +0,0 @@
-package net.floodlightcontroller.learningswitch;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.types.MacVlanPair;
-
-import org.openflow.util.HexString;
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class LearningSwitchTable extends ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(LearningSwitchTable.class);
-    
-    protected Map<String, Object> formatTableEntry(MacVlanPair key, short port) {
-        Map<String, Object> entry = new HashMap<String, Object>();
-        entry.put("mac", HexString.toHexString(key.mac));
-        entry.put("vlan", key.vlan);
-        entry.put("port", port);
-        return entry;
-    }
-    
-    protected List<Map<String, Object>> getOneSwitchTable(Map<MacVlanPair, Short> switchMap) {
-        List<Map<String, Object>> switchTable = new ArrayList<Map<String, Object>>();
-        for (Entry<MacVlanPair, Short> entry : switchMap.entrySet()) {
-            switchTable.add(formatTableEntry(entry.getKey(), entry.getValue()));
-        }
-        return switchTable;
-    }
-    
-    @Get("json")
-    public Map<String, List<Map<String, Object>>> getSwitchTableJson() {
-        ILearningSwitchService lsp = 
-                (ILearningSwitchService)getContext().getAttributes().
-                    get(ILearningSwitchService.class.getCanonicalName());
-
-        Map<IOFSwitch, Map<MacVlanPair,Short>> table = lsp.getTable();
-        Map<String, List<Map<String, Object>>> allSwitchTableJson = new HashMap<String, List<Map<String, Object>>>();
-        
-        String switchId = (String) getRequestAttributes().get("switch");
-        if (switchId.toLowerCase().equals("all")) {
-            for (IOFSwitch sw : table.keySet()) {
-                allSwitchTableJson.put(HexString.toHexString(sw.getId()), getOneSwitchTable(table.get(sw)));
-            }
-        } else {
-            try {
-                IFloodlightProviderService floodlightProvider = 
-                        (IFloodlightProviderService)getContext().getAttributes().
-                            get(IFloodlightProviderService.class.getCanonicalName());
-                long dpid = HexString.toLong(switchId);
-                IOFSwitch sw = floodlightProvider.getSwitches().get(dpid);
-                allSwitchTableJson.put(HexString.toHexString(sw.getId()), getOneSwitchTable(table.get(sw)));
-            } catch (NumberFormatException e) {
-                log.error("Could not decode switch ID = " + switchId);
-                setStatus(Status.CLIENT_ERROR_BAD_REQUEST);
-            }
-        }
-            
-        return allSwitchTableJson;
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchWebRoutable.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchWebRoutable.java
deleted file mode 100644
index 76c30cb..0000000
--- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitchWebRoutable.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package net.floodlightcontroller.learningswitch;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-public class LearningSwitchWebRoutable implements RestletRoutable {
-
-    @Override
-    public Restlet getRestlet(Context context) {
-        Router router = new Router(context);
-        router.attach("/table/{switch}/json", LearningSwitchTable.class);
-        return router;
-    }
-
-    @Override
-    public String basePath() {
-        return "/wm/learningswitch";
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerClient.java b/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerClient.java
deleted file mode 100644
index abed853..0000000
--- a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerClient.java
+++ /dev/null
@@ -1,93 +0,0 @@
-package net.floodlightcontroller.packetstreamer;
-
-import net.floodlightcontroller.packetstreamer.thrift.*;
-
-import java.util.List;
-import java.util.ArrayList;
-
-import org.apache.thrift.TException;
-import org.apache.thrift.transport.TFramedTransport;
-import org.apache.thrift.transport.TTransport;
-import org.apache.thrift.transport.TSocket;
-import org.apache.thrift.transport.TTransportException;
-import org.apache.thrift.protocol.TBinaryProtocol;
-import org.apache.thrift.protocol.TProtocol;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The PacketStreamer Sample Client.
- */
-public class PacketStreamerClient {
-    protected static Logger log = LoggerFactory.getLogger(PacketStreamerClient.class);
-
-    /** 
-     * Main function entry point;
-     * @param args
-     */
-    public static void main(String [] args) {
-        try {
-            int serverPort = Integer.parseInt(System.getProperty("net.floodlightcontroller.packetstreamer.port", "9090"));
-            TTransport transport;
-            transport = new TFramedTransport(new TSocket("localhost", serverPort));
-            transport.open();
-  
-
-            TProtocol protocol = new  TBinaryProtocol(transport);
-            PacketStreamer.Client client = new PacketStreamer.Client(protocol);
-
-            sendPackets(client, (short)2, OFMessageType.PACKET_IN, true);
-            log.debug("Terminate session1");
-            client.terminateSession("session1");
-
-            transport.close();
-        } catch (TException x) {
-            x.printStackTrace();
-        } 
-    }
-
-    /** 
-     * Send test packets of the given OFMessageType to the packetstreamer server;
-     * @param client Packetstreamer client object
-     * @param numPackets number of test packets to be sent
-     * @param ofType OFMessageType of the test packets
-     * @param sync true if send with synchronous interface, false for asynchronous interface
-     * @throws TException
-     */
-    private static void sendPackets(PacketStreamer.Client client, short numPackets, OFMessageType ofType, boolean sync) 
-    throws TException {
-        while (numPackets-- > 0) {
-            Message msg = new Message();
-            Packet packet = new Packet();
-    
-            List<String> sids = new ArrayList<String>();
-            sids.add("session1");
-            sids.add("session2");
-            msg.setSessionIDs(sids);
-            packet.setMessageType(ofType);
-            long sw_dpid = numPackets/40 + 1;
-            packet.setSwPortTuple(new SwitchPortTuple(sw_dpid, (short)(numPackets - (sw_dpid-1)*40)));
-    
-            String strData = "New data, sequence " + numPackets;
-            packet.setData(strData.getBytes());
-            msg.setPacket(packet);
-
-            try {
-                if (sync) {
-                      client.pushMessageSync(msg);
-                      log.debug("Send packet sync: " + msg.toString());
-                } else {
-                      client.pushMessageAsync(msg);
-                      log.debug("Send packet sync: " + msg.toString());
-                }
-            } catch (TTransportException e) {
-                log.error(e.toString());
-            }
-            
-            try {
-                Thread.sleep(100);
-            } catch (Exception e) {}
-        }
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerHandler.java b/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerHandler.java
deleted file mode 100644
index 903295e..0000000
--- a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerHandler.java
+++ /dev/null
@@ -1,213 +0,0 @@
-package net.floodlightcontroller.packetstreamer;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.annotations.LogMessageDocs;
-import net.floodlightcontroller.packetstreamer.thrift.*;
-
-import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.List;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.LinkedBlockingQueue;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * The PacketStreamer handler class that implements the service APIs.
- */
-@LogMessageCategory("OpenFlow Message Tracing")
-public class PacketStreamerHandler implements PacketStreamer.Iface {
-
-	/**
-	 * The queue wrapper class that contains the queue for the streamed packets.
-	 */
-    protected class SessionQueue {
-        protected BlockingQueue<ByteBuffer> pQueue;
-
-        /**
-         * The queue wrapper constructor
-         */
-        public SessionQueue() {
-            this.pQueue = new LinkedBlockingQueue<ByteBuffer>();
-        }
-
-        /**
-         * The access method to get to the internal queue.
-         */
-        public BlockingQueue<ByteBuffer> getQueue() {
-            return this.pQueue;
-        }
-    }
-    
-    /**
-     * The class logger object
-     */
-    protected static Logger log = 
-            LoggerFactory.getLogger(PacketStreamerServer.class);
-    
-    /**
-     * A sessionId-to-queue mapping
-     */
-    protected Map<String, SessionQueue> msgQueues;
-
-    /**
-     * The handler's constructor
-     */
-    public PacketStreamerHandler() {
-        this.msgQueues = new ConcurrentHashMap<String, SessionQueue>();
-    }
-
-    /**
-     * The implementation for getPackets() function.
-     * This is a blocking API.
-     * 
-     * @param sessionid
-     * @return A list of packets associated with the session
-     */
-    @Override
-    @LogMessageDocs({
-        @LogMessageDoc(level="ERROR",
-                message="Interrupted while waiting for session start",
-                explanation="The thread was interrupted waiting " +
-                     "for the packet streamer session to start",
-                recommendation=LogMessageDoc.CHECK_CONTROLLER),
-        @LogMessageDoc(level="ERROR",
-                message="Interrupted while waiting for packets",
-                explanation="The thread was interrupted waiting " +
-                        "for packets",
-                recommendation=LogMessageDoc.CHECK_CONTROLLER)
-    })
-    public List<ByteBuffer> getPackets(String sessionid)
-            throws org.apache.thrift.TException {
-        List<ByteBuffer> packets = new ArrayList<ByteBuffer>();
-        int count = 0;
-        
-        while (!msgQueues.containsKey(sessionid) && count++ < 100) {
-            log.debug("Queue for session {} doesn't exist yet.", sessionid);
-            try {
-                Thread.sleep(100);    // Wait 100 ms to check again.
-            } catch (InterruptedException e) {
-                log.error("Interrupted while waiting for session start");
-            }
-        }
-
-        if (count < 100) {
-	        SessionQueue pQueue = msgQueues.get(sessionid);
-	        BlockingQueue<ByteBuffer> queue = pQueue.getQueue();
-	        // Block if queue is empty
-	        try {
-	            packets.add(queue.take());
-	            queue.drainTo(packets);
-	        } catch (InterruptedException e) {
-	            log.error("Interrupted while waiting for packets");
-	        }
-        }
-
-        return packets;
-    }
-
-    /**
-     * The implementation for pushMessageSync() function.
-     * 
-     * @param msg
-     * @return 1 for success, 0 for failure
-     * @throws TException
-     */
-    @Override
-    @LogMessageDocs({
-        @LogMessageDoc(level="ERROR",
-                message="Could not push empty message",
-                explanation="An empty message was sent to the packet streamer",
-                recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG),
-        @LogMessageDoc(level="ERROR",
-                message="queue for session {sessionId} is null",
-                explanation="The queue for the packet streamer session " +
-                		"is missing",
-                recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
-    })
-
-    public int pushMessageSync(Message msg)
-            throws org.apache.thrift.TException {
-
-        if (msg == null) {
-            log.error("Could not push empty message");
-            return 0;
-        }
-
-        List<String> sessionids = msg.getSessionIDs();
-        for (String sid : sessionids) {
-            SessionQueue pQueue = null;
-
-            if (!msgQueues.containsKey(sid)) {
-                pQueue = new SessionQueue();
-                msgQueues.put(sid, pQueue);
-            } else {
-                pQueue = msgQueues.get(sid);
-            }
-
-            log.debug("pushMessageSync: SessionId: " + sid + 
-                      " Receive a message, " + msg.toString() + "\n");
-            ByteBuffer bb = ByteBuffer.wrap(msg.getPacket().getData());
-            //ByteBuffer dst = ByteBuffer.wrap(msg.getPacket().toString().getBytes());
-            BlockingQueue<ByteBuffer> queue = pQueue.getQueue();
-            if (queue != null) {
-                if (!queue.offer(bb)) {
-                    log.error("Failed to queue message for session: " + sid);
-                } else {
-                    log.debug("insert a message to session: " + sid);
-                }
-            } else {
-                log.error("queue for session {} is null", sid);
-            }
-        }
-
-        return 1;
-    }
-
-    /**
-     * The implementation for pushMessageAsync() function.
-     * 
-     * @param msg
-     * @throws TException
-     */
-    @Override
-    public void pushMessageAsync(Message msg)
-            throws org.apache.thrift.TException {
-        pushMessageSync(msg);
-        return;
-    }
-
-    /**
-     * The implementation for terminateSession() function.
-     * It removes the session to queue association.
-     * @param sessionid
-     * @throws TException
-     */
-    @Override
-    public void terminateSession(String sessionid)
-            throws org.apache.thrift.TException {
-        if (!msgQueues.containsKey(sessionid)) {
-            return;
-        }
-
-        SessionQueue pQueue = msgQueues.get(sessionid);
-
-        log.debug("terminateSession: SessionId: " + sessionid + "\n");
-        String data = "FilterTimeout";
-        ByteBuffer bb = ByteBuffer.wrap(data.getBytes());
-        BlockingQueue<ByteBuffer> queue = pQueue.getQueue();
-        if (queue != null) {
-            if (!queue.offer(bb)) {
-                log.error("Failed to queue message for session: " + sessionid);
-            }
-            msgQueues.remove(sessionid);
-        } else {
-            log.error("queue for session {} is null", sessionid);
-        }
-    }
-}
-
diff --git a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerServer.java b/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerServer.java
deleted file mode 100644
index 4a425e0..0000000
--- a/src/main/java/net/floodlightcontroller/packetstreamer/PacketStreamerServer.java
+++ /dev/null
@@ -1,72 +0,0 @@
-package net.floodlightcontroller.packetstreamer;
-
-import org.apache.thrift.protocol.TBinaryProtocol;
-import org.apache.thrift.server.TServer;
-import org.apache.thrift.server.THsHaServer;
-import org.apache.thrift.transport.TFramedTransport;
-import org.apache.thrift.transport.TNonblockingServerSocket;
-import org.apache.thrift.transport.TNonblockingServerTransport;
-
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-// Generated code
-import net.floodlightcontroller.packetstreamer.thrift.*;
-
-/**
- * The PacketStreamer Server that brokers the packet streaming service.
- */
-@LogMessageCategory("OpenFlow Message Tracing")
-public class PacketStreamerServer {
-    protected static Logger log = LoggerFactory.getLogger(PacketStreamerServer.class);
-    protected static int port = 9090;
-    protected static PacketStreamerHandler handler;
-    protected static PacketStreamer.Processor<PacketStreamerHandler> processor;
-
-    
-    /** 
-     * Main function entry point;
-     * @param args
-     */
-    public static void main(String [] args) {
-        try {
-            port = Integer.parseInt(System.getProperty("net.floodlightcontroller.packetstreamer.port", "9090"));
-            
-            handler = new PacketStreamerHandler();
-            processor = new PacketStreamer.Processor<PacketStreamerHandler>(handler);
-
-            Runnable simple = new Runnable() {
-                public void run() {
-                    hshaServer(processor);
-                }
-            };
-
-            new Thread(simple).start();
-        } catch (Exception x) {
-            x.printStackTrace();
-        }
-    }
-
-    
-    /** 
-     * The function to create a thrift Half-Sync and Half-Async Server.
-     * @param processor
-     */
-    public static void hshaServer(PacketStreamer.Processor<PacketStreamerHandler> processor) {
-        try {
-            TNonblockingServerTransport serverTransport = new TNonblockingServerSocket(port);
-            THsHaServer.Args args = new THsHaServer.Args(serverTransport);
-            args.processor(processor);
-            args.transportFactory(new TFramedTransport.Factory());
-            args.protocolFactory(new TBinaryProtocol.Factory(true, true));
-            TServer server = new THsHaServer(args);
-    
-            log.info("Starting the packetstreamer hsha server on port {} ...", port);
-            server.serve();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java b/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java
deleted file mode 100644
index 6021e3d..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/HostResource.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-
-import net.floodlightcontroller.util.MACAddress;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.restlet.data.Status;
-import org.restlet.resource.Delete;
-import org.restlet.resource.Put;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class HostResource extends org.restlet.resource.ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(HostResource.class);
-    
-    public class HostDefinition {
-        String port = null; // Logical port name
-        String guid = null; // Network ID
-        String mac = null; // MAC Address
-        String attachment = null; // Attachment name
-    }
-    
-    protected void jsonToHostDefinition(String json, HostDefinition host) throws IOException {
-        MappingJsonFactory f = new MappingJsonFactory();
-        JsonParser jp;
-        
-        try {
-            jp = f.createJsonParser(json);
-        } catch (JsonParseException e) {
-            throw new IOException(e);
-        }
-        
-        jp.nextToken();
-        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
-            throw new IOException("Expected START_OBJECT");
-        }
-        
-        while (jp.nextToken() != JsonToken.END_OBJECT) {
-            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
-                throw new IOException("Expected FIELD_NAME");
-            }
-            
-            String n = jp.getCurrentName();
-            jp.nextToken();
-            if (jp.getText().equals("")) 
-                continue;
-            else if (n.equals("attachment")) {
-                while (jp.nextToken() != JsonToken.END_OBJECT) {
-                    String field = jp.getCurrentName();
-                    if (field.equals("id")) {
-                        host.attachment = jp.getText();
-                    } else if (field.equals("mac")) {
-                        host.mac = jp.getText();
-                    }
-                }
-            }
-        }
-        
-        jp.close();
-    }
-    
-    @Put
-    public String addHost(String postData) {
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        HostDefinition host = new HostDefinition();
-        host.port = (String) getRequestAttributes().get("port");
-        host.guid = (String) getRequestAttributes().get("network");
-        try {
-            jsonToHostDefinition(postData, host);
-        } catch (IOException e) {
-            log.error("Could not parse JSON {}", e.getMessage());
-        }
-        vns.addHost(MACAddress.valueOf(host.mac), host.guid, host.port);
-        setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-    }
-    
-    
-    @Delete
-    public String deleteHost() {
-        String port = (String) getRequestAttributes().get("port");
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        vns.deleteHost(null, port);
-        setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/IVirtualNetworkService.java b/src/main/java/net/floodlightcontroller/virtualnetwork/IVirtualNetworkService.java
deleted file mode 100644
index 4304a33..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/IVirtualNetworkService.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.util.Collection;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.util.MACAddress;
-
-public interface IVirtualNetworkService extends IFloodlightService {
-    /**
-     * Creates a new virtual network. This can also be called
-     * to modify a virtual network. To update a network you specify the GUID
-     * and the fields you want to update.
-     * @param network The network name. Must be unique.
-     * @param guid The ID of the network. Must be unique.
-     * @param gateway The IP address of the network gateway, null if none.
-     */
-    public void createNetwork(String guid, String network, Integer gateway);
-    
-    /**
-     * Deletes a virtual network.
-     * @param guid The ID (not name) of virtual network to delete.
-     */
-    public void deleteNetwork(String guid);
-    
-    /**
-     * Adds a host to a virtual network. If a mapping already exists the
-     * new one will override the old mapping.
-     * @param mac The MAC address of the host to add.
-     * @param network The network to add the host to.
-     * @param port The logical port name to attach the host to. Must be unique.
-     */
-    public void addHost(MACAddress mac, String network, String port); 
-    
-    /**
-     * Deletes a host from a virtual network. Either the MAC or Port must
-     * be specified.
-     * @param mac The MAC address to delete.
-     * @param port The logical port the host is attached to.
-     */
-    public void deleteHost(MACAddress mac, String port);
-    
-    /**
-     * Return list of all virtual networks.
-     * @return Collection <VirtualNetwork>
-     */
-    public Collection <VirtualNetwork> listNetworks();
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java b/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java
deleted file mode 100644
index 2efe52a..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/NetworkResource.java
+++ /dev/null
@@ -1,133 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-import java.util.Collection;
-
-import net.floodlightcontroller.packet.IPv4;
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.restlet.data.Status;
-import org.restlet.resource.Delete;
-import org.restlet.resource.Get;
-import org.restlet.resource.Post;
-import org.restlet.resource.Put;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class NetworkResource extends ServerResource {
-    protected static Logger log = LoggerFactory.getLogger(NetworkResource.class);
-    
-    public class NetworkDefinition {
-        public String name = null;
-        public String guid = null;
-        public String gateway = null;
-    }
-    
-    protected void jsonToNetworkDefinition(String json, NetworkDefinition network) throws IOException {
-        MappingJsonFactory f = new MappingJsonFactory();
-        JsonParser jp;
-        
-        try {
-            jp = f.createJsonParser(json);
-        } catch (JsonParseException e) {
-            throw new IOException(e);
-        }
-        
-        jp.nextToken();
-        if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
-            throw new IOException("Expected START_OBJECT");
-        }
-        
-        while (jp.nextToken() != JsonToken.END_OBJECT) {
-            if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
-                throw new IOException("Expected FIELD_NAME");
-            }
-            
-            String n = jp.getCurrentName();
-            jp.nextToken();
-            if (jp.getText().equals("")) 
-                continue;
-            else if (n.equals("network")) {
-                while (jp.nextToken() != JsonToken.END_OBJECT) {
-                    String field = jp.getCurrentName();
-                    if (field.equals("name")) {
-                        network.name = jp.getText();
-                    } else if (field.equals("gateway")) {
-                    	String gw = jp.getText();
-                    	if ((gw != null) && (!gw.equals("null")))
-                    		network.gateway = gw;
-                    } else if (field.equals("id")) {
-                    	network.guid = jp.getText();
-                    } else {
-                        log.warn("Unrecognized field {} in " +
-                        		"parsing network definition", 
-                        		jp.getText());
-                    }
-                }
-            }
-        }
-        
-        jp.close();
-    }
-    
-    @Get("json")
-    public Collection <VirtualNetwork> retrieve() {
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        
-        return vns.listNetworks();               
-    }
-    
-    @Put
-    @Post
-    public String createNetwork(String postData) {        
-        NetworkDefinition network = new NetworkDefinition();
-        try {
-            jsonToNetworkDefinition(postData, network);
-        } catch (IOException e) {
-            log.error("Could not parse JSON {}", e.getMessage());
-        }
-        
-        // We try to get the ID from the URI only if it's not
-        // in the POST data 
-        if (network.guid == null) {
-	        String guid = (String) getRequestAttributes().get("network");
-	        if ((guid != null) && (!guid.equals("null")))
-	        	network.guid = guid;
-        }
-        
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        
-        Integer gw = null;
-        if (network.gateway != null) {
-            try {
-                gw = IPv4.toIPv4Address(network.gateway);
-            } catch (IllegalArgumentException e) {
-                log.warn("Could not parse gateway {} as IP for network {}, setting as null",
-                         network.gateway, network.name);
-                network.gateway = null;
-            }
-        }
-        vns.createNetwork(network.guid, network.name, gw);
-        setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-    }
-    
-    @Delete
-    public String deleteNetwork() {
-        IVirtualNetworkService vns =
-                (IVirtualNetworkService)getContext().getAttributes().
-                    get(IVirtualNetworkService.class.getCanonicalName());
-        String guid = (String) getRequestAttributes().get("network");
-        vns.deleteNetwork(guid);
-        setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java b/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java
deleted file mode 100644
index a184a95..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/NoOp.java
+++ /dev/null
@@ -1,21 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.Post;
-import org.restlet.resource.Put;
-import org.restlet.resource.ServerResource;
-
-public class NoOp extends ServerResource {
-	/**
-	 * Does nothing and returns 200 OK with a status message
-	 * @return status: ok
-	 */
-	@Get
-	@Put
-	@Post
-	public String noOp(String postdata) {
-		setStatus(Status.SUCCESS_OK);
-        return "{\"status\":\"ok\"}";
-	}
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java
deleted file mode 100644
index f5dfb21..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetwork.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import org.codehaus.jackson.map.annotate.JsonSerialize;
-
-import net.floodlightcontroller.util.MACAddress;
-
-/**
- * Data structure for storing and outputing information of a virtual network created
- * by VirtualNetworkFilter
- * 
- * @author KC Wang
- */
-
-@JsonSerialize(using=VirtualNetworkSerializer.class)
-public class VirtualNetwork{
-    protected String name; // network name
-    protected String guid; // network id
-    protected String gateway; // network gateway
-    protected Collection<MACAddress> hosts; // array of hosts explicitly added to this network
-
-    /**
-     * Constructor requires network name and id
-     * @param name: network name
-     * @param guid: network id 
-     */
-    public VirtualNetwork(String name, String guid) {
-        this.name = name;
-        this.guid = guid;
-        this.gateway = null;
-        this.hosts = new ArrayList<MACAddress>();
-        return;        
-    }
-
-    /**
-     * Sets network name
-     * @param gateway: IP address as String
-     */
-    public void setName(String name){
-        this.name = name;
-        return;                
-    }
-    
-    /**
-     * Sets network gateway IP address
-     * @param gateway: IP address as String
-     */
-    public void setGateway(String gateway){
-        this.gateway = gateway;
-        return;                
-    }
-    
-    /**
-     * Adds a host to this network record
-     * @param host: MAC address as MACAddress
-     */
-    public void addHost(MACAddress host){
-        this.hosts.add(host);
-        return;        
-    }
-    
-    /**
-     * Removes a host from this network record
-     * @param host: MAC address as MACAddress
-     * @return boolean: true: removed, false: host not found
-     */
-    public boolean removeHost(MACAddress host){
-        Iterator<MACAddress> iter = this.hosts.iterator();
-        while(iter.hasNext()){
-            MACAddress element = iter.next();
-            if(element.equals(host) ){
-                //assuming MAC address for host is unique
-                iter.remove();
-                return true;
-            }                
-        }
-        return false;
-    }
-    
-    /**
-     * Removes all hosts from this network record
-     */
-    public void clearHosts(){
-        this.hosts.clear();
-    }
-}
\ No newline at end of file
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java
deleted file mode 100644
index 012dfb6..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilter.java
+++ /dev/null
@@ -1,521 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.util.HexString;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.util.AppCookie;
-import net.floodlightcontroller.devicemanager.IDevice;
-import net.floodlightcontroller.devicemanager.IDeviceListener;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.packet.DHCP;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.routing.ForwardingBase;
-import net.floodlightcontroller.util.MACAddress;
-
-/**
- * A simple Layer 2 (MAC based) network virtualization module. This module allows
- * you to create simple L2 networks (host + gateway) and will drop traffic if
- * they are not on the same virtual network.
- * 
- * LIMITATIONS
- * - This module does not allow overlapping of IPs or MACs
- * - You can only have 1 gateway per virtual network (can be shared)
- * - There is filtering of multicast/broadcast traffic
- * - All DHCP traffic will be allowed, regardless of unicast/broadcast
- * 
- * @author alexreimers
- */
-public class VirtualNetworkFilter 
-    implements IFloodlightModule, IVirtualNetworkService, IOFMessageListener, IDeviceListener {
-    protected static Logger log = LoggerFactory.getLogger(VirtualNetworkFilter.class);
-    
-    private final short APP_ID = 20;
-    
-    // Our dependencies
-    IFloodlightProviderService floodlightProvider;
-    IRestApiService restApi;
-    IDeviceService deviceService;
-    
-    // Our internal state
-    protected Map<String, VirtualNetwork> vNetsByGuid; // List of all created virtual networks 
-    protected Map<String, String> nameToGuid; // Logical name -> Network ID
-    protected Map<String, Integer> guidToGateway; // Network ID -> Gateway IP
-    protected Map<Integer, Set<String>> gatewayToGuid; // Gateway IP -> Network ID
-    protected Map<MACAddress, Integer> macToGateway; // Gateway MAC -> Gateway IP
-    protected Map<MACAddress, String> macToGuid; // Host MAC -> Network ID
-    protected Map<String, MACAddress> portToMac; // Host MAC -> logical port name
-    
-    /**
-     * Adds a gateway to a virtual network.
-     * @param guid The ID (not name) of the network.
-     * @param ip The IP addresses of the gateway.
-     */
-    protected void addGateway(String guid, Integer ip) {
-        if (ip.intValue() != 0) {
-        	if (log.isDebugEnabled())
-        		log.debug("Adding {} as gateway for GUID {}",
-        				IPv4.fromIPv4Address(ip), guid);
-        	
-            guidToGateway.put(guid, ip);
-            if (vNetsByGuid.get(guid) != null)
-                vNetsByGuid.get(guid).setGateway(IPv4.fromIPv4Address(ip));
-            if (gatewayToGuid.containsKey(ip)) {
-                Set<String> gSet = gatewayToGuid.get(ip);
-                gSet.add(guid);
-            } else {
-                Set<String> gSet = Collections.synchronizedSet(new HashSet<String>());
-                gSet.add(guid);
-                gatewayToGuid.put(ip, gSet);
-            }
-        }
-    }
-    
-    /**
-     * Deletes a gateway for a virtual network.
-     * @param guid The ID (not name) of the network to delete
-     * the gateway for.
-     */
-    protected void deleteGateway(String guid) {
-        Integer gwIp = guidToGateway.remove(guid);
-        if (gwIp == null) return;
-        Set<String> gSet = gatewayToGuid.get(gwIp);
-        gSet.remove(guid);
-        if(vNetsByGuid.get(guid)!=null)
-            vNetsByGuid.get(guid).setGateway(null);
-    }
-    
-    // IVirtualNetworkService
-    
-    @Override
-    public void createNetwork(String guid, String network, Integer gateway) {
-        if (log.isDebugEnabled()) {
-            String gw = null;
-            try {
-                gw = IPv4.fromIPv4Address(gateway);
-            } catch (Exception e) {
-                // fail silently
-            }
-            log.debug("Creating network {} with ID {} and gateway {}", 
-                      new Object[] {network, guid, gw});
-        }
-        
-        if (!nameToGuid.isEmpty()) {
-            // We have to iterate all the networks to handle name/gateway changes
-            for (Entry<String, String> entry : nameToGuid.entrySet()) {
-                if (entry.getValue().equals(guid)) {
-                    nameToGuid.remove(entry.getKey());
-                    break;
-                }
-            }
-        }
-        nameToGuid.put(network, guid);
-        if (vNetsByGuid.containsKey(guid))
-            vNetsByGuid.get(guid).setName(network); //network already exists, just updating name
-        else
-            vNetsByGuid.put(guid, new VirtualNetwork(network, guid)); //new network
-        
-        // If they don't specify a new gateway the old one will be preserved
-        if ((gateway != null) && (gateway != 0)) {
-            addGateway(guid, gateway);
-            if(vNetsByGuid.get(guid)!=null)
-                vNetsByGuid.get(guid).setGateway(IPv4.fromIPv4Address(gateway));
-        }
-    }
-
-    @Override
-    public void deleteNetwork(String guid) {
-        String name = null;
-        if (nameToGuid.isEmpty()) {
-            log.warn("Could not delete network with ID {}, network doesn't exist",
-                     guid);
-            return;
-        }
-        for (Entry<String, String> entry : nameToGuid.entrySet()) {
-            if (entry.getValue().equals(guid)) {
-                name = entry.getKey();
-                break;
-            }
-            log.warn("Could not delete network with ID {}, network doesn't exist",
-                     guid);
-        }
-        
-        if (log.isDebugEnabled()) 
-            log.debug("Deleting network with name {} ID {}", name, guid);
-        
-        nameToGuid.remove(name);
-        deleteGateway(guid);
-        if(vNetsByGuid.get(guid)!=null){
-            vNetsByGuid.get(guid).clearHosts();
-            vNetsByGuid.remove(guid);
-        }
-        Collection<MACAddress> deleteList = new ArrayList<MACAddress>();
-        for (MACAddress host : macToGuid.keySet()) {
-            if (macToGuid.get(host).equals(guid)) {
-                deleteList.add(host);
-            }
-        }
-        for (MACAddress mac : deleteList) {
-            if (log.isDebugEnabled()) {
-                log.debug("Removing host {} from network {}", 
-                          HexString.toHexString(mac.toBytes()), guid);
-            }
-            macToGuid.remove(mac);
-            for (Entry<String, MACAddress> entry : portToMac.entrySet()) {
-                if (entry.getValue().equals(mac)) {
-                    portToMac.remove(entry.getKey());
-                    break;
-                }
-            }
-        }
-    }
-
-    @Override
-    public void addHost(MACAddress mac, String guid, String port) {
-        if (guid != null) {
-            if (log.isDebugEnabled()) {
-                log.debug("Adding {} to network ID {} on port {}",
-                          new Object[] {mac, guid, port});
-            }
-            // We ignore old mappings
-            macToGuid.put(mac, guid);
-            portToMac.put(port, mac);
-            if(vNetsByGuid.get(guid)!=null)
-                vNetsByGuid.get(guid).addHost(new MACAddress(mac.toBytes()));
-        } else {
-            log.warn("Could not add MAC {} to network ID {} on port {}, the network does not exist",
-                     new Object[] {mac, guid, port});
-        }
-    }
-
-    @Override
-    public void deleteHost(MACAddress mac, String port) {
-        if (log.isDebugEnabled()) {
-            log.debug("Removing host {} from port {}", mac, port);
-        }
-        if (mac == null && port == null) return;
-        if (port != null) {
-            MACAddress host = portToMac.remove(port);
-            if(vNetsByGuid.get(macToGuid.get(host)) != null)
-                vNetsByGuid.get(macToGuid.get(host)).removeHost(host);
-            macToGuid.remove(host);
-        } else if (mac != null) {
-            if (!portToMac.isEmpty()) {
-                for (Entry<String, MACAddress> entry : portToMac.entrySet()) {
-                    if (entry.getValue().equals(mac)) {
-                        if(vNetsByGuid.get(macToGuid.get(entry.getValue())) != null)
-                            vNetsByGuid.get(macToGuid.get(entry.getValue())).removeHost(entry.getValue());
-                        portToMac.remove(entry.getKey());
-                        macToGuid.remove(entry.getValue());
-                        return;
-                    }
-                }
-            }
-        }
-    }
-    
-    // IFloodlightModule
-    
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleServices() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IVirtualNetworkService.class);
-        return l;
-    }
-
-    @Override
-    public Map<Class<? extends IFloodlightService>, IFloodlightService>
-            getServiceImpls() {
-        Map<Class<? extends IFloodlightService>,
-            IFloodlightService> m = 
-                new HashMap<Class<? extends IFloodlightService>,
-                    IFloodlightService>();
-        m.put(IVirtualNetworkService.class, this);
-        return m;
-    }
-
-    @Override
-    public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
-        Collection<Class<? extends IFloodlightService>> l = 
-                new ArrayList<Class<? extends IFloodlightService>>();
-        l.add(IFloodlightProviderService.class);
-        l.add(IRestApiService.class);
-        l.add(IDeviceService.class);
-        return l;
-    }
-
-    @Override
-    public void init(FloodlightModuleContext context)  
-                                 throws FloodlightModuleException {
-        floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class);
-        restApi = context.getServiceImpl(IRestApiService.class);
-        deviceService = context.getServiceImpl(IDeviceService.class);
-        
-        vNetsByGuid = new ConcurrentHashMap<String, VirtualNetwork>();
-        nameToGuid = new ConcurrentHashMap<String, String>();
-        guidToGateway = new ConcurrentHashMap<String, Integer>();
-        gatewayToGuid = new ConcurrentHashMap<Integer, Set<String>>();
-        macToGuid = new ConcurrentHashMap<MACAddress, String>();
-        portToMac = new ConcurrentHashMap<String, MACAddress>();
-        macToGateway = new ConcurrentHashMap<MACAddress, Integer>();
-    }
-
-    @Override
-    public void startUp(FloodlightModuleContext context) {
-        floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this);
-        restApi.addRestletRoutable(new VirtualNetworkWebRoutable());
-        deviceService.addListener(this);
-    }
-
-    // IOFMessageListener
-    
-    @Override
-    public String getName() {
-        return "virtualizer";
-    }
-
-    @Override
-    public boolean isCallbackOrderingPrereq(OFType type, String name) {
-        // Link discovery should go before us so we don't block LLDPs
-        return (type.equals(OFType.PACKET_IN) && 
-        		(name.equals("linkdiscovery") || (name.equals("devicemanager"))));
-    }
-
-    @Override
-    public boolean isCallbackOrderingPostreq(OFType type, String name) {
-        // We need to go before forwarding
-        return (type.equals(OFType.PACKET_IN) && name.equals("forwarding"));
-    }
-
-    @Override
-    public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
-        switch (msg.getType()) {
-            case PACKET_IN:
-                return processPacketIn(sw, (OFPacketIn)msg, cntx);
-            default:
-            	break;
-        }
-        log.warn("Received unexpected message {}", msg);
-        return Command.CONTINUE;
-    }
-    
-    /**
-     * Checks whether the frame is destined to or from a gateway.
-     * @param frame The ethernet frame to check.
-     * @return True if it is to/from a gateway, false otherwise.
-     */
-    protected boolean isDefaultGateway(Ethernet frame) {
-    	if (macToGateway.containsKey(frame.getSourceMAC()))
-    		return true;
-    	
-    	Integer gwIp = macToGateway.get(frame.getDestinationMAC());
-    	if (gwIp != null) {
-    		MACAddress host = frame.getSourceMAC();
-    		String srcNet = macToGuid.get(host);
-    		if (srcNet != null) {
-	    		Integer gwIpSrcNet = guidToGateway.get(srcNet);
-	    		if ((gwIpSrcNet != null) && (gwIp.equals(gwIpSrcNet)))
-	    			return true;
-    		}
-    	}
-
-    	return false;
-    }
-    
-    /**
-     * Checks to see if two MAC Addresses are on the same network.
-     * @param m1 The first MAC.
-     * @param m2 The second MAC.
-     * @return True if they are on the same virtual network,
-     * 		   false otherwise.
-     */
-    protected boolean oneSameNetwork(MACAddress m1, MACAddress m2) {
-        String net1 = macToGuid.get(m1);
-        String net2 = macToGuid.get(m2);
-        if (net1 == null) return false;
-        if (net2 == null) return false;
-        return net1.equals(net2);
-    }
-    
-    /**
-     * Checks to see if an Ethernet frame is a DHCP packet.
-     * @param frame The Ethernet frame.
-     * @return True if it is a DHCP frame, false otherwise.
-     */
-    protected boolean isDhcpPacket(Ethernet frame) {
-        IPacket payload = frame.getPayload(); // IP
-        if (payload == null) return false;
-        IPacket p2 = payload.getPayload(); // TCP or UDP
-        if (p2 == null) return false;
-        IPacket p3 = p2.getPayload(); // Application
-        if ((p3 != null) && (p3 instanceof DHCP)) return true;
-        return false;
-    }
-    
-    /**
-     * Processes an OFPacketIn message and decides if the OFPacketIn should be dropped
-     * or the processing should continue.
-     * @param sw The switch the PacketIn came from.
-     * @param msg The OFPacketIn message from the switch.
-     * @param cntx The FloodlightContext for this message.
-     * @return Command.CONTINUE if processing should be continued, Command.STOP otherwise.
-     */
-    protected Command processPacketIn(IOFSwitch sw, OFPacketIn msg, FloodlightContext cntx) {
-        Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, 
-                                              IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
-        Command ret = Command.STOP;
-        String srcNetwork = macToGuid.get(eth.getSourceMAC());
-        // If the host is on an unknown network we deny it.
-        // We make exceptions for ARP and DHCP.
-        if (eth.isBroadcast() || eth.isMulticast() || isDefaultGateway(eth) || isDhcpPacket(eth)) {
-        	ret = Command.CONTINUE;
-        } else if (srcNetwork == null) {
-            log.trace("Blocking traffic from host {} because it is not attached to any network.",
-                      HexString.toHexString(eth.getSourceMACAddress()));
-            ret = Command.STOP;
-        } else if (oneSameNetwork(eth.getSourceMAC(), eth.getDestinationMAC())) {
-            // if they are on the same network continue
-            ret = Command.CONTINUE;
-        }
-        
-        if (log.isTraceEnabled())
-        	log.trace("Results for flow between {} and {} is {}",
-        			new Object[] {eth.getSourceMAC(), eth.getDestinationMAC(), ret});
-        /*
-         * TODO - figure out how to still detect gateways while using
-         * drop mods 
-        if (ret == Command.STOP) {
-            if (!(eth.getPayload() instanceof ARP))
-            	doDropFlow(sw, msg, cntx);
-        }
-        */
-        return ret;
-    }
-    
-    /**
-     * Writes a FlowMod to a switch that inserts a drop flow.
-     * @param sw The switch to write the FlowMod to.
-     * @param pi The corresponding OFPacketIn. Used to create the OFMatch structure.
-     * @param cntx The FloodlightContext that gets passed to the switch.
-     */
-    protected void doDropFlow(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) {
-        if (log.isTraceEnabled()) {
-            log.trace("doDropFlow pi={} srcSwitch={}",
-                    new Object[] { pi, sw });
-        }
-
-        if (sw == null) {
-            log.warn("Switch is null, not installing drop flowmod for PacketIn {}", pi);
-            return;
-        }
-
-        // Create flow-mod based on packet-in and src-switch
-        OFFlowMod fm = 
-            (OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD);
-        OFMatch match = new OFMatch();
-        match.loadFromPacket(pi.getPacketData(), pi.getInPort());
-        List<OFAction> actions = new ArrayList<OFAction>(); // no actions = drop
-        long cookie = AppCookie.makeCookie(APP_ID, 0);
-        fm.setCookie(cookie)
-        .setIdleTimeout(ForwardingBase.FLOWMOD_DEFAULT_IDLE_TIMEOUT)
-        .setHardTimeout(ForwardingBase.FLOWMOD_DEFAULT_HARD_TIMEOUT)
-        .setBufferId(OFPacketOut.BUFFER_ID_NONE)
-        .setMatch(match)
-        .setActions(actions)
-        .setLengthU(OFFlowMod.MINIMUM_LENGTH);
-        fm.setFlags(OFFlowMod.OFPFF_SEND_FLOW_REM);
-        try {
-            if (log.isTraceEnabled()) {
-                log.trace("write drop flow-mod srcSwitch={} match={} " + 
-                          "pi={} flow-mod={}",
-                          new Object[] {sw, match, pi, fm});
-            }
-            sw.write(fm, cntx);
-        } catch (IOException e) {
-            log.error("Failure writing drop flow mod", e);
-        }
-        return;
-    }
-
-    // IDeviceListener
-    
-	@Override
-	public void deviceAdded(IDevice device) {
-		if (device.getIPv4Addresses() == null) return;
-		for (Integer i : device.getIPv4Addresses()) {
-			if (gatewayToGuid.containsKey(i)) {
-				MACAddress mac = MACAddress.valueOf(device.getMACAddress());
-				if (log.isDebugEnabled())
-					log.debug("Adding MAC {} with IP {} a a gateway",
-							HexString.toHexString(mac.toBytes()),
-							IPv4.fromIPv4Address(i));
-				macToGateway.put(mac, i);
-			}
-		}
-	}
-
-	@Override
-	public void deviceRemoved(IDevice device) {
-		// if device is a gateway remove
-		MACAddress mac = MACAddress.valueOf(device.getMACAddress());
-		if (macToGateway.containsKey(mac)) {
-			if (log.isDebugEnabled())
-				log.debug("Removing MAC {} as a gateway",
-						HexString.toHexString(mac.toBytes()));
-			macToGateway.remove(mac);
-		}
-	}
-
-	@Override
-	public void deviceIPV4AddrChanged(IDevice device) {
-		// add or remove entry as gateway
-		deviceAdded(device);
-	}
-
-	@Override
-	public void deviceMoved(IDevice device) {
-		// ignore
-	}
-	
-	@Override
-	public void deviceVlanChanged(IDevice device) {
-		// ignore
-	}
-
-    @Override
-    public Collection <VirtualNetwork> listNetworks() {
-        return vNetsByGuid.values();
-        
-    }
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java
deleted file mode 100644
index 6902f6c..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkSerializer.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import java.io.IOException;
-import java.util.Iterator;
-
-import net.floodlightcontroller.util.MACAddress;
-
-import org.codehaus.jackson.JsonGenerator;
-import org.codehaus.jackson.JsonProcessingException;
-import org.codehaus.jackson.map.JsonSerializer;
-import org.codehaus.jackson.map.SerializerProvider;
-
-/**
- * Serialize a VirtualNetwork object
- * @author KC Wang
- */
-public class VirtualNetworkSerializer extends JsonSerializer<VirtualNetwork> {
-
-    @Override
-    public void serialize(VirtualNetwork vNet, JsonGenerator jGen,
-            SerializerProvider serializer) throws IOException,
-            JsonProcessingException {
-        jGen.writeStartObject();
-        
-        jGen.writeStringField("name", vNet.name);
-        jGen.writeStringField("guid", vNet.guid);
-        jGen.writeStringField("gateway", vNet.gateway);
-
-        jGen.writeArrayFieldStart("mac");
-        Iterator<MACAddress> hit = vNet.hosts.iterator();
-        while (hit.hasNext())
-            jGen.writeString(hit.next().toString());
-        jGen.writeEndArray();
-        
-        jGen.writeEndObject();
-    }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java b/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java
deleted file mode 100644
index 61769ec..0000000
--- a/src/main/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkWebRoutable.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-public class VirtualNetworkWebRoutable implements RestletRoutable {
-
-    @Override
-    public Restlet getRestlet(Context context) {
-        Router router = new Router(context);
-        router.attach("/tenants/{tenant}/networks", NetworkResource.class); // GET
-        router.attach("/tenants/{tenant}/networks/{network}", NetworkResource.class); // PUT, DELETE
-        router.attach("/tenants/{tenant}/networks", NetworkResource.class); // POST
-        router.attach("/tenants/{tenant}/networks/{network}/ports/{port}/attachment", HostResource.class);
-        router.attachDefault(NoOp.class);
-        return router;
-    }
-
-    @Override
-    public String basePath() {
-        return "/quantum/v1.0";
-    }
-}
\ No newline at end of file
diff --git a/src/main/python/PythonClient.py b/src/main/python/PythonClient.py
deleted file mode 100644
index 5c9890e..0000000
--- a/src/main/python/PythonClient.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-sys.path.append('../../../target/gen-py')
-
-from packetstreamer import PacketStreamer
-from packetstreamer.ttypes import *
-
-from thrift import Thrift
-from thrift.transport import TSocket
-from thrift.transport import TTransport
-from thrift.protocol import TBinaryProtocol
-
-try:
-
-    # Make socket
-    transport = TSocket.TSocket('localhost', 9090)
-
-    # Buffering is critical. Raw sockets are very slow
-    transport = TTransport.TFramedTransport(transport)
-
-    # Wrap in a protocol
-    protocol = TBinaryProtocol.TBinaryProtocol(transport)
-
-    # Create a client to use the protocol encoder
-    client = PacketStreamer.Client(protocol)
-
-    # Connect!
-    transport.open()
-
-    while 1:
-        packets = client.getPackets("session1")
-        print 'session1 packets num: %d' % (len(packets))
-        count = 1
-        for packet in packets:
-            print "Packet %d: %s"% (count, packet)
-            if "FilterTimeout" in packet:
-                sys.exit()
-            count += 1 
-
-    # Close!
-    transport.close()
-
-except Thrift.TException, tx:
-    print '%s' % (tx.message)
-
-except KeyboardInterrupt, e:
-    print 'Bye-bye'
diff --git a/src/main/python/PythonServer.py b/src/main/python/PythonServer.py
deleted file mode 100644
index c3c844e..0000000
--- a/src/main/python/PythonServer.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-import logging
-sys.path.append('../../../target/gen-py')
-
-from packetstreamer import PacketStreamer
-from packetstreamer.ttypes import *
-
-from thrift.transport import TSocket
-from thrift.transport import TTransport
-from thrift.protocol import TBinaryProtocol
-from thrift.server import TServer
-
-class PacketStreamerHandler:
-  def __init__(self):
-    logging.handlers.codecs = None
-    self.log = logging.getLogger("packetstreamer")
-    self.log.setLevel(logging.DEBUG)
-    handler = logging.handlers.SysLogHandler("/dev/log")
-    handler.setFormatter(logging.Formatter("%(name)s: %(levelname)s %(message)s"))
-    self.log.addHandler(handler)
-
-  def ping(self):
-    self.log.debug('ping()')
-    return true
-
-  def pushPacketSync(self, packet):
-    self.log.debug('receive a packet synchronously: %s' %(packet))
-    return 0
-
-  def pushPacketAsync(self, packet):
-    self.log.debug('receive a packet Asynchronously: %s' %(packet))
-
-handler = PacketStreamerHandler()
-processor = PacketStreamer.Processor(handler)
-transport = TSocket.TServerSocket(9090)
-tfactory = TTransport.TBufferedTransportFactory()
-pfactory = TBinaryProtocol.TBinaryProtocolFactory()
-
-server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
-
-# You could do one of these for a multithreaded server
-#server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
-#server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
-
-print 'Starting the server...'
-server.serve()
-print 'done.'
diff --git a/src/main/python/compileall.py b/src/main/python/compileall.py
deleted file mode 100644
index b21d95f..0000000
--- a/src/main/python/compileall.py
+++ /dev/null
@@ -1,157 +0,0 @@
-"""Module/script to "compile" all .py files to .pyc (or .pyo) file.
-
-When called as a script with arguments, this compiles the directories
-given as arguments recursively; the -l option prevents it from
-recursing into directories.
-
-Without arguments, if compiles all modules on sys.path, without
-recursing into subdirectories.  (Even though it should do so for
-packages -- for now, you'll have to deal with packages separately.)
-
-See module py_compile for details of the actual byte-compilation.
-
-"""
-
-import os
-import sys
-import py_compile
-
-__all__ = ["compile_dir","compile_path"]
-
-def compile_dir(dir, maxlevels=10, ddir=None,
-                force=0, rx=None, quiet=0):
-    """Byte-compile all modules in the given directory tree.
-
-    Arguments (only dir is required):
-
-    dir:       the directory to byte-compile
-    maxlevels: maximum recursion level (default 10)
-    ddir:      if given, purported directory name (this is the
-               directory name that will show up in error messages)
-    force:     if 1, force compilation, even if timestamps are up-to-date
-    quiet:     if 1, be quiet during compilation
-
-    """
-    if not quiet:
-        print 'Listing', dir, '...'
-    try:
-        names = os.listdir(dir)
-    except os.error:
-        print "Can't list", dir
-        names = []
-    names.sort()
-    success = 1
-    for name in names:
-        fullname = os.path.join(dir, name)
-        if ddir is not None:
-            dfile = os.path.join(ddir, name)
-        else:
-            dfile = None
-        if rx is not None:
-            mo = rx.search(fullname)
-            if mo:
-                continue
-        if os.path.isfile(fullname):
-            head, tail = name[:-3], name[-3:]
-            if tail == '.py':
-                cfile = fullname + (__debug__ and 'c' or 'o')
-                ftime = os.stat(fullname).st_mtime
-                try: ctime = os.stat(cfile).st_mtime
-                except os.error: ctime = 0
-                if (ctime > ftime) and not force: continue
-                if not quiet:
-                    print 'Compiling', fullname, '...'
-                try:
-                    ok = py_compile.compile(fullname, None, dfile, True)
-                except KeyboardInterrupt:
-                    raise KeyboardInterrupt
-                except py_compile.PyCompileError,err:
-                    if quiet:
-                        print 'Compiling', fullname, '...'
-                    print err.msg
-                    success = 0
-                except IOError, e:
-                    print "Sorry", e
-                    success = 0
-                else:
-                    if ok == 0:
-                        success = 0
-        elif maxlevels > 0 and \
-             name != os.curdir and name != os.pardir and \
-             os.path.isdir(fullname) and \
-             not os.path.islink(fullname):
-            if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, quiet):
-                success = 0
-    return success
-
-def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0):
-    """Byte-compile all module on sys.path.
-
-    Arguments (all optional):
-
-    skip_curdir: if true, skip current directory (default true)
-    maxlevels:   max recursion level (default 0)
-    force: as for compile_dir() (default 0)
-    quiet: as for compile_dir() (default 0)
-
-    """
-    success = 1
-    for dir in sys.path:
-        if (not dir or dir == os.curdir) and skip_curdir:
-            print 'Skipping current directory'
-        else:
-            success = success and compile_dir(dir, maxlevels, None,
-                                              force, quiet=quiet)
-    return success
-
-def main():
-    """Script main program."""
-    import getopt
-    try:
-        opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:')
-    except getopt.error, msg:
-        print msg
-        print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \
-              "[-x regexp] [directory ...]"
-        print "-l: don't recurse down"
-        print "-f: force rebuild even if timestamps are up-to-date"
-        print "-q: quiet operation"
-        print "-d destdir: purported directory name for error messages"
-        print "   if no directory arguments, -l sys.path is assumed"
-        print "-x regexp: skip files matching the regular expression regexp"
-        print "   the regexp is search for in the full path of the file"
-        sys.exit(2)
-    maxlevels = 10
-    ddir = None
-    force = 0
-    quiet = 0
-    rx = None
-    for o, a in opts:
-        if o == '-l': maxlevels = 0
-        if o == '-d': ddir = a
-        if o == '-f': force = 1
-        if o == '-q': quiet = 1
-        if o == '-x':
-            import re
-            rx = re.compile(a)
-    if ddir:
-        if len(args) != 1:
-            print "-d destdir require exactly one directory argument"
-            sys.exit(2)
-    success = 1
-    try:
-        if args:
-            for dir in args:
-                if not compile_dir(dir, maxlevels, ddir,
-                                   force, rx, quiet):
-                    success = 0
-        else:
-            success = compile_path()
-    except KeyboardInterrupt:
-        print "\n[interrupt]"
-        success = 0
-    return success
-
-if __name__ == '__main__':
-    exit_status = int(not main())
-    sys.exit(exit_status)
diff --git a/src/main/python/debugserver.py b/src/main/python/debugserver.py
deleted file mode 100644
index d8c81f9..0000000
--- a/src/main/python/debugserver.py
+++ /dev/null
@@ -1,76 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-from threading import currentThread
-from SocketServer import BaseRequestHandler, TCPServer
-from code import InteractiveConsole
-
-_locals = None
-
-class DebugLogger(object):
-    def do_print(self, *args):
-        for i in args:
-            print i,
-        print
-    info = do_print
-    warn = do_print
-    debug = do_print
-_log = DebugLogger()
-
-
-class DebugConsole(InteractiveConsole):
-    def __init__(self, request):
-        self.request = request
-        InteractiveConsole.__init__(self, _locals)
-
-    def raw_input(self, prompt):
-        self.request.send(prompt)
-        data = self.request.recv(10000).rstrip()
-        if len(data) == 1 and ord(data[0]) == 4:
-            sys.exit()
-        return data
-
-    def write(self, data):
-        self.request.send(str(data))
-
-    def write_nl(self, data):
-        self.write(str(data)+"\r\n")
-
-class DebugServerHandler(BaseRequestHandler):
-    def __init__(self, request, client_address, server):
-        currentThread()._thread.setName("debugserver-%s:%d" % client_address)
-        _log.debug('Open connection to DebugServer from %s:%d' % client_address)
-        BaseRequestHandler.__init__(self, request, client_address, server)
-
-    def handle(self):
-        console = DebugConsole(self.request)
-        sys.displayhook = console.write_nl
-        console.interact('DebugServer')
-        self.request.close()
-
-class DebugServer(TCPServer):
-    daemon_threads = True
-    allow_reuse_address = True
-
-    def handle_error(self, request, client_address):
-        _log.debug('Closing connection to DebugServer from %s:%d' % client_address)
-        request.close()
-
-def run_server(port=6655, host='0.0.0.0', locals=locals()):
-    currentThread()._thread.setName("debugserver-main")
-
-    global _locals
-    _locals = locals
-    if "log" in locals.keys():
-        global _log
-        _log = locals["log"]
-
-    _log.info("Starting DebugServer on port %d" % port)
-    server = DebugServer(('', port), DebugServerHandler)
-    try:
-        server.serve_forever()
-    except KeyboardInterrupt:
-        pass
-
-if __name__ == "__main__":
-    run_server()
diff --git a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
index b4b4f27..c807205 100644
--- a/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
+++ b/src/main/resources/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule
@@ -5,24 +5,18 @@
 net.floodlightcontroller.topology.TopologyManager
 net.floodlightcontroller.forwarding.Forwarding
 net.floodlightcontroller.flowcache.FlowReconcileManager
-net.floodlightcontroller.core.OFMessageFilterManager
 net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher
 net.floodlightcontroller.perfmon.PktInProcessingTime
 net.floodlightcontroller.perfmon.NullPktInProcessingTime
 net.floodlightcontroller.restserver.RestApiServer
-net.floodlightcontroller.learningswitch.LearningSwitch
-net.floodlightcontroller.hub.Hub
-net.floodlightcontroller.jython.JythonDebugInterface
 net.floodlightcontroller.counter.CounterStore
 net.floodlightcontroller.counter.NullCounterStore
 net.floodlightcontroller.threadpool.ThreadPool
 net.floodlightcontroller.ui.web.StaticWebRoutable
-net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter
 net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier
 net.floodlightcontroller.devicemanager.test.MockDeviceManager
 net.floodlightcontroller.core.test.MockFloodlightProvider
 net.floodlightcontroller.core.test.MockThreadPoolService
-net.floodlightcontroller.firewall.Firewall
 net.floodlightcontroller.onoslistener.OnosPublisher
 net.floodlightcontroller.flowcache.FlowManager
 net.floodlightcontroller.routing.TopoRouteService
diff --git a/src/main/thrift/packetstreamer.thrift b/src/main/thrift/packetstreamer.thrift
deleted file mode 100644
index 827dd85..0000000
--- a/src/main/thrift/packetstreamer.thrift
+++ /dev/null
@@ -1,88 +0,0 @@
-#
-# Interface definition for packetstreamer service
-#
-
-namespace java net.floodlightcontroller.packetstreamer.thrift 
-namespace cpp net.floodlightcontroller.packetstreamer
-namespace py packetstreamer
-namespace php packetstreamer
-namespace perl packetstreamer
-
-const string VERSION = "0.1.0"
-
-#
-# data structures
-#
-
-/**
- * OFMessage type
- **/
-enum OFMessageType {
-  HELLO = 0,
-  ERROR = 1,
-  ECHO_REQUEST = 2,
-  ECHO_REPLY = 3,
-  VENDOR = 4,
-  FEATURES_REQUEST = 5,
-  FEATURES_REPLY = 6,
-  GET_CONFIG_REQUEST = 7,
-  GET_CONFIG_REPLY = 8,
-  SET_CONFIG = 9,
-  PACKET_IN = 10,
-  FLOW_REMOVED = 11,
-  PORT_STATUS = 12,
-  PACKET_OUT = 13,
-  FLOW_MOD = 14,
-  PORT_MOD = 15,
-  STATS_REQUEST = 16,
-  STATS_REPLY = 17,
-  BARRIER_REQUEST = 18,
-  BARRIER_REPLY = 19,
-}
-
-/**
- * A struct that defines switch port tuple
- */
-struct SwitchPortTuple {
-  1: i64 dpid,
-  2: i16 port,
-}
-
-struct Packet {
-  1: OFMessageType messageType,
-  2: SwitchPortTuple swPortTuple,
-  3: binary data,
-}
-
-struct Message {
-  1: list<string> sessionIDs,
-  2: Packet packet,
-}
-
-/**
- * Packetstreamer API
- */
-service PacketStreamer {
-
-   /**
-    * Synchronous method to get packets for a given sessionid
-    */
-   list<binary> getPackets(1:string sessionid),
-
-   /**
-    * Synchronous method to publish a packet.
-    * It ensure the order that the packets are pushed
-    */
-   i32 pushMessageSync(1:Message packet),
-
-   /** 
-    * Asynchronous method to publish a packet.
-    * Order is not guaranteed.
-    */
-   oneway void pushMessageAsync(1:Message packet)
-
-   /** 
-    * Terminate a session
-    */
-   void terminateSession(1:string sessionid)
-}
diff --git a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java b/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
deleted file mode 100644
index 959bb49..0000000
--- a/src/test/java/net/floodlightcontroller/firewall/FirewallTest.java
+++ /dev/null
@@ -1,513 +0,0 @@
-package net.floodlightcontroller.firewall;
-
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.packet.ARP;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.TCP;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.restserver.RestApiServer;
-import net.floodlightcontroller.routing.IRoutingDecision;
-import net.floodlightcontroller.storage.IStorageSourceService;
-import net.floodlightcontroller.storage.memory.MemoryStorageSource;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.util.MACAddress;
-
-import org.easymock.EasyMock;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFType;
-import org.openflow.util.HexString;
-
-/**
- * Unit test for stateless firewall implemented as a Google Summer of Code project.
- * 
- * @author Amer Tahir
- */
-public class FirewallTest extends FloodlightTestCase {
-    protected MockFloodlightProvider mockFloodlightProvider;
-    protected FloodlightContext cntx;
-    protected OFPacketIn packetIn;
-    protected IOFSwitch sw;
-    protected IPacket tcpPacket;
-    protected IPacket broadcastARPPacket;
-    protected IPacket ARPReplyPacket;
-    protected IPacket broadcastIPPacket;
-    protected IPacket tcpPacketReply;
-    protected IPacket broadcastMalformedPacket;
-    private Firewall firewall;
-    public static String TestSwitch1DPID = "00:00:00:00:00:00:00:01";
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        cntx = new FloodlightContext();
-        mockFloodlightProvider = getMockFloodlightProvider();
-        firewall = new Firewall();
-        IStorageSourceService storageService = new MemoryStorageSource();
-        RestApiServer restApi = new RestApiServer();
-
-        // Mock switches
-        long dpid = HexString.toLong(TestSwitch1DPID);
-        sw = EasyMock.createNiceMock(IOFSwitch.class);
-        expect(sw.getId()).andReturn(dpid).anyTimes();
-        expect(sw.getStringId()).andReturn(TestSwitch1DPID).anyTimes();
-        replay(sw);
-        // Load the switch map
-        Map<Long, IOFSwitch> switches = new HashMap<Long, IOFSwitch>();
-        switches.put(dpid, sw);
-        mockFloodlightProvider.setSwitches(switches);
-
-        FloodlightModuleContext fmc = new FloodlightModuleContext();
-        fmc.addService(IFloodlightProviderService.class, 
-                mockFloodlightProvider);
-        fmc.addService(IFirewallService.class, firewall);
-        fmc.addService(IStorageSourceService.class, storageService);
-        fmc.addService(IRestApiService.class, restApi);
-
-        try {
-            restApi.init(fmc);
-        } catch (FloodlightModuleException e) {
-            e.printStackTrace();
-        }
-
-        firewall.init(fmc);
-        firewall.startUp(fmc);
-
-        // Build our test packet
-        this.tcpPacket = new Ethernet()
-        .setDestinationMACAddress("00:11:22:33:44:55")
-        .setSourceMACAddress("00:44:33:22:11:00")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new TCP()
-                .setSourcePort((short) 81)
-                .setDestinationPort((short) 80)
-                .setPayload(new Data(new byte[] {0x01}))));
-        
-        // Build a broadcast ARP packet
-        this.broadcastARPPacket = new Ethernet()
-        .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
-        .setSourceMACAddress("00:44:33:22:11:00")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_ARP)
-        .setPayload(
-                new ARP()
-                .setHardwareType(ARP.HW_TYPE_ETHERNET)
-                .setProtocolType(ARP.PROTO_TYPE_IP)
-                .setOpCode(ARP.OP_REQUEST)
-                .setHardwareAddressLength((byte)6)
-                .setProtocolAddressLength((byte)4)
-                .setSenderHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
-                .setSenderProtocolAddress(IPv4.toIPv4Address("192.168.1.1"))
-                .setTargetHardwareAddress(Ethernet.toMACAddress("00:00:00:00:00:00"))
-                .setTargetProtocolAddress(IPv4.toIPv4Address("192.168.1.2"))
-                .setPayload(new Data(new byte[] {0x01})));
-        
-        // Build a ARP packet
-        this.ARPReplyPacket = new Ethernet()
-        .setDestinationMACAddress("00:44:33:22:11:00")
-        .setSourceMACAddress("00:11:22:33:44:55")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_ARP)
-        .setPayload(
-                new ARP()
-                .setHardwareType(ARP.HW_TYPE_ETHERNET)
-                .setProtocolType(ARP.PROTO_TYPE_IP)
-                .setOpCode(ARP.OP_REQUEST)
-                .setHardwareAddressLength((byte)6)
-                .setProtocolAddressLength((byte)4)
-                .setSenderHardwareAddress(Ethernet.toMACAddress("00:11:22:33:44:55"))
-                .setSenderProtocolAddress(IPv4.toIPv4Address("192.168.1.2"))
-                .setTargetHardwareAddress(Ethernet.toMACAddress("00:44:33:22:11:00"))
-                .setTargetProtocolAddress(IPv4.toIPv4Address("192.168.1.1"))
-                .setPayload(new Data(new byte[] {0x01})));
-        
-        // Build a broadcast IP packet
-        this.broadcastIPPacket = new Ethernet()
-        .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
-        .setSourceMACAddress("00:44:33:22:11:00")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.255")
-                .setPayload(new UDP()
-                .setSourcePort((short) 5000)
-                .setDestinationPort((short) 5001)
-                .setPayload(new Data(new byte[] {0x01}))));
-
-        // Build a malformed broadcast packet
-        this.broadcastMalformedPacket = new Ethernet()
-        .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
-        .setSourceMACAddress("00:44:33:22:11:00")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                .setSourcePort((short) 5000)
-                .setDestinationPort((short) 5001)
-                .setPayload(new Data(new byte[] {0x01}))));
-
-        this.tcpPacketReply = new Ethernet()
-        .setDestinationMACAddress("00:44:33:22:11:00")
-        .setSourceMACAddress("00:11:22:33:44:55")
-        .setVlanID((short) 42)
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.2")
-                .setDestinationAddress("192.168.1.1")
-                .setPayload(new TCP()
-                .setSourcePort((short) 80)
-                .setDestinationPort((short) 81)
-                .setPayload(new Data(new byte[] {0x02}))));
-    }
-
-    protected void setPacketIn(IPacket packet) {
-        byte[] serializedPacket = packet.serialize();
-        // Build the PacketIn
-        this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
-                .setBufferId(-1)
-                .setInPort((short) 1)
-                .setPacketData(serializedPacket)
-                .setReason(OFPacketInReason.NO_MATCH)
-                .setTotalLength((short) serializedPacket.length);
-
-        // Add the packet to the context store
-        IFloodlightProviderService.bcStore.
-        put(cntx, 
-                IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                (Ethernet)packet);
-    }
-
-    @Test
-    public void testNoRules() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-        // simulate a packet-in event
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        assertEquals(0, firewall.rules.size());
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        // no rules to match, so firewall should deny
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-    
-    @Test
-    public void testReadRulesFromStorage() throws Exception {
-        // add 2 rules first
-        FirewallRule rule = new FirewallRule();
-        rule.in_port = 2;
-        rule.dl_src = MACAddress.valueOf("00:00:00:00:00:01").toLong();
-        rule.dl_dst = MACAddress.valueOf("00:00:00:00:00:02").toLong();
-        rule.priority = 1;
-        rule.action = FirewallRule.FirewallAction.DENY;
-        firewall.addRule(rule);
-        rule = new FirewallRule();
-        rule.in_port = 3;
-        rule.dl_src = MACAddress.valueOf("00:00:00:00:00:02").toLong();
-        rule.dl_dst = MACAddress.valueOf("00:00:00:00:00:01").toLong();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.tp_dst = 80;
-        rule.priority = 2;
-        rule.action = FirewallRule.FirewallAction.ALLOW;
-        firewall.addRule(rule);
-
-        List<FirewallRule> rules = firewall.readRulesFromStorage();
-        // verify rule 1
-        FirewallRule r = rules.get(0);
-        assertEquals(r.in_port, 2);
-        assertEquals(r.priority, 1);
-        assertEquals(r.dl_src, MACAddress.valueOf("00:00:00:00:00:01").toLong());
-        assertEquals(r.dl_dst, MACAddress.valueOf("00:00:00:00:00:02").toLong());
-        assertEquals(r.action, FirewallRule.FirewallAction.DENY);
-        // verify rule 2
-        r = rules.get(1);
-        assertEquals(r.in_port, 3);
-        assertEquals(r.priority, 2);
-        assertEquals(r.dl_src, MACAddress.valueOf("00:00:00:00:00:02").toLong());
-        assertEquals(r.dl_dst, MACAddress.valueOf("00:00:00:00:00:01").toLong());
-        assertEquals(r.nw_proto, IPv4.PROTOCOL_TCP);
-        assertEquals(r.tp_dst, 80);
-        assertEquals(r.wildcard_nw_proto, false);
-        assertEquals(r.action, FirewallRule.FirewallAction.ALLOW);
-    }
-
-    @Test
-    public void testRuleInsertionIntoStorage() throws Exception {
-        // add TCP rule
-        FirewallRule rule = new FirewallRule();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        List<Map<String, Object>> rulesFromStorage = firewall.getStorageRules();
-        assertEquals(1, rulesFromStorage.size());
-        assertEquals(Integer.parseInt((String)rulesFromStorage.get(0).get("ruleid")), rule.ruleid);
-    }
-
-    @Test
-    public void testRuleDeletion() throws Exception {
-        // add TCP rule
-        FirewallRule rule = new FirewallRule();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-        int rid = rule.ruleid;
-
-        List<Map<String, Object>> rulesFromStorage = firewall.getStorageRules();
-        assertEquals(1, rulesFromStorage.size());
-        assertEquals(Integer.parseInt((String)rulesFromStorage.get(0).get("ruleid")), rid);
-
-        // delete rule
-        firewall.deleteRule(rid);
-        rulesFromStorage = firewall.getStorageRules();
-        assertEquals(0, rulesFromStorage.size());
-    }
-
-    @Test
-    public void testFirewallDisabled() throws Exception {
-        // firewall isn't enabled by default
-        // so, it shouldn't make any decision
-
-        // add TCP rule
-        FirewallRule rule = new FirewallRule();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        assertEquals(1, firewall.rules.size());
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertNull(decision);
-    }
-
-    @Test
-    public void testSimpleAllowRule() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-
-        // add TCP rule
-        FirewallRule rule = new FirewallRule();
-        rule.dl_type = Ethernet.TYPE_IPv4;
-        rule.wildcard_dl_type = false;
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        // source is IP 192.168.1.2
-        rule.nw_src_prefix = IPv4.toIPv4Address("192.168.1.2");
-        rule.wildcard_nw_src = false;
-        // dest is network 192.168.1.0/24
-        rule.nw_dst_prefix = IPv4.toIPv4Address("192.168.1.0");
-        rule.nw_dst_maskbits = 24;
-        rule.wildcard_nw_dst = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        // simulate a packet-in events
-
-        this.setPacketIn(tcpPacketReply);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-
-        // clear decision
-        IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
-
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-
-    @Test
-    public void testOverlappingRules() throws Exception {
-        firewall.enableFirewall(true);
-
-        // add TCP port 80 (destination only) allow rule
-        FirewallRule rule = new FirewallRule();
-        rule.dl_type = Ethernet.TYPE_IPv4;
-        rule.wildcard_dl_type = false;
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.tp_dst = 80;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        // add block all rule
-        rule = new FirewallRule();
-        rule.action = FirewallRule.FirewallAction.DENY;
-        rule.priority = 2;
-        firewall.addRule(rule);
-
-        assertEquals(2, firewall.rules.size());
-
-        // packet destined to TCP port 80 - should be allowed
-
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-
-        // clear decision
-        IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
-
-        // packet destined for port 81 - should be denied
-
-        this.setPacketIn(tcpPacketReply);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-
-    @Test
-    public void testARP() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-
-        // no rules inserted so all traffic other than broadcast and ARP-request-broadcast should be blocked
-
-        // simulate an ARP broadcast packet-in event
-
-        this.setPacketIn(broadcastARPPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        // broadcast-ARP traffic should be allowed
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(IRoutingDecision.RoutingAction.MULTICAST, decision.getRoutingAction());
-        
-        // clear decision
-        IRoutingDecision.rtStore.remove(cntx, IRoutingDecision.CONTEXT_DECISION);
-        
-        // simulate an ARP reply packet-in event
-
-        this.setPacketIn(ARPReplyPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        // ARP reply traffic should be denied
-        decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-    
-    @Test
-    public void testIPBroadcast() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-        
-        // set subnet mask for IP broadcast
-        firewall.setSubnetMask("255.255.255.0");
-
-        // no rules inserted so all traffic other than broadcast and ARP-request-broadcast should be blocked
-
-        // simulate a packet-in event
-
-        this.setPacketIn(broadcastIPPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        // broadcast traffic should be allowed
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(IRoutingDecision.RoutingAction.MULTICAST, decision.getRoutingAction());
-    }
-
-    @Test
-    public void testMalformedIPBroadcast() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-
-        // no rules inserted so all traffic other than broadcast and ARP-request-broadcast should be blocked
-
-        // simulate a packet-in event
-
-        this.setPacketIn(broadcastMalformedPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        // malformed broadcast traffic should NOT be allowed
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.DROP);
-    }
-
-    @Test
-    public void testLayer2Rule() throws Exception {
-        // enable firewall first
-        firewall.enableFirewall(true);
-
-        // add L2 rule
-        FirewallRule rule = new FirewallRule();
-        rule.dl_src = MACAddress.valueOf("00:44:33:22:11:00").toLong();
-        rule.wildcard_dl_src = false;
-        rule.dl_dst = MACAddress.valueOf("00:11:22:33:44:55").toLong();
-        rule.wildcard_dl_dst = false;
-        rule.priority = 1;
-        firewall.addRule(rule);
-
-        // add TCP deny all rule
-        rule = new FirewallRule();
-        rule.nw_proto = IPv4.PROTOCOL_TCP;
-        rule.wildcard_nw_proto = false;
-        rule.priority = 2;
-        rule.action = FirewallRule.FirewallAction.DENY;
-        firewall.addRule(rule);
-
-        // simulate a packet-in event
-
-        this.setPacketIn(tcpPacket);
-        firewall.receive(sw, this.packetIn, cntx);
-        verify(sw);
-
-        IRoutingDecision decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);
-        assertEquals(decision.getRoutingAction(), IRoutingDecision.RoutingAction.FORWARD_OR_FLOOD);
-    }
-}
diff --git a/src/test/java/net/floodlightcontroller/hub/HubTest.java b/src/test/java/net/floodlightcontroller/hub/HubTest.java
deleted file mode 100644
index b4a215c..0000000
--- a/src/test/java/net/floodlightcontroller/hub/HubTest.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    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 net.floodlightcontroller.hub;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-import static org.easymock.EasyMock.capture;
-
-import java.util.Arrays;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.test.FloodlightTestCase;
-
-import org.easymock.Capture;
-import org.easymock.CaptureType;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class HubTest extends FloodlightTestCase {
-    protected OFPacketIn packetIn;
-    protected IPacket testPacket;
-    protected byte[] testPacketSerialized;
-    private   MockFloodlightProvider mockFloodlightProvider;
-    private Hub hub;
-    
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        mockFloodlightProvider = getMockFloodlightProvider();
-        hub = new Hub();
-        mockFloodlightProvider.addOFMessageListener(OFType.PACKET_IN, hub);
-        hub.setFloodlightProvider(mockFloodlightProvider);
-        
-        // Build our test packet
-        this.testPacket = new Ethernet()
-            .setDestinationMACAddress("00:11:22:33:44:55")
-            .setSourceMACAddress("00:44:33:22:11:00")
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                            .setSourcePort((short) 5000)
-                            .setDestinationPort((short) 5001)
-                            .setPayload(new Data(new byte[] {0x01}))));
-        this.testPacketSerialized = testPacket.serialize();
-
-        // Build the PacketIn
-        this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
-            .setBufferId(-1)
-            .setInPort((short) 1)
-            .setPacketData(this.testPacketSerialized)
-            .setReason(OFPacketInReason.NO_MATCH)
-            .setTotalLength((short) this.testPacketSerialized.length);
-    }
-
-    @Test
-    public void testFloodNoBufferId() throws Exception {
-        // build our expected flooded packetOut
-        OFPacketOut po = ((OFPacketOut) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT))
-            .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-            .setBufferId(-1)
-            .setInPort((short) 1)
-            .setPacketData(this.testPacketSerialized);
-        po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU()
-                + this.testPacketSerialized.length);
-
-        // Mock up our expected behavior
-        IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        
-        Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
-        Capture<FloodlightContext> bc1 = new Capture<FloodlightContext>(CaptureType.ALL);
-        
-        mockSwitch.write(capture(wc1), capture(bc1));
-
-        // Start recording the replay on the mocks
-        replay(mockSwitch);
-        // Get the listener and trigger the packet in
-        IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
-                OFType.PACKET_IN).get(0);
-        listener.receive(mockSwitch, this.packetIn,
-                         parseAndAnnotate(this.packetIn));
-
-        // Verify the replay matched our expectations
-        verify(mockSwitch);
-        
-        assertTrue(wc1.hasCaptured());
-        OFMessage m = wc1.getValue();
-        assert(m.equals(po));
-    }
-
-    @Test
-    public void testFloodBufferId() throws Exception {
-        MockFloodlightProvider mockFloodlightProvider = getMockFloodlightProvider();
-        this.packetIn.setBufferId(10);
-
-        // build our expected flooded packetOut
-        OFPacketOut po = ((OFPacketOut) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_OUT))
-            .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-            .setBufferId(10)
-            .setInPort((short) 1);
-        po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU());
-
-        // Mock up our expected behavior
-        IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        Capture<OFMessage> wc1 = new Capture<OFMessage>(CaptureType.ALL);
-        Capture<FloodlightContext> bc1 = new Capture<FloodlightContext>(CaptureType.ALL);
-        
-        mockSwitch.write(capture(wc1), capture(bc1));
-
-        // Start recording the replay on the mocks
-        replay(mockSwitch);
-        // Get the listener and trigger the packet in
-        IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
-                OFType.PACKET_IN).get(0);
-        listener.receive(mockSwitch, this.packetIn,
-                         parseAndAnnotate(this.packetIn));
-
-        // Verify the replay matched our expectations
-        verify(mockSwitch);
-        
-        assertTrue(wc1.hasCaptured());
-        OFMessage m = wc1.getValue();
-        assert(m.equals(po));
-    }
-}
diff --git a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java b/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
deleted file mode 100644
index a68a1b8..0000000
--- a/src/test/java/net/floodlightcontroller/learningswitch/LearningSwitchTest.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/**
-*    Copyright 2011, Big Switch Networks, Inc. 
-*    Originally created by David Erickson, Stanford University
-* 
-*    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 net.floodlightcontroller.learningswitch;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.easymock.EasyMock.verify;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightTestModuleLoader;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.test.MockFloodlightProvider;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.test.FloodlightTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionOutput;
-
-/**
- *
- * @author David Erickson (daviderickson@cs.stanford.edu)
- */
-public class LearningSwitchTest extends FloodlightTestCase {
-    protected OFPacketIn packetIn;
-    protected IPacket testPacket;
-    protected byte[] testPacketSerialized;
-    protected IPacket broadcastPacket;
-    protected byte[] broadcastPacketSerialized;
-    protected IPacket testPacketReply;
-    protected byte[] testPacketReplySerialized;
-    private LearningSwitch learningSwitch;
-    
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-        FloodlightTestModuleLoader fml = new FloodlightTestModuleLoader();
-        Collection<Class<? extends IFloodlightModule>> mods 
-        	= new ArrayList<Class<? extends IFloodlightModule>>();
-        mods.add(LearningSwitch.class);
-        fml.setupModules(mods, null);
-        learningSwitch = (LearningSwitch) fml.getModuleByName(LearningSwitch.class);
-        mockFloodlightProvider = 
-        		(MockFloodlightProvider) fml.getModuleByName(MockFloodlightProvider.class);
-       
-        // Build our test packet
-        this.testPacket = new Ethernet()
-            .setDestinationMACAddress("00:11:22:33:44:55")
-            .setSourceMACAddress("00:44:33:22:11:00")
-            .setVlanID((short) 42)
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                            .setSourcePort((short) 5000)
-                            .setDestinationPort((short) 5001)
-                            .setPayload(new Data(new byte[] {0x01}))));
-        this.testPacketSerialized = testPacket.serialize();
-        // Build a broadcast packet
-        this.broadcastPacket = new Ethernet()
-            .setDestinationMACAddress("FF:FF:FF:FF:FF:FF")
-            .setSourceMACAddress("00:44:33:22:11:00")
-            .setVlanID((short) 42)
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.255.255")
-                .setPayload(new UDP()
-                        .setSourcePort((short) 5000)
-                        .setDestinationPort((short) 5001)
-                        .setPayload(new Data(new byte[] {0x01}))));
-
-        this.broadcastPacketSerialized = broadcastPacket.serialize();
-        this.testPacketReply = new Ethernet()
-            .setDestinationMACAddress("00:44:33:22:11:00")
-            .setSourceMACAddress("00:11:22:33:44:55")
-            .setVlanID((short) 42)
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                    new IPv4()
-                    .setTtl((byte) 128)
-                    .setSourceAddress("192.168.1.2")
-                    .setDestinationAddress("192.168.1.1")
-                    .setPayload(new UDP()
-                    .setSourcePort((short) 5001)
-                    .setDestinationPort((short) 5000)
-                    .setPayload(new Data(new byte[] {0x02}))));
-        this.testPacketReplySerialized = testPacketReply.serialize();
-
-        // Build the PacketIn
-        this.packetIn = ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.PACKET_IN))
-            .setBufferId(-1)
-            .setInPort((short) 1)
-            .setPacketData(this.testPacketSerialized)
-            .setReason(OFPacketInReason.NO_MATCH)
-            .setTotalLength((short) this.testPacketSerialized.length);
-    }
-
-    @Test
-    public void testFlood() throws Exception {
-        // build our expected flooded packetOut
-        OFPacketOut po = new OFPacketOut()
-            .setActions(Arrays.asList(new OFAction[] {new OFActionOutput().setPort(OFPort.OFPP_FLOOD.getValue())}))
-            .setActionsLength((short) OFActionOutput.MINIMUM_LENGTH)
-            .setBufferId(-1)
-            .setInPort((short)1)
-            .setPacketData(this.testPacketSerialized);
-        po.setLengthU(OFPacketOut.MINIMUM_LENGTH + po.getActionsLengthU()
-                + this.testPacketSerialized.length);
-
-        // Mock up our expected behavior
-        IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        expect(mockSwitch.getStringId()).andReturn("00:11:22:33:44:55:66:77").anyTimes();
-        mockSwitch.write(po, null);
-
-        // Start recording the replay on the mocks
-        replay(mockSwitch);
-        // Get the listener and trigger the packet in
-        IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
-                OFType.PACKET_IN).get(0);
-        // Make sure it's the right listener
-        listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn));
-
-        // Verify the replay matched our expectations      
-        short result = learningSwitch.getFromPortMap(mockSwitch, Ethernet.toLong(Ethernet.toMACAddress("00:44:33:22:11:00")), (short) 42).shortValue();
-        verify(mockSwitch);
-
-        // Verify the MAC table inside the switch
-        assertEquals(1, result);
-    }
-    
-    @Test
-    public void testFlowMod() throws Exception {
-        // tweak the test packet in since we need a bufferId
-        this.packetIn.setBufferId(50);
-
-        // build expected flow mods
-        OFMessage fm1 = ((OFFlowMod) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD))
-            .setActions(Arrays.asList(new OFAction[] {
-                    new OFActionOutput().setPort((short) 2).setMaxLength((short) -1)}))
-            .setBufferId(50)
-            .setCommand(OFFlowMod.OFPFC_ADD)
-            .setIdleTimeout((short) 5)
-            .setMatch(new OFMatch()
-                .loadFromPacket(testPacketSerialized, (short) 1)
-                .setWildcards(OFMatch.OFPFW_NW_PROTO | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST
-                        | OFMatch.OFPFW_NW_TOS))
-            .setOutPort(OFPort.OFPP_NONE.getValue())
-            .setCookie(1L << 52)
-            .setPriority((short) 100)
-            .setFlags((short)(1 << 0))
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-        OFMessage fm2 = ((OFFlowMod) mockFloodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD))
-            .setActions(Arrays.asList(new OFAction[] {
-                    new OFActionOutput().setPort((short) 1).setMaxLength((short) -1)}))
-            .setBufferId(-1)
-            .setCommand(OFFlowMod.OFPFC_ADD)
-            .setIdleTimeout((short) 5)
-            .setMatch(new OFMatch()
-                .loadFromPacket(testPacketReplySerialized, (short) 2)
-                .setWildcards(OFMatch.OFPFW_NW_PROTO | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST
-                        | OFMatch.OFPFW_NW_TOS))
-            .setOutPort(OFPort.OFPP_NONE.getValue())
-            .setCookie(1L << 52)
-            .setPriority((short) 100)
-            .setFlags((short)(1 << 0))
-            .setLengthU(OFFlowMod.MINIMUM_LENGTH+OFActionOutput.MINIMUM_LENGTH);
-
-        // Mock up our expected behavior
-        IOFSwitch mockSwitch = createMock(IOFSwitch.class);
-        expect(mockSwitch.getId()).andReturn(1L).anyTimes();
-        expect(mockSwitch.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer) (OFMatch.OFPFW_IN_PORT | OFMatch.OFPFW_NW_PROTO
-                | OFMatch.OFPFW_TP_SRC | OFMatch.OFPFW_TP_DST | OFMatch.OFPFW_NW_SRC_ALL
-                | OFMatch.OFPFW_NW_DST_ALL | OFMatch.OFPFW_NW_TOS));
-        mockSwitch.write(fm1, null);
-        mockSwitch.write(fm2, null);
-
-        // Start recording the replay on the mocks
-        replay(mockSwitch);
-
-        // Populate the MAC table
-        learningSwitch.addToPortMap(mockSwitch,
-                Ethernet.toLong(Ethernet.toMACAddress("00:11:22:33:44:55")), (short) 42, (short) 2);
-        
-        // Get the listener and trigger the packet in
-        IOFMessageListener listener = mockFloodlightProvider.getListeners().get(
-                OFType.PACKET_IN).get(0);
-        listener.receive(mockSwitch, this.packetIn, parseAndAnnotate(this.packetIn));
-        
-        // Verify the replay matched our expectations
-        short result = learningSwitch.getFromPortMap(mockSwitch, Ethernet.toLong(Ethernet.toMACAddress("00:44:33:22:11:00")), (short) 42).shortValue();
-        verify(mockSwitch);
-
-        // Verify the MAC table inside the switch
-        assertEquals(1, result);
-    }
-}
diff --git a/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java b/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java
deleted file mode 100644
index 32afe4e..0000000
--- a/src/test/java/net/floodlightcontroller/virtualnetwork/VirtualNetworkFilterTest.java
+++ /dev/null
@@ -1,375 +0,0 @@
-package net.floodlightcontroller.virtualnetwork;
-
-import static org.easymock.EasyMock.*;
-
-import java.util.List;
-
-import org.easymock.EasyMock;
-import org.junit.Before;
-import org.junit.Test;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFPacketIn;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.OFPacketIn.OFPacketInReason;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IListener.Command;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.test.MockThreadPoolService;
-import net.floodlightcontroller.core.test.PacketFactory;
-import net.floodlightcontroller.devicemanager.IDeviceService;
-import net.floodlightcontroller.devicemanager.IEntityClassifierService;
-import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
-import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
-import net.floodlightcontroller.flowcache.FlowReconcileManager;
-import net.floodlightcontroller.flowcache.IFlowReconcileService;
-import net.floodlightcontroller.packet.Data;
-import net.floodlightcontroller.packet.Ethernet;
-import net.floodlightcontroller.packet.IPacket;
-import net.floodlightcontroller.packet.IPv4;
-import net.floodlightcontroller.packet.UDP;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.restserver.RestApiServer;
-import net.floodlightcontroller.test.FloodlightTestCase;
-import net.floodlightcontroller.threadpool.IThreadPoolService;
-import net.floodlightcontroller.topology.ITopologyService;
-import net.floodlightcontroller.util.MACAddress;
-import net.floodlightcontroller.virtualnetwork.VirtualNetworkFilter;
-
-public class VirtualNetworkFilterTest extends FloodlightTestCase {
-    protected VirtualNetworkFilter vns;
-    protected MockDeviceManager deviceService;
-    
-    protected static String guid1 = "guid1";
-    protected static String net1 = "net1";
-    protected static String gw1 = "1.1.1.1";
-    protected static String guid2 = "guid2";
-    protected static String net2 = "net2";
-    protected static String guid3 = "guid3";
-    protected static String net3 = "net3";
-    protected static String gw2 = "2.2.2.2";
-    
-    protected static MACAddress mac1 = 
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:55"));
-    protected static MACAddress mac2 = 
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:66"));
-    protected static MACAddress mac3 = 
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:77"));
-    protected static MACAddress mac4 = 
-            new MACAddress(Ethernet.toMACAddress("00:11:22:33:44:88"));
-    protected static String hostPort1 = "port1";
-    protected static String hostPort2 = "port2";
-    protected static String hostPort3 = "port3";
-    protected static String hostPort4 = "port4";
-    
-    // For testing forwarding behavior
-    protected IOFSwitch sw1;
-    protected FloodlightContext cntx;
-    protected OFPacketIn mac1ToMac2PacketIn;
-    protected IPacket mac1ToMac2PacketIntestPacket;
-    protected byte[] mac1ToMac2PacketIntestPacketSerialized;
-    protected OFPacketIn mac1ToMac4PacketIn;
-    protected IPacket mac1ToMac4PacketIntestPacket;
-    protected byte[] mac1ToMac4PacketIntestPacketSerialized;
-    protected OFPacketIn mac1ToGwPacketIn;
-    protected IPacket mac1ToGwPacketIntestPacket;
-    protected byte[] mac1ToGwPacketIntestPacketSerialized;
-    protected OFPacketIn packetInDHCPDiscoveryRequest;
-    
-    @Before
-    public void setUp() throws Exception {
-        super.setUp();
-
-        // Module loading stuff
-        FloodlightModuleContext fmc = new FloodlightModuleContext();
-        RestApiServer restApi = new RestApiServer();
-        deviceService = new MockDeviceManager();
-        FlowReconcileManager frm = new FlowReconcileManager();
-        MockThreadPoolService tps = new MockThreadPoolService();
-        ITopologyService topology = createMock(ITopologyService.class);
-        vns = new VirtualNetworkFilter();
-        DefaultEntityClassifier entityClassifier = new DefaultEntityClassifier();
-        fmc.addService(IRestApiService.class, restApi);
-        fmc.addService(IFloodlightProviderService.class, getMockFloodlightProvider());
-        fmc.addService(IDeviceService.class, deviceService);
-        fmc.addService(IFlowReconcileService.class, frm);
-        fmc.addService(IThreadPoolService.class, tps);
-        fmc.addService(IEntityClassifierService.class, entityClassifier);
-        fmc.addService(ITopologyService.class, topology);
-        tps.init(fmc);
-        frm.init(fmc);
-        deviceService.init(fmc);
-        restApi.init(fmc);
-        getMockFloodlightProvider().init(fmc);
-        entityClassifier.init(fmc);
-        tps.startUp(fmc);
-        vns.init(fmc);
-        frm.startUp(fmc);
-        deviceService.startUp(fmc);
-        restApi.startUp(fmc);
-        getMockFloodlightProvider().startUp(fmc);
-        vns.startUp(fmc);
-        entityClassifier.startUp(fmc);
-
-        topology.addListener(deviceService);
-        expectLastCall().times(1);
-        replay(topology);
-        // Mock switches
-        //fastWilcards mocked as this constant
-        int fastWildcards = 
-                OFMatch.OFPFW_IN_PORT | 
-                OFMatch.OFPFW_NW_PROTO | 
-                OFMatch.OFPFW_TP_SRC | 
-                OFMatch.OFPFW_TP_DST | 
-                OFMatch.OFPFW_NW_SRC_ALL | 
-                OFMatch.OFPFW_NW_DST_ALL |
-                OFMatch.OFPFW_NW_TOS;
-        sw1 = EasyMock.createNiceMock(IOFSwitch.class);
-        expect(sw1.getId()).andReturn(1L).anyTimes();
-        expect(sw1.getAttribute(IOFSwitch.PROP_FASTWILDCARDS)).andReturn((Integer)fastWildcards).anyTimes();
-        expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
-        replay(sw1);
-        
-        // Mock packets
-        // Mock from MAC1 -> MAC2
-        mac1ToMac2PacketIntestPacket = new Ethernet()
-            .setDestinationMACAddress(mac2.toBytes())
-            .setSourceMACAddress(mac1.toBytes())
-            .setEtherType(Ethernet.TYPE_IPv4)
-            .setPayload(
-                new IPv4()
-                .setTtl((byte) 128)
-                .setSourceAddress("192.168.1.1")
-                .setDestinationAddress("192.168.1.2")
-                .setPayload(new UDP()
-                            .setSourcePort((short) 5000)
-                            .setDestinationPort((short) 5001)
-                            .setPayload(new Data(new byte[] {0x01}))));
-        mac1ToMac2PacketIntestPacketSerialized = mac1ToMac2PacketIntestPacket.serialize();
-        mac1ToMac2PacketIn = 
-                ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                        getMessage(OFType.PACKET_IN))
-                        .setBufferId(-1)
-                        .setInPort((short) 1)
-                        .setPacketData(mac1ToMac2PacketIntestPacketSerialized)
-                        .setReason(OFPacketInReason.NO_MATCH)
-                        .setTotalLength((short) mac1ToMac2PacketIntestPacketSerialized.length);
-        
-        // Mock from MAC1 -> MAC4
-        mac1ToMac4PacketIntestPacket = new Ethernet()
-        .setDestinationMACAddress(mac4.toBytes())
-        .setSourceMACAddress(mac1.toBytes())
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-            new IPv4()
-            .setTtl((byte) 128)
-            .setSourceAddress("192.168.1.1")
-            .setDestinationAddress("192.168.1.2")
-            .setPayload(new UDP()
-                        .setSourcePort((short) 5000)
-                        .setDestinationPort((short) 5001)
-                        .setPayload(new Data(new byte[] {0x01}))));
-        mac1ToMac4PacketIntestPacketSerialized = mac1ToMac4PacketIntestPacket.serialize();
-        mac1ToMac4PacketIn = 
-            ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.PACKET_IN))
-                    .setBufferId(-1)
-                    .setInPort((short) 1)
-                    .setPacketData(mac1ToMac4PacketIntestPacketSerialized)
-                    .setReason(OFPacketInReason.NO_MATCH)
-                    .setTotalLength((short) mac1ToMac4PacketIntestPacketSerialized.length);
-        
-        // Mock from MAC1 to gateway1
-        mac1ToGwPacketIntestPacket = new Ethernet()
-        .setDestinationMACAddress("00:11:33:33:44:55") // mac shouldn't matter, can't be other host
-        .setSourceMACAddress(mac1.toBytes())
-        .setEtherType(Ethernet.TYPE_IPv4)
-        .setPayload(
-            new IPv4()
-            .setTtl((byte) 128)
-            .setSourceAddress("192.168.1.1")
-            .setDestinationAddress(gw1)
-            .setPayload(new UDP()
-                        .setSourcePort((short) 5000)
-                        .setDestinationPort((short) 5001)
-                        .setPayload(new Data(new byte[] {0x01}))));
-        mac1ToGwPacketIntestPacketSerialized = mac1ToGwPacketIntestPacket.serialize();
-        mac1ToGwPacketIn = 
-            ((OFPacketIn) mockFloodlightProvider.getOFMessageFactory().
-                    getMessage(OFType.PACKET_IN))
-                    .setBufferId(-1)
-                    .setInPort((short) 1)
-                    .setPacketData(mac1ToGwPacketIntestPacketSerialized)
-                    .setReason(OFPacketInReason.NO_MATCH)
-                    .setTotalLength((short) mac1ToGwPacketIntestPacketSerialized.length);
-    }
-    
-    @Test
-    public void testCreateNetwork() {
-        // Test creating a network with all parameters
-        vns.createNetwork(guid1, net1, IPv4.toIPv4Address(gw1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.nameToGuid.get(net1).equals(guid1));
-        assertTrue(vns.guidToGateway.get(guid1).equals(IPv4.toIPv4Address(gw1)));
-        assertTrue(vns.vNetsByGuid.get(guid1).name.equals(net1));
-        assertTrue(vns.vNetsByGuid.get(guid1).guid.equals(guid1));
-        assertTrue(vns.vNetsByGuid.get(guid1).gateway.equals(gw1));
-        assertTrue(vns.vNetsByGuid.get(guid1).hosts.size()==0);
-
-        // Test creating network without a gateway
-        vns.createNetwork(guid2, net2, null);
-        assertTrue(vns.nameToGuid.get(net2).equals(guid2));
-        assertTrue(vns.guidToGateway.get(guid2) == null);
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 1);
-        assertTrue(vns.vNetsByGuid.get(guid2).name.equals(net2));
-        assertTrue(vns.vNetsByGuid.get(guid2).guid.equals(guid2));
-        assertTrue(vns.vNetsByGuid.get(guid2).gateway == null);
-        assertTrue(vns.vNetsByGuid.get(guid2).hosts.size()==0);
-        
-        // Test creating a network that shares the gateway with net1
-        vns.createNetwork(guid3, net3, IPv4.toIPv4Address(gw1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 2);
-        assertTrue(vns.nameToGuid.get(net3).equals(guid3));
-        assertTrue(vns.guidToGateway.get(guid3).equals(IPv4.toIPv4Address(gw1)));
-        assertTrue(vns.vNetsByGuid.get(guid3).name.equals(net3));
-        assertTrue(vns.vNetsByGuid.get(guid3).guid.equals(guid3));
-        assertTrue(vns.vNetsByGuid.get(guid3).gateway.equals(gw1));
-        assertTrue(vns.vNetsByGuid.get(guid3).hosts.size()==0);
-
-    }
-    
-    @Test
-    public void testModifyNetwork() {
-        // Create some networks
-        
-        testCreateNetwork();
-        // Modify net2 to add a gateway
-        vns.createNetwork(guid2, net2, IPv4.toIPv4Address(gw1));
-        assertTrue(vns.nameToGuid.get(net2).equals(guid2));
-        assertTrue(vns.guidToGateway.get(guid2).equals(IPv4.toIPv4Address(gw1)));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid2));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 3);
-        // Modify net2 to change it's name
-        vns.createNetwork(guid2, "newnet2", null);
-        // Make sure the gateway is still there
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid2));
-        assertTrue(vns.vNetsByGuid.get(guid2).gateway.equals(gw1));
-        // make sure the new name mapping was learned
-        assertTrue(vns.nameToGuid.get("newnet2").equals(guid2));
-        assertTrue(vns.vNetsByGuid.get(guid2).name.equals("newnet2"));
-        // and the old one was deleted
-        assertFalse(vns.nameToGuid.containsKey(net2));
-    }
-    
-    @Test
-    public void testDeleteNetwork() {
-        testModifyNetwork();
-        // Delete newnet2
-        vns.deleteNetwork(guid2);
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid1));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).contains(guid3));
-        assertTrue(vns.gatewayToGuid.get(IPv4.toIPv4Address(gw1)).size() == 2);
-        assertFalse(vns.nameToGuid.containsKey(net2));
-        assertFalse(vns.guidToGateway.containsKey(net2));
-        assertTrue(vns.vNetsByGuid.get(guid2)==null);
-    }
-    
-    @Test
-    public void testAddHost() {
-        testModifyNetwork();
-        vns.addHost(mac1, guid1, hostPort1);
-        assertTrue(vns.macToGuid.get(mac1).equals(guid1));
-        assertTrue(vns.portToMac.get(hostPort1).equals(mac1));
-        assertTrue(vns.vNetsByGuid.get(guid1).hosts.contains(mac1));
-        vns.addHost(mac2, guid1, hostPort2);
-        assertTrue(vns.macToGuid.get(mac2).equals(guid1));
-        assertTrue(vns.portToMac.get(hostPort2).equals(mac2));
-        assertTrue(vns.vNetsByGuid.get(guid1).hosts.contains(mac2));
-        vns.addHost(mac3, guid3, hostPort3);
-        vns.addHost(mac4, guid3, hostPort4);
-        assertTrue(vns.vNetsByGuid.get(guid3).hosts.contains(mac4));
-    }
-    
-    @Test
-    public void testDeleteHost() {
-        testAddHost();
-
-        String host1Guid = vns.macToGuid.get(mac1);
-        vns.deleteHost(mac1, null);
-        assertFalse(vns.macToGuid.containsKey(mac1));
-        assertFalse(vns.portToMac.containsKey(hostPort1));
-        assertFalse(vns.vNetsByGuid.get(host1Guid).hosts.contains(mac1));
-        
-        String host2Guid = vns.macToGuid.get(vns.portToMac.get(hostPort2));
-        vns.deleteHost(null, hostPort2);
-        assertFalse(vns.macToGuid.containsKey(mac2));
-        assertFalse(vns.portToMac.containsKey(hostPort2));
-        assertFalse(vns.vNetsByGuid.get(host2Guid).hosts.contains(mac2));
-
-        String host3Guid = vns.macToGuid.get(mac3);        
-        vns.deleteHost(mac3, hostPort3);
-        assertFalse(vns.macToGuid.containsKey(mac3));
-        assertFalse(vns.portToMac.containsKey(hostPort3));
-        assertFalse(vns.vNetsByGuid.get(host3Guid).hosts.contains(mac3));
-        
-    }
-    
-    @Test
-    public void testForwarding() {
-        testAddHost();
-        // make sure mac1 can communicate with mac2
-        IOFMessageListener listener = getVirtualNetworkListener();
-        cntx = new FloodlightContext();
-        IFloodlightProviderService.bcStore.put(cntx, 
-                           IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                               (Ethernet)mac1ToMac2PacketIntestPacket);
-        Command ret = listener.receive(sw1, mac1ToMac2PacketIn, cntx);
-        assertTrue(ret == Command.CONTINUE);
-        // make sure mac1 can't communicate with mac4
-        cntx = new FloodlightContext();
-        IFloodlightProviderService.bcStore.put(cntx,
-                           IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                               (Ethernet)mac1ToMac4PacketIntestPacket);
-        ret = listener.receive(sw1, mac1ToMac4PacketIn, cntx);
-        assertTrue(ret == Command.STOP);
-    }
-
-    @Test
-    public void testDefaultGateway() {
-        testAddHost();
-        IOFMessageListener listener = getVirtualNetworkListener();
-        cntx = new FloodlightContext();
-        IFloodlightProviderService.bcStore.put(cntx, 
-                           IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                               (Ethernet)mac1ToGwPacketIntestPacket);
-        deviceService.learnEntity(((Ethernet)mac1ToGwPacketIntestPacket).getDestinationMAC().toLong(), 
-        		null, IPv4.toIPv4Address(gw1), null, null);
-        Command ret = listener.receive(sw1, mac1ToGwPacketIn, cntx);
-        assertTrue(ret == Command.CONTINUE);
-    }
-    
-    @Test
-    public void testDhcp() {
-        IOFMessageListener listener = getVirtualNetworkListener();
-        Ethernet dhcpPacket = PacketFactory.DhcpDiscoveryRequestEthernet(mac1);
-        OFPacketIn dhcpPacketOf = PacketFactory.DhcpDiscoveryRequestOFPacketIn(mac1);
-        cntx = new FloodlightContext();
-        IFloodlightProviderService.bcStore.put(cntx, 
-                           IFloodlightProviderService.CONTEXT_PI_PAYLOAD, 
-                           dhcpPacket);
-        Command ret = listener.receive(sw1, dhcpPacketOf, cntx);
-        assertTrue(ret == Command.CONTINUE);
-    }
-    
-    protected IOFMessageListener getVirtualNetworkListener() {
-    	List<IOFMessageListener> listeners = mockFloodlightProvider.getListeners().get(OFType.PACKET_IN);
-    	return listeners.get(listeners.indexOf(vns));
-    }
-}
