diff --git a/drivers/barefoot/BUCK b/drivers/barefoot/BUCK
index 5aa0438..9b61412 100644
--- a/drivers/barefoot/BUCK
+++ b/drivers/barefoot/BUCK
@@ -1,5 +1,14 @@
 GRPC_VER = '1.3.0'
 
+remote_jar (
+    name = 'thrift',
+    out = 'thrift-0.10.0.jar',
+    url = 'mvn:org.apache.thrift:libthrift:jar:0.10.0',
+    sha1 = '3201c5a6d85d3f030bae5a520abaaf81ef7df037',
+    maven_coords = 'org.apache.thrift:libthrift:jar:NON-OSGI:0.10.0',
+    visibility = [ 'PUBLIC' ],
+)
+
 COMPILE_DEPS = [
     '//lib:CORE_DEPS',
     '//lib:minimal-json',
@@ -9,11 +18,15 @@
     '//drivers/p4runtime:onos-drivers-p4runtime',
     '//incubator/grpc-dependencies:grpc-core-repkg-' + GRPC_VER,
     '//lib:grpc-netty-' + GRPC_VER,
+    ':thrift',
+    '//providers/general/device:onos-providers-general-device',
+    '//incubator/api:onos-incubator-api',
 ]
 
 BUNDLES = [
     ':onos-drivers-barefoot',
     '//incubator/bmv2/model:onos-incubator-bmv2-model',
+    ':thrift',
 ]
 
 osgi_jar(
diff --git a/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/TofinoPipelineProgrammable.java b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/TofinoPipelineProgrammable.java
index b6fb853..9e4cf24 100644
--- a/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/TofinoPipelineProgrammable.java
+++ b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/TofinoPipelineProgrammable.java
@@ -17,16 +17,40 @@
 package org.onosproject.drivers.barefoot;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import org.apache.commons.io.IOUtils;
+import org.apache.thrift.TException;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TMultiplexedProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TTransport;
 import org.onlab.util.SharedExecutors;
+import org.onosproject.drivers.barefoot.pal.InvalidPalOperation;
+import org.onosproject.drivers.barefoot.pal.pal;
+import org.onosproject.drivers.barefoot.pal.pal_fec_type_t;
+import org.onosproject.drivers.barefoot.pal.pal_port_speed_t;
+import org.onosproject.incubator.net.config.basics.PortDescriptionsConfig;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Port;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.basics.BasicDeviceConfig;
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.PortDescription;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverService;
 import org.onosproject.net.pi.model.PiPipeconf;
 import org.onosproject.net.pi.model.PiPipeconf.ExtensionType;
 import org.onosproject.net.pi.model.PiPipelineProgrammable;
 import org.onosproject.p4runtime.api.P4RuntimeClient;
 import org.onosproject.p4runtime.api.P4RuntimeController;
+import org.onosproject.provider.general.device.api.GeneralProviderDeviceConfig;
 import org.slf4j.Logger;
 
 import java.io.File;
@@ -36,7 +60,9 @@
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
@@ -51,6 +77,11 @@
 
     // FIXME: default pipeconf should depend on the system. Maybe pass it via netcfg?
     private static final PiPipeconf DEFAULT_PIPECONF = TofinoDefaultPipeconfFactory.getMavericks();
+    private static final String P4RUNTIME = "p4runtime";
+    private static final String PROTOCOL_KEY_IP = "ip";
+    private static final String DEVICE_ID = "deviceId";
+    private static final int PAL_MGMT_PORT = 9090;
+    private static final String PAL_THRIFT_SERVICE = "pal";
 
     private final Logger log = getLogger(getClass());
 
@@ -94,8 +125,7 @@
                 return false;
             }
 
-            //FIXME this hack calls the shell command to set up the ports
-            SharedExecutors.getPoolThreadExecutor().submit(() -> runPortCommand(deviceId));
+            SharedExecutors.getPoolThreadExecutor().submit(() -> setupPorts(deviceId));
 
         } catch (InterruptedException | ExecutionException e) {
             throw new RuntimeException(e);
@@ -104,45 +134,68 @@
         return true;
     }
 
-    // FIXME This is a hack to enable port until we either implement Thrift or gNMI
-    private void runPortCommand(DeviceId deviceId) {
-        // TODO we should have a more intelligent way of building the command
-        final String command;
-        if ("device:tofino:11".equals(deviceId.toString())) {
-            command = "./pm.py 10.254.1.38 38-port-config.txt";
-        } else if ("device:tofino:12".equals(deviceId.toString())) {
-            command = "./pm.py 10.254.1.37 37-port-config.txt";
-        } else if ("device:tofino:21".equals(deviceId.toString())) {
-            command = "./pm.py 10.254.1.40 40-port-config.txt";
-        } else if ("device:tofino:22".equals(deviceId.toString())) {
-            command = "./pm.py 10.254.1.39 39-port-config.txt";
-        } else {
-            log.error("Device port config not found: {}", deviceId);
-            return;
-        }
-        try {
-            // Give the switch 2 seconds to get settled with the new config
-            Thread.sleep(3000);
+    // FIXME Currently use thrift, may use gNMI to manage it in the future.
+    private void setupPorts(DeviceId deviceId) {
+        NetworkConfigService netcfgService = handler().get(NetworkConfigService.class);
+        GeneralProviderDeviceConfig providerConfig =
+                netcfgService.getConfig(deviceId, GeneralProviderDeviceConfig.class);
+        PortDescriptionsConfig portConfig =
+                netcfgService.getConfig(deviceId, PortDescriptionsConfig.class);
 
-            String rootDir = System.getenv("ONOS_ROOT");
-            if (rootDir == null) {
-                log.error("ONOS_ROOT is not set");
-                return;
+        Map<String, String> values =
+                providerConfig.protocolsInfo().get(P4RUNTIME).configValues();
+        String ip = values.get(PROTOCOL_KEY_IP);
+        byte tofinoDeviceId = Byte.parseByte(values.get(DEVICE_ID));
+
+        List<PortDescription> ports = portConfig.portDescriptions();
+        ports.forEach(port -> {
+            pal_port_speed_t speed = getPortSpeed(port.portSpeed());
+            addAndEnablePort(ip, tofinoDeviceId, (int) port.portNumber().toLong(), speed);
+        });
+    }
+
+    private pal_port_speed_t getPortSpeed(long speed) {
+        // Mbps -> BF_SPEED (1G~100G)
+        speed = speed / 1000;
+
+        if (speed >= 100) {
+            return pal_port_speed_t.BF_SPEED_100G;
+        }
+        if (speed >= 50) {
+            return pal_port_speed_t.BF_SPEED_50G;
+        }
+        if (speed >= 40) {
+            return pal_port_speed_t.BF_SPEED_40G;
+        }
+        if (speed >= 25) {
+            return pal_port_speed_t.BF_SPEED_25G;
+        }
+        if (speed >= 10) {
+            return pal_port_speed_t.BF_SPEED_10G;
+        }
+
+        return pal_port_speed_t.BF_SPEED_1G;
+    }
+
+    private void addAndEnablePort(String ip, byte deviceId, int dp, pal_port_speed_t speed) {
+        TTransport transport = null;
+        try {
+            transport = new TSocket(ip, PAL_MGMT_PORT);
+            transport.open();
+            TProtocol protocol = new TBinaryProtocol(transport);
+            TMultiplexedProtocol mProtocol = new TMultiplexedProtocol(protocol,
+                                                                      PAL_THRIFT_SERVICE);
+            pal.Client client = new pal.Client(mProtocol);
+
+            client.pal_port_add(deviceId, dp, speed, pal_fec_type_t.BF_FEC_TYP_NONE);
+            client.pal_port_enable(deviceId, dp);
+            transport.close();
+        } catch (TException x) {
+            log.error("Error adding port {} to device {} ({})", dp, deviceId, ip, x);
+        } finally {
+            if (transport != null) {
+                transport.close();
             }
-            File workingDirectory = new File(rootDir, "tools/test/tofino-port-auto-setup-tool");
-            if (!workingDirectory.isDirectory()) {
-                log.error("{} does not exist", workingDirectory);
-                return;
-            }
-            Process process = Runtime.getRuntime().exec(command, null, workingDirectory);
-            int exit = process.waitFor();
-            if (exit != 0) {
-                log.error("port command returned non-zero status {} for device {}", exit, deviceId);
-                return;
-            }
-            log.info("Successfully executed port enable on {}", deviceId);
-        } catch (Exception e) {
-            log.error("Failed to run port command on {}", deviceId, e);
         }
     }
 
diff --git a/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/InvalidPalOperation.java b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/InvalidPalOperation.java
new file mode 100644
index 0000000..4c6fe10
--- /dev/null
+++ b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/InvalidPalOperation.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.barefoot.pal;
+
+/**
+ * Autogenerated by Thrift Compiler (0.10.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)", date = "2017-10-05")
+public class InvalidPalOperation extends org.apache.thrift.TException implements org.apache.thrift.TBase<InvalidPalOperation, InvalidPalOperation._Fields>, java.io.Serializable, Cloneable, Comparable<InvalidPalOperation> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("InvalidPalOperation");
+
+  private static final org.apache.thrift.protocol.TField CODE_FIELD_DESC = new org.apache.thrift.protocol.TField("code", org.apache.thrift.protocol.TType.I32, (short)1);
+
+  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new InvalidPalOperationStandardSchemeFactory();
+  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new InvalidPalOperationTupleSchemeFactory();
+
+  public int code; // 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 {
+    CODE((short)1, "code");
+
+    private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+    static {
+      for (_Fields field : java.util.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: // CODE
+          return CODE;
+        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 java.lang.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(java.lang.String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final java.lang.String _fieldName;
+
+    _Fields(short thriftId, java.lang.String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public java.lang.String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  private static final int __CODE_ISSET_ID = 0;
+  private byte __isset_bitfield = 0;
+  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.CODE, new org.apache.thrift.meta_data.FieldMetaData("code", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(InvalidPalOperation.class, metaDataMap);
+  }
+
+  public InvalidPalOperation() {
+  }
+
+  public InvalidPalOperation(
+    int code)
+  {
+    this();
+    this.code = code;
+    setCodeIsSet(true);
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public InvalidPalOperation(InvalidPalOperation other) {
+    __isset_bitfield = other.__isset_bitfield;
+    this.code = other.code;
+  }
+
+  public InvalidPalOperation deepCopy() {
+    return new InvalidPalOperation(this);
+  }
+
+  @Override
+  public void clear() {
+    setCodeIsSet(false);
+    this.code = 0;
+  }
+
+  public int getCode() {
+    return this.code;
+  }
+
+  public InvalidPalOperation setCode(int code) {
+    this.code = code;
+    setCodeIsSet(true);
+    return this;
+  }
+
+  public void unsetCode() {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CODE_ISSET_ID);
+  }
+
+  /** Returns true if field code is set (has been assigned a value) and false otherwise */
+  public boolean isSetCode() {
+    return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CODE_ISSET_ID);
+  }
+
+  public void setCodeIsSet(boolean value) {
+    __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CODE_ISSET_ID, value);
+  }
+
+  public void setFieldValue(_Fields field, java.lang.Object value) {
+    switch (field) {
+    case CODE:
+      if (value == null) {
+        unsetCode();
+      } else {
+        setCode((java.lang.Integer)value);
+      }
+      break;
+
+    }
+  }
+
+  public java.lang.Object getFieldValue(_Fields field) {
+    switch (field) {
+    case CODE:
+      return getCode();
+
+    }
+    throw new java.lang.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 java.lang.IllegalArgumentException();
+    }
+
+    switch (field) {
+    case CODE:
+      return isSetCode();
+    }
+    throw new java.lang.IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(java.lang.Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof InvalidPalOperation)
+      return this.equals((InvalidPalOperation)that);
+    return false;
+  }
+
+  public boolean equals(InvalidPalOperation that) {
+    if (that == null)
+      return false;
+    if (this == that)
+      return true;
+
+    boolean this_present_code = true;
+    boolean that_present_code = true;
+    if (this_present_code || that_present_code) {
+      if (!(this_present_code && that_present_code))
+        return false;
+      if (this.code != that.code)
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int hashCode = 1;
+
+    hashCode = hashCode * 8191 + code;
+
+    return hashCode;
+  }
+
+  @Override
+  public int compareTo(InvalidPalOperation other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = java.lang.Boolean.valueOf(isSetCode()).compareTo(other.isSetCode());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetCode()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.code, other.code);
+      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 {
+    scheme(iprot).read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    scheme(oprot).write(oprot, this);
+  }
+
+  @Override
+  public java.lang.String toString() {
+    java.lang.StringBuilder sb = new java.lang.StringBuilder("InvalidPalOperation(");
+    boolean first = true;
+
+    sb.append("code:");
+    sb.append(this.code);
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  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, java.lang.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_bitfield = 0;
+      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);
+    }
+  }
+
+  private static class InvalidPalOperationStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public InvalidPalOperationStandardScheme getScheme() {
+      return new InvalidPalOperationStandardScheme();
+    }
+  }
+
+  private static class InvalidPalOperationStandardScheme extends org.apache.thrift.scheme.StandardScheme<InvalidPalOperation> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, InvalidPalOperation struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // CODE
+            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+              struct.code = iprot.readI32();
+              struct.setCodeIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, InvalidPalOperation struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      oprot.writeFieldBegin(CODE_FIELD_DESC);
+      oprot.writeI32(struct.code);
+      oprot.writeFieldEnd();
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class InvalidPalOperationTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+    public InvalidPalOperationTupleScheme getScheme() {
+      return new InvalidPalOperationTupleScheme();
+    }
+  }
+
+  private static class InvalidPalOperationTupleScheme extends org.apache.thrift.scheme.TupleScheme<InvalidPalOperation> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, InvalidPalOperation struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet optionals = new java.util.BitSet();
+      if (struct.isSetCode()) {
+        optionals.set(0);
+      }
+      oprot.writeBitSet(optionals, 1);
+      if (struct.isSetCode()) {
+        oprot.writeI32(struct.code);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, InvalidPalOperation struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+      java.util.BitSet incoming = iprot.readBitSet(1);
+      if (incoming.get(0)) {
+        struct.code = iprot.readI32();
+        struct.setCodeIsSet(true);
+      }
+    }
+  }
+
+  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+  }
+}
+
diff --git a/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal.java b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal.java
new file mode 100644
index 0000000..0efa53d
--- /dev/null
+++ b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal.java
@@ -0,0 +1,7950 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.barefoot.pal;
+
+/**
+ * Autogenerated by Thrift Compiler (0.10.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)", date = "2017-10-05")
+public class pal {
+
+  public interface Iface {
+
+    public int pal_port_add(byte device, int dev_port, pal_port_speed_t ps, pal_fec_type_t fec) throws InvalidPalOperation, org.apache.thrift.TException;
+
+    public int pal_port_del(byte device, int dev_port) throws InvalidPalOperation, org.apache.thrift.TException;
+
+    public int pal_port_del_all(byte device) throws InvalidPalOperation, org.apache.thrift.TException;
+
+    public int pal_port_enable(byte device, int dev_port) throws InvalidPalOperation, org.apache.thrift.TException;
+
+    public int pal_port_dis(byte device, int dev_port) throws InvalidPalOperation, org.apache.thrift.TException;
+
+    public pal_oper_status_t pal_port_oper_status_get(byte device, int dev_port) throws InvalidPalOperation, org.apache.thrift.TException;
+
+    public int pal_port_an_set(byte device, int dev_port, pal_autoneg_policy_t an) throws InvalidPalOperation, org.apache.thrift.TException;
+
+  }
+
+  public interface AsyncIface {
+
+    public void pal_port_add(byte device, int dev_port, pal_port_speed_t ps, pal_fec_type_t fec, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_del(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_del_all(byte device, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_enable(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_dis(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_oper_status_get(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<pal_oper_status_t> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_an_set(byte device, int dev_port, pal_autoneg_policy_t an, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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 int pal_port_add(byte device, int dev_port, pal_port_speed_t ps, pal_fec_type_t fec) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_add(device, dev_port, ps, fec);
+      return recv_pal_port_add();
+    }
+
+    public void send_pal_port_add(byte device, int dev_port, pal_port_speed_t ps, pal_fec_type_t fec) throws org.apache.thrift.TException
+    {
+      pal_port_add_args args = new pal_port_add_args();
+      args.setDevice(device);
+      args.setDev_port(dev_port);
+      args.setPs(ps);
+      args.setFec(fec);
+      sendBase("pal_port_add", args);
+    }
+
+    public int recv_pal_port_add() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_add_result result = new pal_port_add_result();
+      receiveBase(result, "pal_port_add");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch != null) {
+        throw result.ouch;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "pal_port_add failed: unknown result");
+    }
+
+    public int pal_port_del(byte device, int dev_port) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_del(device, dev_port);
+      return recv_pal_port_del();
+    }
+
+    public void send_pal_port_del(byte device, int dev_port) throws org.apache.thrift.TException
+    {
+      pal_port_del_args args = new pal_port_del_args();
+      args.setDevice(device);
+      args.setDev_port(dev_port);
+      sendBase("pal_port_del", args);
+    }
+
+    public int recv_pal_port_del() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_del_result result = new pal_port_del_result();
+      receiveBase(result, "pal_port_del");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch != null) {
+        throw result.ouch;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "pal_port_del failed: unknown result");
+    }
+
+    public int pal_port_del_all(byte device) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_del_all(device);
+      return recv_pal_port_del_all();
+    }
+
+    public void send_pal_port_del_all(byte device) throws org.apache.thrift.TException
+    {
+      pal_port_del_all_args args = new pal_port_del_all_args();
+      args.setDevice(device);
+      sendBase("pal_port_del_all", args);
+    }
+
+    public int recv_pal_port_del_all() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_del_all_result result = new pal_port_del_all_result();
+      receiveBase(result, "pal_port_del_all");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch != null) {
+        throw result.ouch;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "pal_port_del_all failed: unknown result");
+    }
+
+    public int pal_port_enable(byte device, int dev_port) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_enable(device, dev_port);
+      return recv_pal_port_enable();
+    }
+
+    public void send_pal_port_enable(byte device, int dev_port) throws org.apache.thrift.TException
+    {
+      pal_port_enable_args args = new pal_port_enable_args();
+      args.setDevice(device);
+      args.setDev_port(dev_port);
+      sendBase("pal_port_enable", args);
+    }
+
+    public int recv_pal_port_enable() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_enable_result result = new pal_port_enable_result();
+      receiveBase(result, "pal_port_enable");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch != null) {
+        throw result.ouch;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "pal_port_enable failed: unknown result");
+    }
+
+    public int pal_port_dis(byte device, int dev_port) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_dis(device, dev_port);
+      return recv_pal_port_dis();
+    }
+
+    public void send_pal_port_dis(byte device, int dev_port) throws org.apache.thrift.TException
+    {
+      pal_port_dis_args args = new pal_port_dis_args();
+      args.setDevice(device);
+      args.setDev_port(dev_port);
+      sendBase("pal_port_dis", args);
+    }
+
+    public int recv_pal_port_dis() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_dis_result result = new pal_port_dis_result();
+      receiveBase(result, "pal_port_dis");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch != null) {
+        throw result.ouch;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "pal_port_dis failed: unknown result");
+    }
+
+    public pal_oper_status_t pal_port_oper_status_get(byte device, int dev_port) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_oper_status_get(device, dev_port);
+      return recv_pal_port_oper_status_get();
+    }
+
+    public void send_pal_port_oper_status_get(byte device, int dev_port) throws org.apache.thrift.TException
+    {
+      pal_port_oper_status_get_args args = new pal_port_oper_status_get_args();
+      args.setDevice(device);
+      args.setDev_port(dev_port);
+      sendBase("pal_port_oper_status_get", args);
+    }
+
+    public pal_oper_status_t recv_pal_port_oper_status_get() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_oper_status_get_result result = new pal_port_oper_status_get_result();
+      receiveBase(result, "pal_port_oper_status_get");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch != null) {
+        throw result.ouch;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "pal_port_oper_status_get failed: unknown result");
+    }
+
+    public int pal_port_an_set(byte device, int dev_port, pal_autoneg_policy_t an) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_an_set(device, dev_port, an);
+      return recv_pal_port_an_set();
+    }
+
+    public void send_pal_port_an_set(byte device, int dev_port, pal_autoneg_policy_t an) throws org.apache.thrift.TException
+    {
+      pal_port_an_set_args args = new pal_port_an_set_args();
+      args.setDevice(device);
+      args.setDev_port(dev_port);
+      args.setAn(an);
+      sendBase("pal_port_an_set", args);
+    }
+
+    public int recv_pal_port_an_set() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_an_set_result result = new pal_port_an_set_result();
+      receiveBase(result, "pal_port_an_set");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ouch != null) {
+        throw result.ouch;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "pal_port_an_set failed: unknown result");
+    }
+
+  }
+  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 pal_port_add(byte device, int dev_port, pal_port_speed_t ps, pal_fec_type_t fec, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_add_call method_call = new pal_port_add_call(device, dev_port, ps, fec, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_add_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Integer> {
+      private byte device;
+      private int dev_port;
+      private pal_port_speed_t ps;
+      private pal_fec_type_t fec;
+      public pal_port_add_call(byte device, int dev_port, pal_port_speed_t ps, pal_fec_type_t fec, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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.device = device;
+        this.dev_port = dev_port;
+        this.ps = ps;
+        this.fec = fec;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pal_port_add", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_add_args args = new pal_port_add_args();
+        args.setDevice(device);
+        args.setDev_port(dev_port);
+        args.setPs(ps);
+        args.setFec(fec);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public java.lang.Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.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_pal_port_add();
+      }
+    }
+
+    public void pal_port_del(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_del_call method_call = new pal_port_del_call(device, dev_port, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_del_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Integer> {
+      private byte device;
+      private int dev_port;
+      public pal_port_del_call(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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.device = device;
+        this.dev_port = dev_port;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pal_port_del", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_del_args args = new pal_port_del_args();
+        args.setDevice(device);
+        args.setDev_port(dev_port);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public java.lang.Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.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_pal_port_del();
+      }
+    }
+
+    public void pal_port_del_all(byte device, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_del_all_call method_call = new pal_port_del_all_call(device, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_del_all_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Integer> {
+      private byte device;
+      public pal_port_del_all_call(byte device, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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.device = device;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pal_port_del_all", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_del_all_args args = new pal_port_del_all_args();
+        args.setDevice(device);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public java.lang.Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.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_pal_port_del_all();
+      }
+    }
+
+    public void pal_port_enable(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_enable_call method_call = new pal_port_enable_call(device, dev_port, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_enable_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Integer> {
+      private byte device;
+      private int dev_port;
+      public pal_port_enable_call(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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.device = device;
+        this.dev_port = dev_port;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pal_port_enable", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_enable_args args = new pal_port_enable_args();
+        args.setDevice(device);
+        args.setDev_port(dev_port);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public java.lang.Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.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_pal_port_enable();
+      }
+    }
+
+    public void pal_port_dis(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_dis_call method_call = new pal_port_dis_call(device, dev_port, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_dis_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Integer> {
+      private byte device;
+      private int dev_port;
+      public pal_port_dis_call(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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.device = device;
+        this.dev_port = dev_port;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pal_port_dis", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_dis_args args = new pal_port_dis_args();
+        args.setDevice(device);
+        args.setDev_port(dev_port);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public java.lang.Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.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_pal_port_dis();
+      }
+    }
+
+    public void pal_port_oper_status_get(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<pal_oper_status_t> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_oper_status_get_call method_call = new pal_port_oper_status_get_call(device, dev_port, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_oper_status_get_call extends org.apache.thrift.async.TAsyncMethodCall<pal_oper_status_t> {
+      private byte device;
+      private int dev_port;
+      public pal_port_oper_status_get_call(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<pal_oper_status_t> 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.device = device;
+        this.dev_port = dev_port;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pal_port_oper_status_get", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_oper_status_get_args args = new pal_port_oper_status_get_args();
+        args.setDevice(device);
+        args.setDev_port(dev_port);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public pal_oper_status_t getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.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_pal_port_oper_status_get();
+      }
+    }
+
+    public void pal_port_an_set(byte device, int dev_port, pal_autoneg_policy_t an, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_an_set_call method_call = new pal_port_an_set_call(device, dev_port, an, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_an_set_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Integer> {
+      private byte device;
+      private int dev_port;
+      private pal_autoneg_policy_t an;
+      public pal_port_an_set_call(byte device, int dev_port, pal_autoneg_policy_t an, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> 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.device = device;
+        this.dev_port = dev_port;
+        this.an = an;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("pal_port_an_set", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_an_set_args args = new pal_port_an_set_args();
+        args.setDevice(device);
+        args.setDev_port(dev_port);
+        args.setAn(an);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public java.lang.Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new java.lang.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_pal_port_an_set();
+      }
+    }
+
+  }
+
+  public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor {
+    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName());
+    public Processor(I iface) {
+      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
+    }
+
+    protected Processor(I iface, java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends Iface> java.util.Map<java.lang.String,  org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
+      processMap.put("pal_port_add", new pal_port_add());
+      processMap.put("pal_port_del", new pal_port_del());
+      processMap.put("pal_port_del_all", new pal_port_del_all());
+      processMap.put("pal_port_enable", new pal_port_enable());
+      processMap.put("pal_port_dis", new pal_port_dis());
+      processMap.put("pal_port_oper_status_get", new pal_port_oper_status_get());
+      processMap.put("pal_port_an_set", new pal_port_an_set());
+      return processMap;
+    }
+
+    public static class pal_port_add<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_add_args> {
+      public pal_port_add() {
+        super("pal_port_add");
+      }
+
+      public pal_port_add_args getEmptyArgsInstance() {
+        return new pal_port_add_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public pal_port_add_result getResult(I iface, pal_port_add_args args) throws org.apache.thrift.TException {
+        pal_port_add_result result = new pal_port_add_result();
+        try {
+          result.success = iface.pal_port_add(args.device, args.dev_port, args.ps, args.fec);
+          result.setSuccessIsSet(true);
+        } catch (InvalidPalOperation ouch) {
+          result.ouch = ouch;
+        }
+        return result;
+      }
+    }
+
+    public static class pal_port_del<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_del_args> {
+      public pal_port_del() {
+        super("pal_port_del");
+      }
+
+      public pal_port_del_args getEmptyArgsInstance() {
+        return new pal_port_del_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public pal_port_del_result getResult(I iface, pal_port_del_args args) throws org.apache.thrift.TException {
+        pal_port_del_result result = new pal_port_del_result();
+        try {
+          result.success = iface.pal_port_del(args.device, args.dev_port);
+          result.setSuccessIsSet(true);
+        } catch (InvalidPalOperation ouch) {
+          result.ouch = ouch;
+        }
+        return result;
+      }
+    }
+
+    public static class pal_port_del_all<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_del_all_args> {
+      public pal_port_del_all() {
+        super("pal_port_del_all");
+      }
+
+      public pal_port_del_all_args getEmptyArgsInstance() {
+        return new pal_port_del_all_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public pal_port_del_all_result getResult(I iface, pal_port_del_all_args args) throws org.apache.thrift.TException {
+        pal_port_del_all_result result = new pal_port_del_all_result();
+        try {
+          result.success = iface.pal_port_del_all(args.device);
+          result.setSuccessIsSet(true);
+        } catch (InvalidPalOperation ouch) {
+          result.ouch = ouch;
+        }
+        return result;
+      }
+    }
+
+    public static class pal_port_enable<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_enable_args> {
+      public pal_port_enable() {
+        super("pal_port_enable");
+      }
+
+      public pal_port_enable_args getEmptyArgsInstance() {
+        return new pal_port_enable_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public pal_port_enable_result getResult(I iface, pal_port_enable_args args) throws org.apache.thrift.TException {
+        pal_port_enable_result result = new pal_port_enable_result();
+        try {
+          result.success = iface.pal_port_enable(args.device, args.dev_port);
+          result.setSuccessIsSet(true);
+        } catch (InvalidPalOperation ouch) {
+          result.ouch = ouch;
+        }
+        return result;
+      }
+    }
+
+    public static class pal_port_dis<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_dis_args> {
+      public pal_port_dis() {
+        super("pal_port_dis");
+      }
+
+      public pal_port_dis_args getEmptyArgsInstance() {
+        return new pal_port_dis_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public pal_port_dis_result getResult(I iface, pal_port_dis_args args) throws org.apache.thrift.TException {
+        pal_port_dis_result result = new pal_port_dis_result();
+        try {
+          result.success = iface.pal_port_dis(args.device, args.dev_port);
+          result.setSuccessIsSet(true);
+        } catch (InvalidPalOperation ouch) {
+          result.ouch = ouch;
+        }
+        return result;
+      }
+    }
+
+    public static class pal_port_oper_status_get<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_oper_status_get_args> {
+      public pal_port_oper_status_get() {
+        super("pal_port_oper_status_get");
+      }
+
+      public pal_port_oper_status_get_args getEmptyArgsInstance() {
+        return new pal_port_oper_status_get_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public pal_port_oper_status_get_result getResult(I iface, pal_port_oper_status_get_args args) throws org.apache.thrift.TException {
+        pal_port_oper_status_get_result result = new pal_port_oper_status_get_result();
+        try {
+          result.success = iface.pal_port_oper_status_get(args.device, args.dev_port);
+        } catch (InvalidPalOperation ouch) {
+          result.ouch = ouch;
+        }
+        return result;
+      }
+    }
+
+    public static class pal_port_an_set<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_an_set_args> {
+      public pal_port_an_set() {
+        super("pal_port_an_set");
+      }
+
+      public pal_port_an_set_args getEmptyArgsInstance() {
+        return new pal_port_an_set_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public pal_port_an_set_result getResult(I iface, pal_port_an_set_args args) throws org.apache.thrift.TException {
+        pal_port_an_set_result result = new pal_port_an_set_result();
+        try {
+          result.success = iface.pal_port_an_set(args.device, args.dev_port, args.an);
+          result.setSuccessIsSet(true);
+        } catch (InvalidPalOperation ouch) {
+          result.ouch = ouch;
+        }
+        return result;
+      }
+    }
+
+  }
+
+  public static class AsyncProcessor<I extends AsyncIface> extends org.apache.thrift.TBaseAsyncProcessor<I> {
+    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());
+    public AsyncProcessor(I iface) {
+      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
+    }
+
+    protected AsyncProcessor(I iface, java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends AsyncIface> java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
+      processMap.put("pal_port_add", new pal_port_add());
+      processMap.put("pal_port_del", new pal_port_del());
+      processMap.put("pal_port_del_all", new pal_port_del_all());
+      processMap.put("pal_port_enable", new pal_port_enable());
+      processMap.put("pal_port_dis", new pal_port_dis());
+      processMap.put("pal_port_oper_status_get", new pal_port_oper_status_get());
+      processMap.put("pal_port_an_set", new pal_port_an_set());
+      return processMap;
+    }
+
+    public static class pal_port_add<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_add_args, java.lang.Integer> {
+      public pal_port_add() {
+        super("pal_port_add");
+      }
+
+      public pal_port_add_args getEmptyArgsInstance() {
+        return new pal_port_add_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer>() { 
+          public void onComplete(java.lang.Integer o) {
+            pal_port_add_result result = new pal_port_add_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_add_result result = new pal_port_add_result();
+            if (e instanceof InvalidPalOperation) {
+              result.ouch = (InvalidPalOperation) e;
+              result.setOuchIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, pal_port_add_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_add(args.device, args.dev_port, args.ps, args.fec,resultHandler);
+      }
+    }
+
+    public static class pal_port_del<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_del_args, java.lang.Integer> {
+      public pal_port_del() {
+        super("pal_port_del");
+      }
+
+      public pal_port_del_args getEmptyArgsInstance() {
+        return new pal_port_del_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer>() { 
+          public void onComplete(java.lang.Integer o) {
+            pal_port_del_result result = new pal_port_del_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_del_result result = new pal_port_del_result();
+            if (e instanceof InvalidPalOperation) {
+              result.ouch = (InvalidPalOperation) e;
+              result.setOuchIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, pal_port_del_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_del(args.device, args.dev_port,resultHandler);
+      }
+    }
+
+    public static class pal_port_del_all<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_del_all_args, java.lang.Integer> {
+      public pal_port_del_all() {
+        super("pal_port_del_all");
+      }
+
+      public pal_port_del_all_args getEmptyArgsInstance() {
+        return new pal_port_del_all_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer>() { 
+          public void onComplete(java.lang.Integer o) {
+            pal_port_del_all_result result = new pal_port_del_all_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_del_all_result result = new pal_port_del_all_result();
+            if (e instanceof InvalidPalOperation) {
+              result.ouch = (InvalidPalOperation) e;
+              result.setOuchIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, pal_port_del_all_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_del_all(args.device,resultHandler);
+      }
+    }
+
+    public static class pal_port_enable<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_enable_args, java.lang.Integer> {
+      public pal_port_enable() {
+        super("pal_port_enable");
+      }
+
+      public pal_port_enable_args getEmptyArgsInstance() {
+        return new pal_port_enable_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer>() { 
+          public void onComplete(java.lang.Integer o) {
+            pal_port_enable_result result = new pal_port_enable_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_enable_result result = new pal_port_enable_result();
+            if (e instanceof InvalidPalOperation) {
+              result.ouch = (InvalidPalOperation) e;
+              result.setOuchIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, pal_port_enable_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_enable(args.device, args.dev_port,resultHandler);
+      }
+    }
+
+    public static class pal_port_dis<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_dis_args, java.lang.Integer> {
+      public pal_port_dis() {
+        super("pal_port_dis");
+      }
+
+      public pal_port_dis_args getEmptyArgsInstance() {
+        return new pal_port_dis_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer>() { 
+          public void onComplete(java.lang.Integer o) {
+            pal_port_dis_result result = new pal_port_dis_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_dis_result result = new pal_port_dis_result();
+            if (e instanceof InvalidPalOperation) {
+              result.ouch = (InvalidPalOperation) e;
+              result.setOuchIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, pal_port_dis_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_dis(args.device, args.dev_port,resultHandler);
+      }
+    }
+
+    public static class pal_port_oper_status_get<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_oper_status_get_args, pal_oper_status_t> {
+      public pal_port_oper_status_get() {
+        super("pal_port_oper_status_get");
+      }
+
+      public pal_port_oper_status_get_args getEmptyArgsInstance() {
+        return new pal_port_oper_status_get_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<pal_oper_status_t> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<pal_oper_status_t>() { 
+          public void onComplete(pal_oper_status_t o) {
+            pal_port_oper_status_get_result result = new pal_port_oper_status_get_result();
+            result.success = o;
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_oper_status_get_result result = new pal_port_oper_status_get_result();
+            if (e instanceof InvalidPalOperation) {
+              result.ouch = (InvalidPalOperation) e;
+              result.setOuchIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, pal_port_oper_status_get_args args, org.apache.thrift.async.AsyncMethodCallback<pal_oper_status_t> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_oper_status_get(args.device, args.dev_port,resultHandler);
+      }
+    }
+
+    public static class pal_port_an_set<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_an_set_args, java.lang.Integer> {
+      public pal_port_an_set() {
+        super("pal_port_an_set");
+      }
+
+      public pal_port_an_set_args getEmptyArgsInstance() {
+        return new pal_port_an_set_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
+        final org.apache.thrift.AsyncProcessFunction fcall = this;
+        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer>() { 
+          public void onComplete(java.lang.Integer o) {
+            pal_port_an_set_result result = new pal_port_an_set_result();
+            result.success = o;
+            result.setSuccessIsSet(true);
+            try {
+              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
+            } catch (org.apache.thrift.transport.TTransportException e) {
+              _LOGGER.error("TTransportException writing to internal frame buffer", e);
+              fb.close();
+            } catch (java.lang.Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(java.lang.Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_an_set_result result = new pal_port_an_set_result();
+            if (e instanceof InvalidPalOperation) {
+              result.ouch = (InvalidPalOperation) e;
+              result.setOuchIsSet(true);
+              msg = result;
+            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
+              _LOGGER.error("TTransportException inside handler", e);
+              fb.close();
+              return;
+            } else if (e instanceof org.apache.thrift.TApplicationException) {
+              _LOGGER.error("TApplicationException inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = (org.apache.thrift.TApplicationException)e;
+            } else {
+              _LOGGER.error("Exception inside handler", e);
+              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
+              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
+            }
+            try {
+              fcall.sendResponse(fb,msg,msgType,seqid);
+            } catch (java.lang.Exception ex) {
+              _LOGGER.error("Exception writing to internal frame buffer", ex);
+              fb.close();
+            }
+          }
+        };
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public void start(I iface, pal_port_an_set_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_an_set(args.device, args.dev_port, args.an,resultHandler);
+      }
+    }
+
+  }
+
+  public static class pal_port_add_args implements org.apache.thrift.TBase<pal_port_add_args, pal_port_add_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_add_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_add_args");
+
+    private static final org.apache.thrift.protocol.TField DEVICE_FIELD_DESC = new org.apache.thrift.protocol.TField("device", org.apache.thrift.protocol.TType.BYTE, (short)1);
+    private static final org.apache.thrift.protocol.TField DEV_PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("dev_port", org.apache.thrift.protocol.TType.I32, (short)2);
+    private static final org.apache.thrift.protocol.TField PS_FIELD_DESC = new org.apache.thrift.protocol.TField("ps", org.apache.thrift.protocol.TType.I32, (short)3);
+    private static final org.apache.thrift.protocol.TField FEC_FIELD_DESC = new org.apache.thrift.protocol.TField("fec", org.apache.thrift.protocol.TType.I32, (short)4);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_add_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_add_argsTupleSchemeFactory();
+
+    public byte device; // required
+    public int dev_port; // required
+    /**
+     * 
+     * @see pal_port_speed_t
+     */
+    public pal_port_speed_t ps; // required
+    /**
+     * 
+     * @see pal_fec_type_t
+     */
+    public pal_fec_type_t fec; // 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 {
+      DEVICE((short)1, "device"),
+      DEV_PORT((short)2, "dev_port"),
+      /**
+       * 
+       * @see pal_port_speed_t
+       */
+      PS((short)3, "ps"),
+      /**
+       * 
+       * @see pal_fec_type_t
+       */
+      FEC((short)4, "fec");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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: // DEVICE
+            return DEVICE;
+          case 2: // DEV_PORT
+            return DEV_PORT;
+          case 3: // PS
+            return PS;
+          case 4: // FEC
+            return FEC;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __DEVICE_ISSET_ID = 0;
+    private static final int __DEV_PORT_ISSET_ID = 1;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.DEVICE, new org.apache.thrift.meta_data.FieldMetaData("device", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE          , "pal_device_t")));
+      tmpMap.put(_Fields.DEV_PORT, new org.apache.thrift.meta_data.FieldMetaData("dev_port", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "pal_dev_port_t")));
+      tmpMap.put(_Fields.PS, new org.apache.thrift.meta_data.FieldMetaData("ps", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, pal_port_speed_t.class)));
+      tmpMap.put(_Fields.FEC, new org.apache.thrift.meta_data.FieldMetaData("fec", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, pal_fec_type_t.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_add_args.class, metaDataMap);
+    }
+
+    public pal_port_add_args() {
+    }
+
+    public pal_port_add_args(
+      byte device,
+      int dev_port,
+      pal_port_speed_t ps,
+      pal_fec_type_t fec)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+      this.ps = ps;
+      this.fec = fec;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_add_args(pal_port_add_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+      this.dev_port = other.dev_port;
+      if (other.isSetPs()) {
+        this.ps = other.ps;
+      }
+      if (other.isSetFec()) {
+        this.fec = other.fec;
+      }
+    }
+
+    public pal_port_add_args deepCopy() {
+      return new pal_port_add_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+      setDev_portIsSet(false);
+      this.dev_port = 0;
+      this.ps = null;
+      this.fec = null;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_add_args setDevice(byte device) {
+      this.device = device;
+      setDeviceIsSet(true);
+      return this;
+    }
+
+    public void unsetDevice() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    /** Returns true if field device is set (has been assigned a value) and false otherwise */
+    public boolean isSetDevice() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    public void setDeviceIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEVICE_ISSET_ID, value);
+    }
+
+    public int getDev_port() {
+      return this.dev_port;
+    }
+
+    public pal_port_add_args setDev_port(int dev_port) {
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+      return this;
+    }
+
+    public void unsetDev_port() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    /** Returns true if field dev_port is set (has been assigned a value) and false otherwise */
+    public boolean isSetDev_port() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    public void setDev_portIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEV_PORT_ISSET_ID, value);
+    }
+
+    /**
+     * 
+     * @see pal_port_speed_t
+     */
+    public pal_port_speed_t getPs() {
+      return this.ps;
+    }
+
+    /**
+     * 
+     * @see pal_port_speed_t
+     */
+    public pal_port_add_args setPs(pal_port_speed_t ps) {
+      this.ps = ps;
+      return this;
+    }
+
+    public void unsetPs() {
+      this.ps = null;
+    }
+
+    /** Returns true if field ps is set (has been assigned a value) and false otherwise */
+    public boolean isSetPs() {
+      return this.ps != null;
+    }
+
+    public void setPsIsSet(boolean value) {
+      if (!value) {
+        this.ps = null;
+      }
+    }
+
+    /**
+     * 
+     * @see pal_fec_type_t
+     */
+    public pal_fec_type_t getFec() {
+      return this.fec;
+    }
+
+    /**
+     * 
+     * @see pal_fec_type_t
+     */
+    public pal_port_add_args setFec(pal_fec_type_t fec) {
+      this.fec = fec;
+      return this;
+    }
+
+    public void unsetFec() {
+      this.fec = null;
+    }
+
+    /** Returns true if field fec is set (has been assigned a value) and false otherwise */
+    public boolean isSetFec() {
+      return this.fec != null;
+    }
+
+    public void setFecIsSet(boolean value) {
+      if (!value) {
+        this.fec = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((java.lang.Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((java.lang.Integer)value);
+        }
+        break;
+
+      case PS:
+        if (value == null) {
+          unsetPs();
+        } else {
+          setPs((pal_port_speed_t)value);
+        }
+        break;
+
+      case FEC:
+        if (value == null) {
+          unsetFec();
+        } else {
+          setFec((pal_fec_type_t)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      case PS:
+        return getPs();
+
+      case FEC:
+        return getFec();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      case PS:
+        return isSetPs();
+      case FEC:
+        return isSetFec();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_add_args)
+        return this.equals((pal_port_add_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_add_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_device = true;
+      boolean that_present_device = true;
+      if (this_present_device || that_present_device) {
+        if (!(this_present_device && that_present_device))
+          return false;
+        if (this.device != that.device)
+          return false;
+      }
+
+      boolean this_present_dev_port = true;
+      boolean that_present_dev_port = true;
+      if (this_present_dev_port || that_present_dev_port) {
+        if (!(this_present_dev_port && that_present_dev_port))
+          return false;
+        if (this.dev_port != that.dev_port)
+          return false;
+      }
+
+      boolean this_present_ps = true && this.isSetPs();
+      boolean that_present_ps = true && that.isSetPs();
+      if (this_present_ps || that_present_ps) {
+        if (!(this_present_ps && that_present_ps))
+          return false;
+        if (!this.ps.equals(that.ps))
+          return false;
+      }
+
+      boolean this_present_fec = true && this.isSetFec();
+      boolean that_present_fec = true && that.isSetFec();
+      if (this_present_fec || that_present_fec) {
+        if (!(this_present_fec && that_present_fec))
+          return false;
+        if (!this.fec.equals(that.fec))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + (int) (device);
+
+      hashCode = hashCode * 8191 + dev_port;
+
+      hashCode = hashCode * 8191 + ((isSetPs()) ? 131071 : 524287);
+      if (isSetPs())
+        hashCode = hashCode * 8191 + ps.getValue();
+
+      hashCode = hashCode * 8191 + ((isSetFec()) ? 131071 : 524287);
+      if (isSetFec())
+        hashCode = hashCode * 8191 + fec.getValue();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_add_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetDevice()).compareTo(other.isSetDevice());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDevice()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.device, other.device);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetDev_port()).compareTo(other.isSetDev_port());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDev_port()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dev_port, other.dev_port);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetPs()).compareTo(other.isSetPs());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetPs()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ps, other.ps);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetFec()).compareTo(other.isSetFec());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetFec()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.fec, other.fec);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_add_args(");
+      boolean first = true;
+
+      sb.append("device:");
+      sb.append(this.device);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("dev_port:");
+      sb.append(this.dev_port);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ps:");
+      if (this.ps == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ps);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("fec:");
+      if (this.fec == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.fec);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_add_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_add_argsStandardScheme getScheme() {
+        return new pal_port_add_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_add_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_add_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_add_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // DEVICE
+              if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
+                struct.device = iprot.readByte();
+                struct.setDeviceIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DEV_PORT
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.dev_port = iprot.readI32();
+                struct.setDev_portIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // PS
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.ps = pal_port_speed_t.findByValue(iprot.readI32());
+                struct.setPsIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // FEC
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.fec = pal_fec_type_t.findByValue(iprot.readI32());
+                struct.setFecIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_add_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(DEVICE_FIELD_DESC);
+        oprot.writeByte(struct.device);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(DEV_PORT_FIELD_DESC);
+        oprot.writeI32(struct.dev_port);
+        oprot.writeFieldEnd();
+        if (struct.ps != null) {
+          oprot.writeFieldBegin(PS_FIELD_DESC);
+          oprot.writeI32(struct.ps.getValue());
+          oprot.writeFieldEnd();
+        }
+        if (struct.fec != null) {
+          oprot.writeFieldBegin(FEC_FIELD_DESC);
+          oprot.writeI32(struct.fec.getValue());
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_add_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_add_argsTupleScheme getScheme() {
+        return new pal_port_add_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_add_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_add_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_add_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetDevice()) {
+          optionals.set(0);
+        }
+        if (struct.isSetDev_port()) {
+          optionals.set(1);
+        }
+        if (struct.isSetPs()) {
+          optionals.set(2);
+        }
+        if (struct.isSetFec()) {
+          optionals.set(3);
+        }
+        oprot.writeBitSet(optionals, 4);
+        if (struct.isSetDevice()) {
+          oprot.writeByte(struct.device);
+        }
+        if (struct.isSetDev_port()) {
+          oprot.writeI32(struct.dev_port);
+        }
+        if (struct.isSetPs()) {
+          oprot.writeI32(struct.ps.getValue());
+        }
+        if (struct.isSetFec()) {
+          oprot.writeI32(struct.fec.getValue());
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_add_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(4);
+        if (incoming.get(0)) {
+          struct.device = iprot.readByte();
+          struct.setDeviceIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.dev_port = iprot.readI32();
+          struct.setDev_portIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.ps = pal_port_speed_t.findByValue(iprot.readI32());
+          struct.setPsIsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.fec = pal_fec_type_t.findByValue(iprot.readI32());
+          struct.setFecIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_add_result implements org.apache.thrift.TBase<pal_port_add_result, pal_port_add_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_add_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_add_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);
+    private static final org.apache.thrift.protocol.TField OUCH_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_add_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_add_resultTupleSchemeFactory();
+
+    public int success; // required
+    public InvalidPalOperation ouch; // 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"),
+      OUCH((short)1, "ouch");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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;
+          case 1: // OUCH
+            return OUCH;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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          , "pal_status_t")));
+      tmpMap.put(_Fields.OUCH, new org.apache.thrift.meta_data.FieldMetaData("ouch", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, InvalidPalOperation.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_add_result.class, metaDataMap);
+    }
+
+    public pal_port_add_result() {
+    }
+
+    public pal_port_add_result(
+      int success,
+      InvalidPalOperation ouch)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch = ouch;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_add_result(pal_port_add_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_add_result deepCopy() {
+      return new pal_port_add_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_add_result setSuccess(int success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public InvalidPalOperation getOuch() {
+      return this.ouch;
+    }
+
+    public pal_port_add_result setOuch(InvalidPalOperation ouch) {
+      this.ouch = ouch;
+      return this;
+    }
+
+    public void unsetOuch() {
+      this.ouch = null;
+    }
+
+    /** Returns true if field ouch is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch() {
+      return this.ouch != null;
+    }
+
+    public void setOuchIsSet(boolean value) {
+      if (!value) {
+        this.ouch = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((java.lang.Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_add_result)
+        return this.equals((pal_port_add_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_add_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      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;
+      }
+
+      boolean this_present_ouch = true && this.isSetOuch();
+      boolean that_present_ouch = true && that.isSetOuch();
+      if (this_present_ouch || that_present_ouch) {
+        if (!(this_present_ouch && that_present_ouch))
+          return false;
+        if (!this.ouch.equals(that.ouch))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + success;
+
+      hashCode = hashCode * 8191 + ((isSetOuch()) ? 131071 : 524287);
+      if (isSetOuch())
+        hashCode = hashCode * 8191 + ouch.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_add_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch()).compareTo(other.isSetOuch());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch, other.ouch);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_add_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch:");
+      if (this.ouch == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_add_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_add_resultStandardScheme getScheme() {
+        return new pal_port_add_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_add_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_add_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_add_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.success = iprot.readI32();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch = new InvalidPalOperation();
+                struct.ouch.read(iprot);
+                struct.setOuchIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_add_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeI32(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch != null) {
+          oprot.writeFieldBegin(OUCH_FIELD_DESC);
+          struct.ouch.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_add_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_add_resultTupleScheme getScheme() {
+        return new pal_port_add_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_add_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_add_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_add_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          oprot.writeI32(struct.success);
+        }
+        if (struct.isSetOuch()) {
+          struct.ouch.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_add_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = iprot.readI32();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch = new InvalidPalOperation();
+          struct.ouch.read(iprot);
+          struct.setOuchIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_del_args implements org.apache.thrift.TBase<pal_port_del_args, pal_port_del_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_del_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_del_args");
+
+    private static final org.apache.thrift.protocol.TField DEVICE_FIELD_DESC = new org.apache.thrift.protocol.TField("device", org.apache.thrift.protocol.TType.BYTE, (short)1);
+    private static final org.apache.thrift.protocol.TField DEV_PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("dev_port", org.apache.thrift.protocol.TType.I32, (short)2);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_del_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_del_argsTupleSchemeFactory();
+
+    public byte device; // required
+    public int dev_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 {
+      DEVICE((short)1, "device"),
+      DEV_PORT((short)2, "dev_port");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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: // DEVICE
+            return DEVICE;
+          case 2: // DEV_PORT
+            return DEV_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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __DEVICE_ISSET_ID = 0;
+    private static final int __DEV_PORT_ISSET_ID = 1;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.DEVICE, new org.apache.thrift.meta_data.FieldMetaData("device", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE          , "pal_device_t")));
+      tmpMap.put(_Fields.DEV_PORT, new org.apache.thrift.meta_data.FieldMetaData("dev_port", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "pal_dev_port_t")));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_del_args.class, metaDataMap);
+    }
+
+    public pal_port_del_args() {
+    }
+
+    public pal_port_del_args(
+      byte device,
+      int dev_port)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_del_args(pal_port_del_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+      this.dev_port = other.dev_port;
+    }
+
+    public pal_port_del_args deepCopy() {
+      return new pal_port_del_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+      setDev_portIsSet(false);
+      this.dev_port = 0;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_del_args setDevice(byte device) {
+      this.device = device;
+      setDeviceIsSet(true);
+      return this;
+    }
+
+    public void unsetDevice() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    /** Returns true if field device is set (has been assigned a value) and false otherwise */
+    public boolean isSetDevice() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    public void setDeviceIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEVICE_ISSET_ID, value);
+    }
+
+    public int getDev_port() {
+      return this.dev_port;
+    }
+
+    public pal_port_del_args setDev_port(int dev_port) {
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+      return this;
+    }
+
+    public void unsetDev_port() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    /** Returns true if field dev_port is set (has been assigned a value) and false otherwise */
+    public boolean isSetDev_port() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    public void setDev_portIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEV_PORT_ISSET_ID, value);
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((java.lang.Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((java.lang.Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_del_args)
+        return this.equals((pal_port_del_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_del_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_device = true;
+      boolean that_present_device = true;
+      if (this_present_device || that_present_device) {
+        if (!(this_present_device && that_present_device))
+          return false;
+        if (this.device != that.device)
+          return false;
+      }
+
+      boolean this_present_dev_port = true;
+      boolean that_present_dev_port = true;
+      if (this_present_dev_port || that_present_dev_port) {
+        if (!(this_present_dev_port && that_present_dev_port))
+          return false;
+        if (this.dev_port != that.dev_port)
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + (int) (device);
+
+      hashCode = hashCode * 8191 + dev_port;
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_del_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetDevice()).compareTo(other.isSetDevice());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDevice()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.device, other.device);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetDev_port()).compareTo(other.isSetDev_port());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDev_port()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dev_port, other.dev_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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_del_args(");
+      boolean first = true;
+
+      sb.append("device:");
+      sb.append(this.device);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("dev_port:");
+      sb.append(this.dev_port);
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_del_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_del_argsStandardScheme getScheme() {
+        return new pal_port_del_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_del_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_del_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_del_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // DEVICE
+              if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
+                struct.device = iprot.readByte();
+                struct.setDeviceIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DEV_PORT
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.dev_port = iprot.readI32();
+                struct.setDev_portIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_del_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(DEVICE_FIELD_DESC);
+        oprot.writeByte(struct.device);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(DEV_PORT_FIELD_DESC);
+        oprot.writeI32(struct.dev_port);
+        oprot.writeFieldEnd();
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_del_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_del_argsTupleScheme getScheme() {
+        return new pal_port_del_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_del_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_del_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_del_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetDevice()) {
+          optionals.set(0);
+        }
+        if (struct.isSetDev_port()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetDevice()) {
+          oprot.writeByte(struct.device);
+        }
+        if (struct.isSetDev_port()) {
+          oprot.writeI32(struct.dev_port);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_del_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.device = iprot.readByte();
+          struct.setDeviceIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.dev_port = iprot.readI32();
+          struct.setDev_portIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_del_result implements org.apache.thrift.TBase<pal_port_del_result, pal_port_del_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_del_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_del_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);
+    private static final org.apache.thrift.protocol.TField OUCH_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_del_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_del_resultTupleSchemeFactory();
+
+    public int success; // required
+    public InvalidPalOperation ouch; // 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"),
+      OUCH((short)1, "ouch");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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;
+          case 1: // OUCH
+            return OUCH;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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          , "pal_status_t")));
+      tmpMap.put(_Fields.OUCH, new org.apache.thrift.meta_data.FieldMetaData("ouch", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, InvalidPalOperation.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_del_result.class, metaDataMap);
+    }
+
+    public pal_port_del_result() {
+    }
+
+    public pal_port_del_result(
+      int success,
+      InvalidPalOperation ouch)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch = ouch;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_del_result(pal_port_del_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_del_result deepCopy() {
+      return new pal_port_del_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_del_result setSuccess(int success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public InvalidPalOperation getOuch() {
+      return this.ouch;
+    }
+
+    public pal_port_del_result setOuch(InvalidPalOperation ouch) {
+      this.ouch = ouch;
+      return this;
+    }
+
+    public void unsetOuch() {
+      this.ouch = null;
+    }
+
+    /** Returns true if field ouch is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch() {
+      return this.ouch != null;
+    }
+
+    public void setOuchIsSet(boolean value) {
+      if (!value) {
+        this.ouch = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((java.lang.Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_del_result)
+        return this.equals((pal_port_del_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_del_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      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;
+      }
+
+      boolean this_present_ouch = true && this.isSetOuch();
+      boolean that_present_ouch = true && that.isSetOuch();
+      if (this_present_ouch || that_present_ouch) {
+        if (!(this_present_ouch && that_present_ouch))
+          return false;
+        if (!this.ouch.equals(that.ouch))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + success;
+
+      hashCode = hashCode * 8191 + ((isSetOuch()) ? 131071 : 524287);
+      if (isSetOuch())
+        hashCode = hashCode * 8191 + ouch.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_del_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch()).compareTo(other.isSetOuch());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch, other.ouch);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_del_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch:");
+      if (this.ouch == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_del_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_del_resultStandardScheme getScheme() {
+        return new pal_port_del_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_del_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_del_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_del_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.success = iprot.readI32();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch = new InvalidPalOperation();
+                struct.ouch.read(iprot);
+                struct.setOuchIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_del_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeI32(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch != null) {
+          oprot.writeFieldBegin(OUCH_FIELD_DESC);
+          struct.ouch.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_del_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_del_resultTupleScheme getScheme() {
+        return new pal_port_del_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_del_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_del_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_del_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          oprot.writeI32(struct.success);
+        }
+        if (struct.isSetOuch()) {
+          struct.ouch.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_del_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = iprot.readI32();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch = new InvalidPalOperation();
+          struct.ouch.read(iprot);
+          struct.setOuchIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_del_all_args implements org.apache.thrift.TBase<pal_port_del_all_args, pal_port_del_all_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_del_all_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_del_all_args");
+
+    private static final org.apache.thrift.protocol.TField DEVICE_FIELD_DESC = new org.apache.thrift.protocol.TField("device", org.apache.thrift.protocol.TType.BYTE, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_del_all_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_del_all_argsTupleSchemeFactory();
+
+    public byte device; // 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 {
+      DEVICE((short)1, "device");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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: // DEVICE
+            return DEVICE;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __DEVICE_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.DEVICE, new org.apache.thrift.meta_data.FieldMetaData("device", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE          , "pal_device_t")));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_del_all_args.class, metaDataMap);
+    }
+
+    public pal_port_del_all_args() {
+    }
+
+    public pal_port_del_all_args(
+      byte device)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_del_all_args(pal_port_del_all_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+    }
+
+    public pal_port_del_all_args deepCopy() {
+      return new pal_port_del_all_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_del_all_args setDevice(byte device) {
+      this.device = device;
+      setDeviceIsSet(true);
+      return this;
+    }
+
+    public void unsetDevice() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    /** Returns true if field device is set (has been assigned a value) and false otherwise */
+    public boolean isSetDevice() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    public void setDeviceIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEVICE_ISSET_ID, value);
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((java.lang.Byte)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_del_all_args)
+        return this.equals((pal_port_del_all_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_del_all_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_device = true;
+      boolean that_present_device = true;
+      if (this_present_device || that_present_device) {
+        if (!(this_present_device && that_present_device))
+          return false;
+        if (this.device != that.device)
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + (int) (device);
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_del_all_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetDevice()).compareTo(other.isSetDevice());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDevice()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.device, other.device);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_del_all_args(");
+      boolean first = true;
+
+      sb.append("device:");
+      sb.append(this.device);
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_del_all_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_del_all_argsStandardScheme getScheme() {
+        return new pal_port_del_all_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_del_all_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_del_all_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_del_all_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // DEVICE
+              if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
+                struct.device = iprot.readByte();
+                struct.setDeviceIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_del_all_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(DEVICE_FIELD_DESC);
+        oprot.writeByte(struct.device);
+        oprot.writeFieldEnd();
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_del_all_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_del_all_argsTupleScheme getScheme() {
+        return new pal_port_del_all_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_del_all_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_del_all_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_del_all_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetDevice()) {
+          optionals.set(0);
+        }
+        oprot.writeBitSet(optionals, 1);
+        if (struct.isSetDevice()) {
+          oprot.writeByte(struct.device);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_del_all_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(1);
+        if (incoming.get(0)) {
+          struct.device = iprot.readByte();
+          struct.setDeviceIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_del_all_result implements org.apache.thrift.TBase<pal_port_del_all_result, pal_port_del_all_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_del_all_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_del_all_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);
+    private static final org.apache.thrift.protocol.TField OUCH_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_del_all_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_del_all_resultTupleSchemeFactory();
+
+    public int success; // required
+    public InvalidPalOperation ouch; // 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"),
+      OUCH((short)1, "ouch");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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;
+          case 1: // OUCH
+            return OUCH;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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          , "pal_status_t")));
+      tmpMap.put(_Fields.OUCH, new org.apache.thrift.meta_data.FieldMetaData("ouch", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, InvalidPalOperation.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_del_all_result.class, metaDataMap);
+    }
+
+    public pal_port_del_all_result() {
+    }
+
+    public pal_port_del_all_result(
+      int success,
+      InvalidPalOperation ouch)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch = ouch;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_del_all_result(pal_port_del_all_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_del_all_result deepCopy() {
+      return new pal_port_del_all_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_del_all_result setSuccess(int success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public InvalidPalOperation getOuch() {
+      return this.ouch;
+    }
+
+    public pal_port_del_all_result setOuch(InvalidPalOperation ouch) {
+      this.ouch = ouch;
+      return this;
+    }
+
+    public void unsetOuch() {
+      this.ouch = null;
+    }
+
+    /** Returns true if field ouch is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch() {
+      return this.ouch != null;
+    }
+
+    public void setOuchIsSet(boolean value) {
+      if (!value) {
+        this.ouch = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((java.lang.Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_del_all_result)
+        return this.equals((pal_port_del_all_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_del_all_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      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;
+      }
+
+      boolean this_present_ouch = true && this.isSetOuch();
+      boolean that_present_ouch = true && that.isSetOuch();
+      if (this_present_ouch || that_present_ouch) {
+        if (!(this_present_ouch && that_present_ouch))
+          return false;
+        if (!this.ouch.equals(that.ouch))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + success;
+
+      hashCode = hashCode * 8191 + ((isSetOuch()) ? 131071 : 524287);
+      if (isSetOuch())
+        hashCode = hashCode * 8191 + ouch.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_del_all_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch()).compareTo(other.isSetOuch());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch, other.ouch);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_del_all_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch:");
+      if (this.ouch == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_del_all_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_del_all_resultStandardScheme getScheme() {
+        return new pal_port_del_all_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_del_all_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_del_all_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_del_all_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.success = iprot.readI32();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch = new InvalidPalOperation();
+                struct.ouch.read(iprot);
+                struct.setOuchIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_del_all_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeI32(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch != null) {
+          oprot.writeFieldBegin(OUCH_FIELD_DESC);
+          struct.ouch.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_del_all_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_del_all_resultTupleScheme getScheme() {
+        return new pal_port_del_all_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_del_all_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_del_all_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_del_all_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          oprot.writeI32(struct.success);
+        }
+        if (struct.isSetOuch()) {
+          struct.ouch.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_del_all_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = iprot.readI32();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch = new InvalidPalOperation();
+          struct.ouch.read(iprot);
+          struct.setOuchIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_enable_args implements org.apache.thrift.TBase<pal_port_enable_args, pal_port_enable_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_enable_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_enable_args");
+
+    private static final org.apache.thrift.protocol.TField DEVICE_FIELD_DESC = new org.apache.thrift.protocol.TField("device", org.apache.thrift.protocol.TType.BYTE, (short)1);
+    private static final org.apache.thrift.protocol.TField DEV_PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("dev_port", org.apache.thrift.protocol.TType.I32, (short)2);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_enable_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_enable_argsTupleSchemeFactory();
+
+    public byte device; // required
+    public int dev_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 {
+      DEVICE((short)1, "device"),
+      DEV_PORT((short)2, "dev_port");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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: // DEVICE
+            return DEVICE;
+          case 2: // DEV_PORT
+            return DEV_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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __DEVICE_ISSET_ID = 0;
+    private static final int __DEV_PORT_ISSET_ID = 1;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.DEVICE, new org.apache.thrift.meta_data.FieldMetaData("device", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE          , "pal_device_t")));
+      tmpMap.put(_Fields.DEV_PORT, new org.apache.thrift.meta_data.FieldMetaData("dev_port", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "pal_dev_port_t")));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_enable_args.class, metaDataMap);
+    }
+
+    public pal_port_enable_args() {
+    }
+
+    public pal_port_enable_args(
+      byte device,
+      int dev_port)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_enable_args(pal_port_enable_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+      this.dev_port = other.dev_port;
+    }
+
+    public pal_port_enable_args deepCopy() {
+      return new pal_port_enable_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+      setDev_portIsSet(false);
+      this.dev_port = 0;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_enable_args setDevice(byte device) {
+      this.device = device;
+      setDeviceIsSet(true);
+      return this;
+    }
+
+    public void unsetDevice() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    /** Returns true if field device is set (has been assigned a value) and false otherwise */
+    public boolean isSetDevice() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    public void setDeviceIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEVICE_ISSET_ID, value);
+    }
+
+    public int getDev_port() {
+      return this.dev_port;
+    }
+
+    public pal_port_enable_args setDev_port(int dev_port) {
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+      return this;
+    }
+
+    public void unsetDev_port() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    /** Returns true if field dev_port is set (has been assigned a value) and false otherwise */
+    public boolean isSetDev_port() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    public void setDev_portIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEV_PORT_ISSET_ID, value);
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((java.lang.Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((java.lang.Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_enable_args)
+        return this.equals((pal_port_enable_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_enable_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_device = true;
+      boolean that_present_device = true;
+      if (this_present_device || that_present_device) {
+        if (!(this_present_device && that_present_device))
+          return false;
+        if (this.device != that.device)
+          return false;
+      }
+
+      boolean this_present_dev_port = true;
+      boolean that_present_dev_port = true;
+      if (this_present_dev_port || that_present_dev_port) {
+        if (!(this_present_dev_port && that_present_dev_port))
+          return false;
+        if (this.dev_port != that.dev_port)
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + (int) (device);
+
+      hashCode = hashCode * 8191 + dev_port;
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_enable_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetDevice()).compareTo(other.isSetDevice());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDevice()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.device, other.device);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetDev_port()).compareTo(other.isSetDev_port());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDev_port()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dev_port, other.dev_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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_enable_args(");
+      boolean first = true;
+
+      sb.append("device:");
+      sb.append(this.device);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("dev_port:");
+      sb.append(this.dev_port);
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_enable_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_enable_argsStandardScheme getScheme() {
+        return new pal_port_enable_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_enable_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_enable_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_enable_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // DEVICE
+              if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
+                struct.device = iprot.readByte();
+                struct.setDeviceIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DEV_PORT
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.dev_port = iprot.readI32();
+                struct.setDev_portIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_enable_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(DEVICE_FIELD_DESC);
+        oprot.writeByte(struct.device);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(DEV_PORT_FIELD_DESC);
+        oprot.writeI32(struct.dev_port);
+        oprot.writeFieldEnd();
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_enable_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_enable_argsTupleScheme getScheme() {
+        return new pal_port_enable_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_enable_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_enable_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_enable_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetDevice()) {
+          optionals.set(0);
+        }
+        if (struct.isSetDev_port()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetDevice()) {
+          oprot.writeByte(struct.device);
+        }
+        if (struct.isSetDev_port()) {
+          oprot.writeI32(struct.dev_port);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_enable_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.device = iprot.readByte();
+          struct.setDeviceIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.dev_port = iprot.readI32();
+          struct.setDev_portIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_enable_result implements org.apache.thrift.TBase<pal_port_enable_result, pal_port_enable_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_enable_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_enable_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);
+    private static final org.apache.thrift.protocol.TField OUCH_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_enable_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_enable_resultTupleSchemeFactory();
+
+    public int success; // required
+    public InvalidPalOperation ouch; // 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"),
+      OUCH((short)1, "ouch");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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;
+          case 1: // OUCH
+            return OUCH;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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          , "pal_status_t")));
+      tmpMap.put(_Fields.OUCH, new org.apache.thrift.meta_data.FieldMetaData("ouch", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, InvalidPalOperation.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_enable_result.class, metaDataMap);
+    }
+
+    public pal_port_enable_result() {
+    }
+
+    public pal_port_enable_result(
+      int success,
+      InvalidPalOperation ouch)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch = ouch;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_enable_result(pal_port_enable_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_enable_result deepCopy() {
+      return new pal_port_enable_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_enable_result setSuccess(int success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public InvalidPalOperation getOuch() {
+      return this.ouch;
+    }
+
+    public pal_port_enable_result setOuch(InvalidPalOperation ouch) {
+      this.ouch = ouch;
+      return this;
+    }
+
+    public void unsetOuch() {
+      this.ouch = null;
+    }
+
+    /** Returns true if field ouch is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch() {
+      return this.ouch != null;
+    }
+
+    public void setOuchIsSet(boolean value) {
+      if (!value) {
+        this.ouch = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((java.lang.Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_enable_result)
+        return this.equals((pal_port_enable_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_enable_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      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;
+      }
+
+      boolean this_present_ouch = true && this.isSetOuch();
+      boolean that_present_ouch = true && that.isSetOuch();
+      if (this_present_ouch || that_present_ouch) {
+        if (!(this_present_ouch && that_present_ouch))
+          return false;
+        if (!this.ouch.equals(that.ouch))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + success;
+
+      hashCode = hashCode * 8191 + ((isSetOuch()) ? 131071 : 524287);
+      if (isSetOuch())
+        hashCode = hashCode * 8191 + ouch.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_enable_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch()).compareTo(other.isSetOuch());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch, other.ouch);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_enable_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch:");
+      if (this.ouch == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_enable_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_enable_resultStandardScheme getScheme() {
+        return new pal_port_enable_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_enable_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_enable_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_enable_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.success = iprot.readI32();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch = new InvalidPalOperation();
+                struct.ouch.read(iprot);
+                struct.setOuchIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_enable_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeI32(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch != null) {
+          oprot.writeFieldBegin(OUCH_FIELD_DESC);
+          struct.ouch.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_enable_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_enable_resultTupleScheme getScheme() {
+        return new pal_port_enable_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_enable_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_enable_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_enable_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          oprot.writeI32(struct.success);
+        }
+        if (struct.isSetOuch()) {
+          struct.ouch.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_enable_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = iprot.readI32();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch = new InvalidPalOperation();
+          struct.ouch.read(iprot);
+          struct.setOuchIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_dis_args implements org.apache.thrift.TBase<pal_port_dis_args, pal_port_dis_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_dis_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_dis_args");
+
+    private static final org.apache.thrift.protocol.TField DEVICE_FIELD_DESC = new org.apache.thrift.protocol.TField("device", org.apache.thrift.protocol.TType.BYTE, (short)1);
+    private static final org.apache.thrift.protocol.TField DEV_PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("dev_port", org.apache.thrift.protocol.TType.I32, (short)2);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_dis_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_dis_argsTupleSchemeFactory();
+
+    public byte device; // required
+    public int dev_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 {
+      DEVICE((short)1, "device"),
+      DEV_PORT((short)2, "dev_port");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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: // DEVICE
+            return DEVICE;
+          case 2: // DEV_PORT
+            return DEV_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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __DEVICE_ISSET_ID = 0;
+    private static final int __DEV_PORT_ISSET_ID = 1;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.DEVICE, new org.apache.thrift.meta_data.FieldMetaData("device", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE          , "pal_device_t")));
+      tmpMap.put(_Fields.DEV_PORT, new org.apache.thrift.meta_data.FieldMetaData("dev_port", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "pal_dev_port_t")));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_dis_args.class, metaDataMap);
+    }
+
+    public pal_port_dis_args() {
+    }
+
+    public pal_port_dis_args(
+      byte device,
+      int dev_port)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_dis_args(pal_port_dis_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+      this.dev_port = other.dev_port;
+    }
+
+    public pal_port_dis_args deepCopy() {
+      return new pal_port_dis_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+      setDev_portIsSet(false);
+      this.dev_port = 0;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_dis_args setDevice(byte device) {
+      this.device = device;
+      setDeviceIsSet(true);
+      return this;
+    }
+
+    public void unsetDevice() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    /** Returns true if field device is set (has been assigned a value) and false otherwise */
+    public boolean isSetDevice() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    public void setDeviceIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEVICE_ISSET_ID, value);
+    }
+
+    public int getDev_port() {
+      return this.dev_port;
+    }
+
+    public pal_port_dis_args setDev_port(int dev_port) {
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+      return this;
+    }
+
+    public void unsetDev_port() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    /** Returns true if field dev_port is set (has been assigned a value) and false otherwise */
+    public boolean isSetDev_port() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    public void setDev_portIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEV_PORT_ISSET_ID, value);
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((java.lang.Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((java.lang.Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_dis_args)
+        return this.equals((pal_port_dis_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_dis_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_device = true;
+      boolean that_present_device = true;
+      if (this_present_device || that_present_device) {
+        if (!(this_present_device && that_present_device))
+          return false;
+        if (this.device != that.device)
+          return false;
+      }
+
+      boolean this_present_dev_port = true;
+      boolean that_present_dev_port = true;
+      if (this_present_dev_port || that_present_dev_port) {
+        if (!(this_present_dev_port && that_present_dev_port))
+          return false;
+        if (this.dev_port != that.dev_port)
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + (int) (device);
+
+      hashCode = hashCode * 8191 + dev_port;
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_dis_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetDevice()).compareTo(other.isSetDevice());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDevice()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.device, other.device);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetDev_port()).compareTo(other.isSetDev_port());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDev_port()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dev_port, other.dev_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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_dis_args(");
+      boolean first = true;
+
+      sb.append("device:");
+      sb.append(this.device);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("dev_port:");
+      sb.append(this.dev_port);
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_dis_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_dis_argsStandardScheme getScheme() {
+        return new pal_port_dis_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_dis_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_dis_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_dis_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // DEVICE
+              if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
+                struct.device = iprot.readByte();
+                struct.setDeviceIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DEV_PORT
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.dev_port = iprot.readI32();
+                struct.setDev_portIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_dis_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(DEVICE_FIELD_DESC);
+        oprot.writeByte(struct.device);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(DEV_PORT_FIELD_DESC);
+        oprot.writeI32(struct.dev_port);
+        oprot.writeFieldEnd();
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_dis_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_dis_argsTupleScheme getScheme() {
+        return new pal_port_dis_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_dis_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_dis_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_dis_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetDevice()) {
+          optionals.set(0);
+        }
+        if (struct.isSetDev_port()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetDevice()) {
+          oprot.writeByte(struct.device);
+        }
+        if (struct.isSetDev_port()) {
+          oprot.writeI32(struct.dev_port);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_dis_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.device = iprot.readByte();
+          struct.setDeviceIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.dev_port = iprot.readI32();
+          struct.setDev_portIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_dis_result implements org.apache.thrift.TBase<pal_port_dis_result, pal_port_dis_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_dis_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_dis_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);
+    private static final org.apache.thrift.protocol.TField OUCH_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_dis_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_dis_resultTupleSchemeFactory();
+
+    public int success; // required
+    public InvalidPalOperation ouch; // 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"),
+      OUCH((short)1, "ouch");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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;
+          case 1: // OUCH
+            return OUCH;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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          , "pal_status_t")));
+      tmpMap.put(_Fields.OUCH, new org.apache.thrift.meta_data.FieldMetaData("ouch", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, InvalidPalOperation.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_dis_result.class, metaDataMap);
+    }
+
+    public pal_port_dis_result() {
+    }
+
+    public pal_port_dis_result(
+      int success,
+      InvalidPalOperation ouch)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch = ouch;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_dis_result(pal_port_dis_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_dis_result deepCopy() {
+      return new pal_port_dis_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_dis_result setSuccess(int success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public InvalidPalOperation getOuch() {
+      return this.ouch;
+    }
+
+    public pal_port_dis_result setOuch(InvalidPalOperation ouch) {
+      this.ouch = ouch;
+      return this;
+    }
+
+    public void unsetOuch() {
+      this.ouch = null;
+    }
+
+    /** Returns true if field ouch is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch() {
+      return this.ouch != null;
+    }
+
+    public void setOuchIsSet(boolean value) {
+      if (!value) {
+        this.ouch = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((java.lang.Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_dis_result)
+        return this.equals((pal_port_dis_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_dis_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      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;
+      }
+
+      boolean this_present_ouch = true && this.isSetOuch();
+      boolean that_present_ouch = true && that.isSetOuch();
+      if (this_present_ouch || that_present_ouch) {
+        if (!(this_present_ouch && that_present_ouch))
+          return false;
+        if (!this.ouch.equals(that.ouch))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + success;
+
+      hashCode = hashCode * 8191 + ((isSetOuch()) ? 131071 : 524287);
+      if (isSetOuch())
+        hashCode = hashCode * 8191 + ouch.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_dis_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch()).compareTo(other.isSetOuch());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch, other.ouch);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_dis_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch:");
+      if (this.ouch == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_dis_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_dis_resultStandardScheme getScheme() {
+        return new pal_port_dis_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_dis_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_dis_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_dis_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.success = iprot.readI32();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch = new InvalidPalOperation();
+                struct.ouch.read(iprot);
+                struct.setOuchIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_dis_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeI32(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch != null) {
+          oprot.writeFieldBegin(OUCH_FIELD_DESC);
+          struct.ouch.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_dis_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_dis_resultTupleScheme getScheme() {
+        return new pal_port_dis_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_dis_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_dis_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_dis_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          oprot.writeI32(struct.success);
+        }
+        if (struct.isSetOuch()) {
+          struct.ouch.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_dis_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = iprot.readI32();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch = new InvalidPalOperation();
+          struct.ouch.read(iprot);
+          struct.setOuchIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_oper_status_get_args implements org.apache.thrift.TBase<pal_port_oper_status_get_args, pal_port_oper_status_get_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_oper_status_get_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_oper_status_get_args");
+
+    private static final org.apache.thrift.protocol.TField DEVICE_FIELD_DESC = new org.apache.thrift.protocol.TField("device", org.apache.thrift.protocol.TType.BYTE, (short)1);
+    private static final org.apache.thrift.protocol.TField DEV_PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("dev_port", org.apache.thrift.protocol.TType.I32, (short)2);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_oper_status_get_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_oper_status_get_argsTupleSchemeFactory();
+
+    public byte device; // required
+    public int dev_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 {
+      DEVICE((short)1, "device"),
+      DEV_PORT((short)2, "dev_port");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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: // DEVICE
+            return DEVICE;
+          case 2: // DEV_PORT
+            return DEV_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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __DEVICE_ISSET_ID = 0;
+    private static final int __DEV_PORT_ISSET_ID = 1;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.DEVICE, new org.apache.thrift.meta_data.FieldMetaData("device", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE          , "pal_device_t")));
+      tmpMap.put(_Fields.DEV_PORT, new org.apache.thrift.meta_data.FieldMetaData("dev_port", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "pal_dev_port_t")));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_oper_status_get_args.class, metaDataMap);
+    }
+
+    public pal_port_oper_status_get_args() {
+    }
+
+    public pal_port_oper_status_get_args(
+      byte device,
+      int dev_port)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_oper_status_get_args(pal_port_oper_status_get_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+      this.dev_port = other.dev_port;
+    }
+
+    public pal_port_oper_status_get_args deepCopy() {
+      return new pal_port_oper_status_get_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+      setDev_portIsSet(false);
+      this.dev_port = 0;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_oper_status_get_args setDevice(byte device) {
+      this.device = device;
+      setDeviceIsSet(true);
+      return this;
+    }
+
+    public void unsetDevice() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    /** Returns true if field device is set (has been assigned a value) and false otherwise */
+    public boolean isSetDevice() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    public void setDeviceIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEVICE_ISSET_ID, value);
+    }
+
+    public int getDev_port() {
+      return this.dev_port;
+    }
+
+    public pal_port_oper_status_get_args setDev_port(int dev_port) {
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+      return this;
+    }
+
+    public void unsetDev_port() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    /** Returns true if field dev_port is set (has been assigned a value) and false otherwise */
+    public boolean isSetDev_port() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    public void setDev_portIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEV_PORT_ISSET_ID, value);
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((java.lang.Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((java.lang.Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_oper_status_get_args)
+        return this.equals((pal_port_oper_status_get_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_oper_status_get_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_device = true;
+      boolean that_present_device = true;
+      if (this_present_device || that_present_device) {
+        if (!(this_present_device && that_present_device))
+          return false;
+        if (this.device != that.device)
+          return false;
+      }
+
+      boolean this_present_dev_port = true;
+      boolean that_present_dev_port = true;
+      if (this_present_dev_port || that_present_dev_port) {
+        if (!(this_present_dev_port && that_present_dev_port))
+          return false;
+        if (this.dev_port != that.dev_port)
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + (int) (device);
+
+      hashCode = hashCode * 8191 + dev_port;
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_oper_status_get_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetDevice()).compareTo(other.isSetDevice());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDevice()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.device, other.device);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetDev_port()).compareTo(other.isSetDev_port());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDev_port()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dev_port, other.dev_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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_oper_status_get_args(");
+      boolean first = true;
+
+      sb.append("device:");
+      sb.append(this.device);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("dev_port:");
+      sb.append(this.dev_port);
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_oper_status_get_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_oper_status_get_argsStandardScheme getScheme() {
+        return new pal_port_oper_status_get_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_oper_status_get_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_oper_status_get_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_oper_status_get_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // DEVICE
+              if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
+                struct.device = iprot.readByte();
+                struct.setDeviceIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DEV_PORT
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.dev_port = iprot.readI32();
+                struct.setDev_portIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_oper_status_get_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(DEVICE_FIELD_DESC);
+        oprot.writeByte(struct.device);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(DEV_PORT_FIELD_DESC);
+        oprot.writeI32(struct.dev_port);
+        oprot.writeFieldEnd();
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_oper_status_get_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_oper_status_get_argsTupleScheme getScheme() {
+        return new pal_port_oper_status_get_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_oper_status_get_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_oper_status_get_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_oper_status_get_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetDevice()) {
+          optionals.set(0);
+        }
+        if (struct.isSetDev_port()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetDevice()) {
+          oprot.writeByte(struct.device);
+        }
+        if (struct.isSetDev_port()) {
+          oprot.writeI32(struct.dev_port);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_oper_status_get_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.device = iprot.readByte();
+          struct.setDeviceIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.dev_port = iprot.readI32();
+          struct.setDev_portIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_oper_status_get_result implements org.apache.thrift.TBase<pal_port_oper_status_get_result, pal_port_oper_status_get_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_oper_status_get_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_oper_status_get_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);
+    private static final org.apache.thrift.protocol.TField OUCH_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_oper_status_get_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_oper_status_get_resultTupleSchemeFactory();
+
+    /**
+     * 
+     * @see pal_oper_status_t
+     */
+    public pal_oper_status_t success; // required
+    public InvalidPalOperation ouch; // 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 pal_oper_status_t
+       */
+      SUCCESS((short)0, "success"),
+      OUCH((short)1, "ouch");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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;
+          case 1: // OUCH
+            return OUCH;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, pal_oper_status_t.class)));
+      tmpMap.put(_Fields.OUCH, new org.apache.thrift.meta_data.FieldMetaData("ouch", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, InvalidPalOperation.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_oper_status_get_result.class, metaDataMap);
+    }
+
+    public pal_port_oper_status_get_result() {
+    }
+
+    public pal_port_oper_status_get_result(
+      pal_oper_status_t success,
+      InvalidPalOperation ouch)
+    {
+      this();
+      this.success = success;
+      this.ouch = ouch;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_oper_status_get_result(pal_port_oper_status_get_result other) {
+      if (other.isSetSuccess()) {
+        this.success = other.success;
+      }
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_oper_status_get_result deepCopy() {
+      return new pal_port_oper_status_get_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.ouch = null;
+    }
+
+    /**
+     * 
+     * @see pal_oper_status_t
+     */
+    public pal_oper_status_t getSuccess() {
+      return this.success;
+    }
+
+    /**
+     * 
+     * @see pal_oper_status_t
+     */
+    public pal_port_oper_status_get_result setSuccess(pal_oper_status_t 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 InvalidPalOperation getOuch() {
+      return this.ouch;
+    }
+
+    public pal_port_oper_status_get_result setOuch(InvalidPalOperation ouch) {
+      this.ouch = ouch;
+      return this;
+    }
+
+    public void unsetOuch() {
+      this.ouch = null;
+    }
+
+    /** Returns true if field ouch is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch() {
+      return this.ouch != null;
+    }
+
+    public void setOuchIsSet(boolean value) {
+      if (!value) {
+        this.ouch = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((pal_oper_status_t)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_oper_status_get_result)
+        return this.equals((pal_port_oper_status_get_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_oper_status_get_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      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;
+      }
+
+      boolean this_present_ouch = true && this.isSetOuch();
+      boolean that_present_ouch = true && that.isSetOuch();
+      if (this_present_ouch || that_present_ouch) {
+        if (!(this_present_ouch && that_present_ouch))
+          return false;
+        if (!this.ouch.equals(that.ouch))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+      if (isSetSuccess())
+        hashCode = hashCode * 8191 + success.getValue();
+
+      hashCode = hashCode * 8191 + ((isSetOuch()) ? 131071 : 524287);
+      if (isSetOuch())
+        hashCode = hashCode * 8191 + ouch.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_oper_status_get_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch()).compareTo(other.isSetOuch());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch, other.ouch);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_oper_status_get_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch:");
+      if (this.ouch == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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);
+      }
+    }
+
+    private static class pal_port_oper_status_get_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_oper_status_get_resultStandardScheme getScheme() {
+        return new pal_port_oper_status_get_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_oper_status_get_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_oper_status_get_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_oper_status_get_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.success = pal_oper_status_t.findByValue(iprot.readI32());
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch = new InvalidPalOperation();
+                struct.ouch.read(iprot);
+                struct.setOuchIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_oper_status_get_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeI32(struct.success.getValue());
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch != null) {
+          oprot.writeFieldBegin(OUCH_FIELD_DESC);
+          struct.ouch.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_oper_status_get_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_oper_status_get_resultTupleScheme getScheme() {
+        return new pal_port_oper_status_get_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_oper_status_get_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_oper_status_get_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_oper_status_get_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          oprot.writeI32(struct.success.getValue());
+        }
+        if (struct.isSetOuch()) {
+          struct.ouch.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_oper_status_get_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = pal_oper_status_t.findByValue(iprot.readI32());
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch = new InvalidPalOperation();
+          struct.ouch.read(iprot);
+          struct.setOuchIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_an_set_args implements org.apache.thrift.TBase<pal_port_an_set_args, pal_port_an_set_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_an_set_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_an_set_args");
+
+    private static final org.apache.thrift.protocol.TField DEVICE_FIELD_DESC = new org.apache.thrift.protocol.TField("device", org.apache.thrift.protocol.TType.BYTE, (short)1);
+    private static final org.apache.thrift.protocol.TField DEV_PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("dev_port", org.apache.thrift.protocol.TType.I32, (short)2);
+    private static final org.apache.thrift.protocol.TField AN_FIELD_DESC = new org.apache.thrift.protocol.TField("an", org.apache.thrift.protocol.TType.I32, (short)3);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_an_set_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_an_set_argsTupleSchemeFactory();
+
+    public byte device; // required
+    public int dev_port; // required
+    /**
+     * 
+     * @see pal_autoneg_policy_t
+     */
+    public pal_autoneg_policy_t an; // 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 {
+      DEVICE((short)1, "device"),
+      DEV_PORT((short)2, "dev_port"),
+      /**
+       * 
+       * @see pal_autoneg_policy_t
+       */
+      AN((short)3, "an");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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: // DEVICE
+            return DEVICE;
+          case 2: // DEV_PORT
+            return DEV_PORT;
+          case 3: // AN
+            return AN;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __DEVICE_ISSET_ID = 0;
+    private static final int __DEV_PORT_ISSET_ID = 1;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.DEVICE, new org.apache.thrift.meta_data.FieldMetaData("device", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE          , "pal_device_t")));
+      tmpMap.put(_Fields.DEV_PORT, new org.apache.thrift.meta_data.FieldMetaData("dev_port", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "pal_dev_port_t")));
+      tmpMap.put(_Fields.AN, new org.apache.thrift.meta_data.FieldMetaData("an", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, pal_autoneg_policy_t.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_an_set_args.class, metaDataMap);
+    }
+
+    public pal_port_an_set_args() {
+    }
+
+    public pal_port_an_set_args(
+      byte device,
+      int dev_port,
+      pal_autoneg_policy_t an)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+      this.an = an;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_an_set_args(pal_port_an_set_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+      this.dev_port = other.dev_port;
+      if (other.isSetAn()) {
+        this.an = other.an;
+      }
+    }
+
+    public pal_port_an_set_args deepCopy() {
+      return new pal_port_an_set_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+      setDev_portIsSet(false);
+      this.dev_port = 0;
+      this.an = null;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_an_set_args setDevice(byte device) {
+      this.device = device;
+      setDeviceIsSet(true);
+      return this;
+    }
+
+    public void unsetDevice() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    /** Returns true if field device is set (has been assigned a value) and false otherwise */
+    public boolean isSetDevice() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEVICE_ISSET_ID);
+    }
+
+    public void setDeviceIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEVICE_ISSET_ID, value);
+    }
+
+    public int getDev_port() {
+      return this.dev_port;
+    }
+
+    public pal_port_an_set_args setDev_port(int dev_port) {
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+      return this;
+    }
+
+    public void unsetDev_port() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    /** Returns true if field dev_port is set (has been assigned a value) and false otherwise */
+    public boolean isSetDev_port() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEV_PORT_ISSET_ID);
+    }
+
+    public void setDev_portIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEV_PORT_ISSET_ID, value);
+    }
+
+    /**
+     * 
+     * @see pal_autoneg_policy_t
+     */
+    public pal_autoneg_policy_t getAn() {
+      return this.an;
+    }
+
+    /**
+     * 
+     * @see pal_autoneg_policy_t
+     */
+    public pal_port_an_set_args setAn(pal_autoneg_policy_t an) {
+      this.an = an;
+      return this;
+    }
+
+    public void unsetAn() {
+      this.an = null;
+    }
+
+    /** Returns true if field an is set (has been assigned a value) and false otherwise */
+    public boolean isSetAn() {
+      return this.an != null;
+    }
+
+    public void setAnIsSet(boolean value) {
+      if (!value) {
+        this.an = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((java.lang.Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((java.lang.Integer)value);
+        }
+        break;
+
+      case AN:
+        if (value == null) {
+          unsetAn();
+        } else {
+          setAn((pal_autoneg_policy_t)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      case AN:
+        return getAn();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      case AN:
+        return isSetAn();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_an_set_args)
+        return this.equals((pal_port_an_set_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_an_set_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_device = true;
+      boolean that_present_device = true;
+      if (this_present_device || that_present_device) {
+        if (!(this_present_device && that_present_device))
+          return false;
+        if (this.device != that.device)
+          return false;
+      }
+
+      boolean this_present_dev_port = true;
+      boolean that_present_dev_port = true;
+      if (this_present_dev_port || that_present_dev_port) {
+        if (!(this_present_dev_port && that_present_dev_port))
+          return false;
+        if (this.dev_port != that.dev_port)
+          return false;
+      }
+
+      boolean this_present_an = true && this.isSetAn();
+      boolean that_present_an = true && that.isSetAn();
+      if (this_present_an || that_present_an) {
+        if (!(this_present_an && that_present_an))
+          return false;
+        if (!this.an.equals(that.an))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + (int) (device);
+
+      hashCode = hashCode * 8191 + dev_port;
+
+      hashCode = hashCode * 8191 + ((isSetAn()) ? 131071 : 524287);
+      if (isSetAn())
+        hashCode = hashCode * 8191 + an.getValue();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_an_set_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetDevice()).compareTo(other.isSetDevice());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDevice()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.device, other.device);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetDev_port()).compareTo(other.isSetDev_port());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDev_port()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dev_port, other.dev_port);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetAn()).compareTo(other.isSetAn());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetAn()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.an, other.an);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+    }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_an_set_args(");
+      boolean first = true;
+
+      sb.append("device:");
+      sb.append(this.device);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("dev_port:");
+      sb.append(this.dev_port);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("an:");
+      if (this.an == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.an);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_an_set_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_an_set_argsStandardScheme getScheme() {
+        return new pal_port_an_set_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_an_set_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_an_set_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_an_set_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // DEVICE
+              if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
+                struct.device = iprot.readByte();
+                struct.setDeviceIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // DEV_PORT
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.dev_port = iprot.readI32();
+                struct.setDev_portIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // AN
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.an = pal_autoneg_policy_t.findByValue(iprot.readI32());
+                struct.setAnIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_an_set_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(DEVICE_FIELD_DESC);
+        oprot.writeByte(struct.device);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(DEV_PORT_FIELD_DESC);
+        oprot.writeI32(struct.dev_port);
+        oprot.writeFieldEnd();
+        if (struct.an != null) {
+          oprot.writeFieldBegin(AN_FIELD_DESC);
+          oprot.writeI32(struct.an.getValue());
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_an_set_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_an_set_argsTupleScheme getScheme() {
+        return new pal_port_an_set_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_an_set_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_an_set_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_an_set_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetDevice()) {
+          optionals.set(0);
+        }
+        if (struct.isSetDev_port()) {
+          optionals.set(1);
+        }
+        if (struct.isSetAn()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetDevice()) {
+          oprot.writeByte(struct.device);
+        }
+        if (struct.isSetDev_port()) {
+          oprot.writeI32(struct.dev_port);
+        }
+        if (struct.isSetAn()) {
+          oprot.writeI32(struct.an.getValue());
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_an_set_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(3);
+        if (incoming.get(0)) {
+          struct.device = iprot.readByte();
+          struct.setDeviceIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.dev_port = iprot.readI32();
+          struct.setDev_portIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.an = pal_autoneg_policy_t.findByValue(iprot.readI32());
+          struct.setAnIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+  public static class pal_port_an_set_result implements org.apache.thrift.TBase<pal_port_an_set_result, pal_port_an_set_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_an_set_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_an_set_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);
+    private static final org.apache.thrift.protocol.TField OUCH_FIELD_DESC = new org.apache.thrift.protocol.TField("ouch", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_an_set_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_an_set_resultTupleSchemeFactory();
+
+    public int success; // required
+    public InvalidPalOperation ouch; // 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"),
+      OUCH((short)1, "ouch");
+
+      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();
+
+      static {
+        for (_Fields field : java.util.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;
+          case 1: // OUCH
+            return OUCH;
+          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 java.lang.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(java.lang.String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final java.lang.String _fieldName;
+
+      _Fields(short thriftId, java.lang.String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public java.lang.String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private byte __isset_bitfield = 0;
+    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.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          , "pal_status_t")));
+      tmpMap.put(_Fields.OUCH, new org.apache.thrift.meta_data.FieldMetaData("ouch", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, InvalidPalOperation.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_an_set_result.class, metaDataMap);
+    }
+
+    public pal_port_an_set_result() {
+    }
+
+    public pal_port_an_set_result(
+      int success,
+      InvalidPalOperation ouch)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch = ouch;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_an_set_result(pal_port_an_set_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_an_set_result deepCopy() {
+      return new pal_port_an_set_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_an_set_result setSuccess(int success) {
+      this.success = success;
+      setSuccessIsSet(true);
+      return this;
+    }
+
+    public void unsetSuccess() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
+    }
+
+    public InvalidPalOperation getOuch() {
+      return this.ouch;
+    }
+
+    public pal_port_an_set_result setOuch(InvalidPalOperation ouch) {
+      this.ouch = ouch;
+      return this;
+    }
+
+    public void unsetOuch() {
+      this.ouch = null;
+    }
+
+    /** Returns true if field ouch is set (has been assigned a value) and false otherwise */
+    public boolean isSetOuch() {
+      return this.ouch != null;
+    }
+
+    public void setOuchIsSet(boolean value) {
+      if (!value) {
+        this.ouch = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, java.lang.Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((java.lang.Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public java.lang.Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new java.lang.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 java.lang.IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new java.lang.IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(java.lang.Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_an_set_result)
+        return this.equals((pal_port_an_set_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_an_set_result that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      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;
+      }
+
+      boolean this_present_ouch = true && this.isSetOuch();
+      boolean that_present_ouch = true && that.isSetOuch();
+      if (this_present_ouch || that_present_ouch) {
+        if (!(this_present_ouch && that_present_ouch))
+          return false;
+        if (!this.ouch.equals(that.ouch))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + success;
+
+      hashCode = hashCode * 8191 + ((isSetOuch()) ? 131071 : 524287);
+      if (isSetOuch())
+        hashCode = hashCode * 8191 + ouch.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_an_set_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = java.lang.Boolean.valueOf(isSetOuch()).compareTo(other.isSetOuch());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetOuch()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ouch, other.ouch);
+        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 {
+      scheme(iprot).read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      scheme(oprot).write(oprot, this);
+      }
+
+    @Override
+    public java.lang.String toString() {
+      java.lang.StringBuilder sb = new java.lang.StringBuilder("pal_port_an_set_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      sb.append(this.success);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ouch:");
+      if (this.ouch == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ouch);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+    }
+
+    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, java.lang.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_bitfield = 0;
+        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);
+      }
+    }
+
+    private static class pal_port_an_set_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_an_set_resultStandardScheme getScheme() {
+        return new pal_port_an_set_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_an_set_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_an_set_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_an_set_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.success = iprot.readI32();
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // OUCH
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ouch = new InvalidPalOperation();
+                struct.ouch.read(iprot);
+                struct.setOuchIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, pal_port_an_set_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeI32(struct.success);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ouch != null) {
+          oprot.writeFieldBegin(OUCH_FIELD_DESC);
+          struct.ouch.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_an_set_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_an_set_resultTupleScheme getScheme() {
+        return new pal_port_an_set_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_an_set_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_an_set_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_an_set_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet optionals = new java.util.BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetOuch()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetSuccess()) {
+          oprot.writeI32(struct.success);
+        }
+        if (struct.isSetOuch()) {
+          struct.ouch.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_an_set_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
+        java.util.BitSet incoming = iprot.readBitSet(2);
+        if (incoming.get(0)) {
+          struct.success = iprot.readI32();
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ouch = new InvalidPalOperation();
+          struct.ouch.read(iprot);
+          struct.setOuchIsSet(true);
+        }
+      }
+    }
+
+    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+    }
+  }
+
+}
diff --git a/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_autoneg_policy_t.java b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_autoneg_policy_t.java
new file mode 100644
index 0000000..40efb53
--- /dev/null
+++ b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_autoneg_policy_t.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.barefoot.pal;
+/**
+ * Autogenerated by Thrift Compiler (0.10.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.thrift.TEnum;
+
+public enum pal_autoneg_policy_t implements org.apache.thrift.TEnum {
+  BF_AN_DEFAULT(0),
+  BF_AN_FORCE_ENABLE(1),
+  BF_AN_FORCE_DISABLE(2);
+
+  private final int value;
+
+  private pal_autoneg_policy_t(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 pal_autoneg_policy_t findByValue(int value) { 
+    switch (value) {
+      case 0:
+        return BF_AN_DEFAULT;
+      case 1:
+        return BF_AN_FORCE_ENABLE;
+      case 2:
+        return BF_AN_FORCE_DISABLE;
+      default:
+        return null;
+    }
+  }
+}
diff --git a/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_fec_type_t.java b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_fec_type_t.java
new file mode 100644
index 0000000..94a2a9e
--- /dev/null
+++ b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_fec_type_t.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.barefoot.pal;
+/**
+ * Autogenerated by Thrift Compiler (0.10.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.thrift.TEnum;
+
+public enum pal_fec_type_t implements org.apache.thrift.TEnum {
+  BF_FEC_TYP_NONE(0),
+  BF_FEC_TYP_FIRECODE(1),
+  BF_FEC_TYP_REED_SOLOMON(2);
+
+  private final int value;
+
+  private pal_fec_type_t(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 pal_fec_type_t findByValue(int value) { 
+    switch (value) {
+      case 0:
+        return BF_FEC_TYP_NONE;
+      case 1:
+        return BF_FEC_TYP_FIRECODE;
+      case 2:
+        return BF_FEC_TYP_REED_SOLOMON;
+      default:
+        return null;
+    }
+  }
+}
diff --git a/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_oper_status_t.java b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_oper_status_t.java
new file mode 100644
index 0000000..d2dc690
--- /dev/null
+++ b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_oper_status_t.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.barefoot.pal;
+/**
+ * Autogenerated by Thrift Compiler (0.10.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.thrift.TEnum;
+
+public enum pal_oper_status_t implements org.apache.thrift.TEnum {
+  BF_PORT_DOWN(0),
+  BF_PORT_UP(1);
+
+  private final int value;
+
+  private pal_oper_status_t(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 pal_oper_status_t findByValue(int value) { 
+    switch (value) {
+      case 0:
+        return BF_PORT_DOWN;
+      case 1:
+        return BF_PORT_UP;
+      default:
+        return null;
+    }
+  }
+}
diff --git a/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_port_speed_t.java b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_port_speed_t.java
new file mode 100644
index 0000000..2ae3dc4
--- /dev/null
+++ b/drivers/barefoot/src/main/java/org/onosproject/drivers/barefoot/pal/pal_port_speed_t.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.drivers.barefoot.pal;
+/**
+ * Autogenerated by Thrift Compiler (0.10.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+import java.util.Map;
+import java.util.HashMap;
+import org.apache.thrift.TEnum;
+
+public enum pal_port_speed_t implements org.apache.thrift.TEnum {
+  BF_SPEED_NONE(0),
+  BF_SPEED_1G(1),
+  BF_SPEED_10G(2),
+  BF_SPEED_25G(3),
+  BF_SPEED_40G(4),
+  BF_SPEED_40G_NB(5),
+  BF_SPEED_50G(6),
+  BF_SPEED_100G(7),
+  BF_SPEED_40G_NON_BREAKABLE(8);
+
+  private final int value;
+
+  private pal_port_speed_t(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 pal_port_speed_t findByValue(int value) { 
+    switch (value) {
+      case 0:
+        return BF_SPEED_NONE;
+      case 1:
+        return BF_SPEED_1G;
+      case 2:
+        return BF_SPEED_10G;
+      case 3:
+        return BF_SPEED_25G;
+      case 4:
+        return BF_SPEED_40G;
+      case 5:
+        return BF_SPEED_40G_NB;
+      case 6:
+        return BF_SPEED_50G;
+      case 7:
+        return BF_SPEED_100G;
+      case 8:
+        return BF_SPEED_40G_NON_BREAKABLE;
+      default:
+        return null;
+    }
+  }
+}
