diff --git a/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Constants.java b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Constants.java
new file mode 100644
index 0000000..d1ef80b
--- /dev/null
+++ b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Constants.java
@@ -0,0 +1,27 @@
+/**
+ * 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
new file mode 100644
index 0000000..8e4d989
--- /dev/null
+++ b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Message.java
@@ -0,0 +1,446 @@
+/**
+ * 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
new file mode 100644
index 0000000..b9b2843
--- /dev/null
+++ b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/OFMessageType.java
@@ -0,0 +1,102 @@
+/**
+ * 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
new file mode 100644
index 0000000..65c140f
--- /dev/null
+++ b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/Packet.java
@@ -0,0 +1,525 @@
+/**
+ * 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
new file mode 100644
index 0000000..f4e8ae5
--- /dev/null
+++ b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/PacketStreamer.java
@@ -0,0 +1,2427 @@
+/**
+ * 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
new file mode 100644
index 0000000..8fe8191
--- /dev/null
+++ b/lib/gen-java/net/floodlightcontroller/packetstreamer/thrift/SwitchPortTuple.java
@@ -0,0 +1,406 @@
+/**
+ * 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);
+    }
+  }
+
+}
+
