diff --git a/drivers/barefoot-pro/BUCK b/drivers/barefoot-pro/BUCK
new file mode 100644
index 0000000..0a8f81d
--- /dev/null
+++ b/drivers/barefoot-pro/BUCK
@@ -0,0 +1,39 @@
+GRPC_VER = '1.3.1'
+
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//drivers/barefoot:onos-drivers-barefoot',
+    '//drivers/p4runtime:onos-drivers-p4runtime',
+    '//providers/general/device:onos-providers-general-device',
+    '//incubator/api:onos-incubator-api',
+    ':thrift',
+]
+
+BUNDLES = [
+    ':onos-drivers-barefoot-pro',
+    ':thrift',
+]
+
+osgi_jar(
+    deps = COMPILE_DEPS,
+)
+
+onos_app(
+    app_name = 'org.onosproject.drivers.barefoot-pro',
+    title = 'Barefoot-Pro Drivers',
+    category = 'Drivers',
+    url = 'http://onosproject.org',
+    description = 'Adds support for Barefoot-based devices using both open and proprietary APIs',
+    included_bundles = BUNDLES,
+    required_apps = [
+        'org.onosproject.drivers.barefoot',
+    ],
+)
+
+remote_jar(
+    name = 'thrift',
+    out = 'thrift-0.11.0.jar',
+    url = 'mvn:org.apache.thrift:libthrift:jar:0.11.0',
+    sha1 = '4f4f1c1fbbae63258625dea71007fa41bee7edb3',
+    maven_coords = 'org.apache.thrift:libthrift:jar:NON-OSGI:0.11.0',
+)
diff --git a/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/BarefootProDriversLoader.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/BarefootProDriversLoader.java
new file mode 100644
index 0000000..c6cf18c
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/BarefootProDriversLoader.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2018-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.pro;
+
+import org.apache.felix.scr.annotations.Component;
+import org.onosproject.net.driver.AbstractDriverLoader;
+
+/**
+ * Loader for the Barefoot-PRO device drivers.
+ */
+@Component(immediate = true)
+public class BarefootProDriversLoader extends AbstractDriverLoader {
+
+    public BarefootProDriversLoader() {
+        super("/barefoot-pro-drivers.xml");
+    }
+}
diff --git a/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/TofinoPortConfigurator.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/TofinoPortConfigurator.java
new file mode 100644
index 0000000..adb1e8a
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/TofinoPortConfigurator.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2018-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.pro;
+
+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.onosproject.drivers.barefoot.pro.pal.pal;
+import org.onosproject.drivers.barefoot.pro.pal.pal_autoneg_policy_t;
+import org.onosproject.drivers.barefoot.pro.pal.pal_fec_type_t;
+import org.onosproject.drivers.barefoot.pro.pal.pal_port_speed_t;
+import org.onosproject.incubator.net.config.basics.PortDescriptionsConfig;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.provider.general.device.api.GeneralProviderDeviceConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Map;
+
+import static java.lang.Boolean.parseBoolean;
+
+/**
+ * Class to configure ports on Tofino.
+ */
+final class TofinoPortConfigurator {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private static final String P4RUNTIME = "p4runtime";
+    private static final String PROTOCOL_KEY_IP = "ip";
+    private static final String DEVICE_ID = "deviceId";
+    private static final String AUTONEG = "autoneg";
+    private static final int PAL_MGMT_PORT = 9090;
+    private static final String PAL_THRIFT_SERVICE = "pal";
+
+    private static final pal_fec_type_t DEFAULT_FEC_TYPE =
+            pal_fec_type_t.BF_FEC_TYP_NONE;
+
+    private final NetworkConfigService netcfgService;
+
+    TofinoPortConfigurator(NetworkConfigService netcfgService) {
+        this.netcfgService = netcfgService;
+    }
+
+    // FIXME Currently use thrift, may use gNMI to manage it in the future.
+    public void setupPorts(DeviceId deviceId) {
+        GeneralProviderDeviceConfig providerConfig = netcfgService
+                .getConfig(deviceId, GeneralProviderDeviceConfig.class);
+        PortDescriptionsConfig portConfig = netcfgService
+                .getConfig(deviceId, PortDescriptionsConfig.class);
+
+        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();
+
+        if (ports == null) {
+            log.warn("Empty port configuration for {}, won't add any port", deviceId);
+            return;
+        }
+
+         ports.forEach(port -> {
+            pal_port_speed_t speed = getPortSpeed(port.portSpeed());
+            String anString = port.annotations().value(AUTONEG);
+            pal_autoneg_policy_t an = anString != null && parseBoolean(anString)
+                    ? pal_autoneg_policy_t.BF_AN_FORCE_ENABLE
+                    : pal_autoneg_policy_t.BF_AN_FORCE_DISABLE;
+            addAndEnablePort(deviceId, port.portNumber().name(),
+                             ip, tofinoDeviceId,
+                             (int) port.portNumber().toLong(), speed,
+                             DEFAULT_FEC_TYPE, an);
+        });
+    }
+
+    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(DeviceId deviceId, String portName, String ip,
+                                  byte tofinoDeviceId,
+                                  int dp, pal_port_speed_t speed,
+                                  pal_fec_type_t fec,
+                                  pal_autoneg_policy_t an) {
+        log.info("Adding port {} to {}: dp={}, speed={}, an={}, fec={}",
+                 portName, deviceId, dp, speed.name(), an.name(), fec.name());
+
+        TTransport transport = new TSocket(ip, PAL_MGMT_PORT);
+        try {
+            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(tofinoDeviceId, dp, speed, fec);
+            client.pal_port_an_set(tofinoDeviceId, dp, an);
+            client.pal_port_enable(tofinoDeviceId, dp);
+        } catch (TException x) {
+            log.error("Error adding port {} to device {}:\n{}",
+                      dp, tofinoDeviceId, ip, x);
+        } finally {
+            if (transport.isOpen()) {
+                transport.close();
+            }
+        }
+    }
+}
diff --git a/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/TofinoProPipelineProgrammable.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/TofinoProPipelineProgrammable.java
new file mode 100644
index 0000000..8827502
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/TofinoProPipelineProgrammable.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2018-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.pro;
+
+import org.onosproject.drivers.barefoot.TofinoPipelineProgrammable;
+import org.onosproject.net.behaviour.PiPipelineProgrammable;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.pi.model.PiPipeconf;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ * Implementation of the PiPipelineProgrammable behaviour for a Tofino-based
+ * switch.
+ */
+public class TofinoProPipelineProgrammable
+        extends TofinoPipelineProgrammable
+        implements PiPipelineProgrammable {
+
+    @Override
+    public CompletableFuture<Boolean> deployPipeconf(PiPipeconf pipeconf) {
+        return super.deployPipeconf(pipeconf).thenApplyAsync(result -> {
+            if (result) {
+                doPortconfig();
+            }
+            return result;
+        });
+    }
+
+    private void doPortconfig() {
+        new TofinoPortConfigurator(handler().get(NetworkConfigService.class))
+                .setupPorts(data().deviceId());
+    }
+}
diff --git a/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/package-info.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/package-info.java
new file mode 100644
index 0000000..2edbf53
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2018-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 for Barefoot-Pro device drivers.
+ */
+package org.onosproject.drivers.barefoot.pro;
diff --git a/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/InvalidPalOperation.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/InvalidPalOperation.java
new file mode 100644
index 0000000..c47ad38
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/InvalidPalOperation.java
@@ -0,0 +1,368 @@
+package org.onosproject.drivers.barefoot.pro.pal;
+
+/**
+ * Autogenerated by Thrift Compiler (0.11.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.11.0)", date = "2018-01-31")
+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-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal.java
new file mode 100644
index 0000000..94226f2
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal.java
@@ -0,0 +1,14769 @@
+package org.onosproject.drivers.barefoot.pro.pal;
+
+/**
+ * Autogenerated by Thrift Compiler (0.11.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.11.0)", date = "2018-01-31")
+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_add_all(byte device, 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_enable_all(byte device) 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 boolean pal_port_is_valid(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 int pal_port_an_set_all(byte device, pal_autoneg_policy_t an) throws InvalidPalOperation, org.apache.thrift.TException;
+
+    public int pal_port_loopback_mode_set(byte dev, int dev_port, pal_loopback_mod_t mode) throws InvalidPalOperation, org.apache.thrift.TException;
+
+    public int pal_port_front_panel_port_to_dev_port_get(byte dev, int front_port, int front_chnl) 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<Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_add_all(byte device, pal_port_speed_t ps, pal_fec_type_t fec, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_del(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_del_all(byte device, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_enable(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_enable_all(byte device, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_dis(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<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_is_valid(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<Boolean> 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<Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_an_set_all(byte device, pal_autoneg_policy_t an, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_loopback_mode_set(byte dev, int dev_port, pal_loopback_mod_t mode, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException;
+
+    public void pal_port_front_panel_port_to_dev_port_get(byte dev, int front_port, int front_chnl, org.apache.thrift.async.AsyncMethodCallback<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_add_all(byte device, pal_port_speed_t ps, pal_fec_type_t fec) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_add_all(device, ps, fec);
+      return recv_pal_port_add_all();
+    }
+
+    public void send_pal_port_add_all(byte device, pal_port_speed_t ps, pal_fec_type_t fec) throws org.apache.thrift.TException
+    {
+      pal_port_add_all_args args = new pal_port_add_all_args();
+      args.setDevice(device);
+      args.setPs(ps);
+      args.setFec(fec);
+      sendBase("pal_port_add_all", args);
+    }
+
+    public int recv_pal_port_add_all() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_add_all_result result = new pal_port_add_all_result();
+      receiveBase(result, "pal_port_add_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_add_all 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_enable_all(byte device) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_enable_all(device);
+      return recv_pal_port_enable_all();
+    }
+
+    public void send_pal_port_enable_all(byte device) throws org.apache.thrift.TException
+    {
+      pal_port_enable_all_args args = new pal_port_enable_all_args();
+      args.setDevice(device);
+      sendBase("pal_port_enable_all", args);
+    }
+
+    public int recv_pal_port_enable_all() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_enable_all_result result = new pal_port_enable_all_result();
+      receiveBase(result, "pal_port_enable_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_enable_all 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 boolean pal_port_is_valid(byte device, int dev_port) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_is_valid(device, dev_port);
+      return recv_pal_port_is_valid();
+    }
+
+    public void send_pal_port_is_valid(byte device, int dev_port) throws org.apache.thrift.TException
+    {
+      pal_port_is_valid_args args = new pal_port_is_valid_args();
+      args.setDevice(device);
+      args.setDev_port(dev_port);
+      sendBase("pal_port_is_valid", args);
+    }
+
+    public boolean recv_pal_port_is_valid() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_is_valid_result result = new pal_port_is_valid_result();
+      receiveBase(result, "pal_port_is_valid");
+      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_is_valid 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 int pal_port_an_set_all(byte device, pal_autoneg_policy_t an) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_an_set_all(device, an);
+      return recv_pal_port_an_set_all();
+    }
+
+    public void send_pal_port_an_set_all(byte device, pal_autoneg_policy_t an) throws org.apache.thrift.TException
+    {
+      pal_port_an_set_all_args args = new pal_port_an_set_all_args();
+      args.setDevice(device);
+      args.setAn(an);
+      sendBase("pal_port_an_set_all", args);
+    }
+
+    public int recv_pal_port_an_set_all() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_an_set_all_result result = new pal_port_an_set_all_result();
+      receiveBase(result, "pal_port_an_set_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_an_set_all failed: unknown result");
+    }
+
+    public int pal_port_loopback_mode_set(byte dev, int dev_port, pal_loopback_mod_t mode) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_loopback_mode_set(dev, dev_port, mode);
+      return recv_pal_port_loopback_mode_set();
+    }
+
+    public void send_pal_port_loopback_mode_set(byte dev, int dev_port, pal_loopback_mod_t mode) throws org.apache.thrift.TException
+    {
+      pal_port_loopback_mode_set_args args = new pal_port_loopback_mode_set_args();
+      args.setDev(dev);
+      args.setDev_port(dev_port);
+      args.setMode(mode);
+      sendBase("pal_port_loopback_mode_set", args);
+    }
+
+    public int recv_pal_port_loopback_mode_set() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_loopback_mode_set_result result = new pal_port_loopback_mode_set_result();
+      receiveBase(result, "pal_port_loopback_mode_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_loopback_mode_set failed: unknown result");
+    }
+
+    public int pal_port_front_panel_port_to_dev_port_get(byte dev, int front_port, int front_chnl) throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      send_pal_port_front_panel_port_to_dev_port_get(dev, front_port, front_chnl);
+      return recv_pal_port_front_panel_port_to_dev_port_get();
+    }
+
+    public void send_pal_port_front_panel_port_to_dev_port_get(byte dev, int front_port, int front_chnl) throws org.apache.thrift.TException
+    {
+      pal_port_front_panel_port_to_dev_port_get_args args = new pal_port_front_panel_port_to_dev_port_get_args();
+      args.setDev(dev);
+      args.setFront_port(front_port);
+      args.setFront_chnl(front_chnl);
+      sendBase("pal_port_front_panel_port_to_dev_port_get", args);
+    }
+
+    public int recv_pal_port_front_panel_port_to_dev_port_get() throws InvalidPalOperation, org.apache.thrift.TException
+    {
+      pal_port_front_panel_port_to_dev_port_get_result result = new pal_port_front_panel_port_to_dev_port_get_result();
+      receiveBase(result, "pal_port_front_panel_port_to_dev_port_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_front_panel_port_to_dev_port_get 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<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<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<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 Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_add();
+      }
+    }
+
+    public void pal_port_add_all(byte device, pal_port_speed_t ps, pal_fec_type_t fec, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_add_all_call method_call = new pal_port_add_all_call(device, ps, fec, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_add_all_call extends org.apache.thrift.async.TAsyncMethodCall<Integer> {
+      private byte device;
+      private pal_port_speed_t ps;
+      private pal_fec_type_t fec;
+      public pal_port_add_all_call(byte device, pal_port_speed_t ps, pal_fec_type_t fec, org.apache.thrift.async.AsyncMethodCallback<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.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_all", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_add_all_args args = new pal_port_add_all_args();
+        args.setDevice(device);
+        args.setPs(ps);
+        args.setFec(fec);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_add_all();
+      }
+    }
+
+    public void pal_port_del(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<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<Integer> {
+      private byte device;
+      private int dev_port;
+      public pal_port_del_call(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<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 Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_del();
+      }
+    }
+
+    public void pal_port_del_all(byte device, org.apache.thrift.async.AsyncMethodCallback<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<Integer> {
+      private byte device;
+      public pal_port_del_all_call(byte device, org.apache.thrift.async.AsyncMethodCallback<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 Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_del_all();
+      }
+    }
+
+    public void pal_port_enable(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<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<Integer> {
+      private byte device;
+      private int dev_port;
+      public pal_port_enable_call(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<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 Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_enable();
+      }
+    }
+
+    public void pal_port_enable_all(byte device, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_enable_all_call method_call = new pal_port_enable_all_call(device, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_enable_all_call extends org.apache.thrift.async.TAsyncMethodCall<Integer> {
+      private byte device;
+      public pal_port_enable_all_call(byte device, org.apache.thrift.async.AsyncMethodCallback<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_enable_all", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_enable_all_args args = new pal_port_enable_all_args();
+        args.setDevice(device);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_enable_all();
+      }
+    }
+
+    public void pal_port_dis(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<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<Integer> {
+      private byte device;
+      private int dev_port;
+      public pal_port_dis_call(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<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 Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_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 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_is_valid(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_is_valid_call method_call = new pal_port_is_valid_call(device, dev_port, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_is_valid_call extends org.apache.thrift.async.TAsyncMethodCall<Boolean> {
+      private byte device;
+      private int dev_port;
+      public pal_port_is_valid_call(byte device, int dev_port, org.apache.thrift.async.AsyncMethodCallback<Boolean> 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_is_valid", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_is_valid_args args = new pal_port_is_valid_args();
+        args.setDevice(device);
+        args.setDev_port(dev_port);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Boolean getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_is_valid();
+      }
+    }
+
+    public void pal_port_an_set(byte device, int dev_port, pal_autoneg_policy_t an, org.apache.thrift.async.AsyncMethodCallback<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<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<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 Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_an_set();
+      }
+    }
+
+    public void pal_port_an_set_all(byte device, pal_autoneg_policy_t an, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_an_set_all_call method_call = new pal_port_an_set_all_call(device, an, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_an_set_all_call extends org.apache.thrift.async.TAsyncMethodCall<Integer> {
+      private byte device;
+      private pal_autoneg_policy_t an;
+      public pal_port_an_set_all_call(byte device, pal_autoneg_policy_t an, org.apache.thrift.async.AsyncMethodCallback<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.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_all", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_an_set_all_args args = new pal_port_an_set_all_args();
+        args.setDevice(device);
+        args.setAn(an);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_an_set_all();
+      }
+    }
+
+    public void pal_port_loopback_mode_set(byte dev, int dev_port, pal_loopback_mod_t mode, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_loopback_mode_set_call method_call = new pal_port_loopback_mode_set_call(dev, dev_port, mode, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_loopback_mode_set_call extends org.apache.thrift.async.TAsyncMethodCall<Integer> {
+      private byte dev;
+      private int dev_port;
+      private pal_loopback_mod_t mode;
+      public pal_port_loopback_mode_set_call(byte dev, int dev_port, pal_loopback_mod_t mode, org.apache.thrift.async.AsyncMethodCallback<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.dev = dev;
+        this.dev_port = dev_port;
+        this.mode = mode;
+      }
+
+      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_loopback_mode_set", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_loopback_mode_set_args args = new pal_port_loopback_mode_set_args();
+        args.setDev(dev);
+        args.setDev_port(dev_port);
+        args.setMode(mode);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_loopback_mode_set();
+      }
+    }
+
+    public void pal_port_front_panel_port_to_dev_port_get(byte dev, int front_port, int front_chnl, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      pal_port_front_panel_port_to_dev_port_get_call method_call = new pal_port_front_panel_port_to_dev_port_get_call(dev, front_port, front_chnl, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class pal_port_front_panel_port_to_dev_port_get_call extends org.apache.thrift.async.TAsyncMethodCall<Integer> {
+      private byte dev;
+      private int front_port;
+      private int front_chnl;
+      public pal_port_front_panel_port_to_dev_port_get_call(byte dev, int front_port, int front_chnl, org.apache.thrift.async.AsyncMethodCallback<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.dev = dev;
+        this.front_port = front_port;
+        this.front_chnl = front_chnl;
+      }
+
+      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_front_panel_port_to_dev_port_get", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        pal_port_front_panel_port_to_dev_port_get_args args = new pal_port_front_panel_port_to_dev_port_get_args();
+        args.setDev(dev);
+        args.setFront_port(front_port);
+        args.setFront_chnl(front_chnl);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public Integer getResult() throws InvalidPalOperation, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_pal_port_front_panel_port_to_dev_port_get();
+      }
+    }
+
+  }
+
+  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<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
+    }
+
+    protected Processor(I iface, java.util.Map<String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends Iface> java.util.Map<String,  org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<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_add_all", new pal_port_add_all());
+      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_enable_all", new pal_port_enable_all());
+      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_is_valid", new pal_port_is_valid());
+      processMap.put("pal_port_an_set", new pal_port_an_set());
+      processMap.put("pal_port_an_set_all", new pal_port_an_set_all());
+      processMap.put("pal_port_loopback_mode_set", new pal_port_loopback_mode_set());
+      processMap.put("pal_port_front_panel_port_to_dev_port_get", new pal_port_front_panel_port_to_dev_port_get());
+      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;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        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_add_all<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_add_all_args> {
+      public pal_port_add_all() {
+        super("pal_port_add_all");
+      }
+
+      public pal_port_add_all_args getEmptyArgsInstance() {
+        return new pal_port_add_all_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        return false;
+      }
+
+      public pal_port_add_all_result getResult(I iface, pal_port_add_all_args args) throws org.apache.thrift.TException {
+        pal_port_add_all_result result = new pal_port_add_all_result();
+        try {
+          result.success = iface.pal_port_add_all(args.device, 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;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        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;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        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;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        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_enable_all<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_enable_all_args> {
+      public pal_port_enable_all() {
+        super("pal_port_enable_all");
+      }
+
+      public pal_port_enable_all_args getEmptyArgsInstance() {
+        return new pal_port_enable_all_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        return false;
+      }
+
+      public pal_port_enable_all_result getResult(I iface, pal_port_enable_all_args args) throws org.apache.thrift.TException {
+        pal_port_enable_all_result result = new pal_port_enable_all_result();
+        try {
+          result.success = iface.pal_port_enable_all(args.device);
+          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;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        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;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        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_is_valid<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_is_valid_args> {
+      public pal_port_is_valid() {
+        super("pal_port_is_valid");
+      }
+
+      public pal_port_is_valid_args getEmptyArgsInstance() {
+        return new pal_port_is_valid_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        return false;
+      }
+
+      public pal_port_is_valid_result getResult(I iface, pal_port_is_valid_args args) throws org.apache.thrift.TException {
+        pal_port_is_valid_result result = new pal_port_is_valid_result();
+        try {
+          result.success = iface.pal_port_is_valid(args.device, args.dev_port);
+          result.setSuccessIsSet(true);
+        } 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;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        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 pal_port_an_set_all<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_an_set_all_args> {
+      public pal_port_an_set_all() {
+        super("pal_port_an_set_all");
+      }
+
+      public pal_port_an_set_all_args getEmptyArgsInstance() {
+        return new pal_port_an_set_all_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        return false;
+      }
+
+      public pal_port_an_set_all_result getResult(I iface, pal_port_an_set_all_args args) throws org.apache.thrift.TException {
+        pal_port_an_set_all_result result = new pal_port_an_set_all_result();
+        try {
+          result.success = iface.pal_port_an_set_all(args.device, args.an);
+          result.setSuccessIsSet(true);
+        } catch (InvalidPalOperation ouch) {
+          result.ouch = ouch;
+        }
+        return result;
+      }
+    }
+
+    public static class pal_port_loopback_mode_set<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_loopback_mode_set_args> {
+      public pal_port_loopback_mode_set() {
+        super("pal_port_loopback_mode_set");
+      }
+
+      public pal_port_loopback_mode_set_args getEmptyArgsInstance() {
+        return new pal_port_loopback_mode_set_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        return false;
+      }
+
+      public pal_port_loopback_mode_set_result getResult(I iface, pal_port_loopback_mode_set_args args) throws org.apache.thrift.TException {
+        pal_port_loopback_mode_set_result result = new pal_port_loopback_mode_set_result();
+        try {
+          result.success = iface.pal_port_loopback_mode_set(args.dev, args.dev_port, args.mode);
+          result.setSuccessIsSet(true);
+        } catch (InvalidPalOperation ouch) {
+          result.ouch = ouch;
+        }
+        return result;
+      }
+    }
+
+    public static class pal_port_front_panel_port_to_dev_port_get<I extends Iface> extends org.apache.thrift.ProcessFunction<I, pal_port_front_panel_port_to_dev_port_get_args> {
+      public pal_port_front_panel_port_to_dev_port_get() {
+        super("pal_port_front_panel_port_to_dev_port_get");
+      }
+
+      public pal_port_front_panel_port_to_dev_port_get_args getEmptyArgsInstance() {
+        return new pal_port_front_panel_port_to_dev_port_get_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      @Override
+      protected boolean handleRuntimeExceptions() {
+        return false;
+      }
+
+      public pal_port_front_panel_port_to_dev_port_get_result getResult(I iface, pal_port_front_panel_port_to_dev_port_get_args args) throws org.apache.thrift.TException {
+        pal_port_front_panel_port_to_dev_port_get_result result = new pal_port_front_panel_port_to_dev_port_get_result();
+        try {
+          result.success = iface.pal_port_front_panel_port_to_dev_port_get(args.dev, args.front_port, args.front_chnl);
+          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<String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
+    }
+
+    protected AsyncProcessor(I iface, java.util.Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
+      super(iface, getProcessMap(processMap));
+    }
+
+    private static <I extends AsyncIface> java.util.Map<String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<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_add_all", new pal_port_add_all());
+      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_enable_all", new pal_port_enable_all());
+      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_is_valid", new pal_port_is_valid());
+      processMap.put("pal_port_an_set", new pal_port_an_set());
+      processMap.put("pal_port_an_set_all", new pal_port_an_set_all());
+      processMap.put("pal_port_loopback_mode_set", new pal_port_loopback_mode_set());
+      processMap.put("pal_port_front_panel_port_to_dev_port_get", new pal_port_front_panel_port_to_dev_port_get());
+      return processMap;
+    }
+
+    public static class pal_port_add<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_add_args, 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<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<Integer>() {
+          public void onComplete(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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(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 (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<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_add_all<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_add_all_args, Integer> {
+      public pal_port_add_all() {
+        super("pal_port_add_all");
+      }
+
+      public pal_port_add_all_args getEmptyArgsInstance() {
+        return new pal_port_add_all_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<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<Integer>() {
+          public void onComplete(Integer o) {
+            pal_port_add_all_result result = new pal_port_add_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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_add_all_result result = new pal_port_add_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 (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_all_args args, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_add_all(args.device, args.ps, args.fec,resultHandler);
+      }
+    }
+
+    public static class pal_port_del<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_del_args, 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<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<Integer>() {
+          public void onComplete(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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(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 (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<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, 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<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<Integer>() {
+          public void onComplete(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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(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 (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<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, 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<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<Integer>() {
+          public void onComplete(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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(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 (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<Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_enable(args.device, args.dev_port,resultHandler);
+      }
+    }
+
+    public static class pal_port_enable_all<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_enable_all_args, Integer> {
+      public pal_port_enable_all() {
+        super("pal_port_enable_all");
+      }
+
+      public pal_port_enable_all_args getEmptyArgsInstance() {
+        return new pal_port_enable_all_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<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<Integer>() {
+          public void onComplete(Integer o) {
+            pal_port_enable_all_result result = new pal_port_enable_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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_enable_all_result result = new pal_port_enable_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 (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_all_args args, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_enable_all(args.device,resultHandler);
+      }
+    }
+
+    public static class pal_port_dis<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_dis_args, 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<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<Integer>() {
+          public void onComplete(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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(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 (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<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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(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 (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_is_valid<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_is_valid_args, Boolean> {
+      public pal_port_is_valid() {
+        super("pal_port_is_valid");
+      }
+
+      public pal_port_is_valid_args getEmptyArgsInstance() {
+        return new pal_port_is_valid_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<Boolean> 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<Boolean>() {
+          public void onComplete(Boolean o) {
+            pal_port_is_valid_result result = new pal_port_is_valid_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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_is_valid_result result = new pal_port_is_valid_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 (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_is_valid_args args, org.apache.thrift.async.AsyncMethodCallback<Boolean> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_is_valid(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, 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<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<Integer>() {
+          public void onComplete(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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(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 (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<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_an_set_all<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_an_set_all_args, Integer> {
+      public pal_port_an_set_all() {
+        super("pal_port_an_set_all");
+      }
+
+      public pal_port_an_set_all_args getEmptyArgsInstance() {
+        return new pal_port_an_set_all_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<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<Integer>() {
+          public void onComplete(Integer o) {
+            pal_port_an_set_all_result result = new pal_port_an_set_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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_an_set_all_result result = new pal_port_an_set_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 (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_all_args args, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_an_set_all(args.device, args.an,resultHandler);
+      }
+    }
+
+    public static class pal_port_loopback_mode_set<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_loopback_mode_set_args, Integer> {
+      public pal_port_loopback_mode_set() {
+        super("pal_port_loopback_mode_set");
+      }
+
+      public pal_port_loopback_mode_set_args getEmptyArgsInstance() {
+        return new pal_port_loopback_mode_set_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<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<Integer>() {
+          public void onComplete(Integer o) {
+            pal_port_loopback_mode_set_result result = new pal_port_loopback_mode_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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_loopback_mode_set_result result = new pal_port_loopback_mode_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 (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_loopback_mode_set_args args, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_loopback_mode_set(args.dev, args.dev_port, args.mode,resultHandler);
+      }
+    }
+
+    public static class pal_port_front_panel_port_to_dev_port_get<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, pal_port_front_panel_port_to_dev_port_get_args, Integer> {
+      public pal_port_front_panel_port_to_dev_port_get() {
+        super("pal_port_front_panel_port_to_dev_port_get");
+      }
+
+      public pal_port_front_panel_port_to_dev_port_get_args getEmptyArgsInstance() {
+        return new pal_port_front_panel_port_to_dev_port_get_args();
+      }
+
+      public org.apache.thrift.async.AsyncMethodCallback<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<Integer>() {
+          public void onComplete(Integer o) {
+            pal_port_front_panel_port_to_dev_port_get_result result = new pal_port_front_panel_port_to_dev_port_get_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 (Exception e) {
+              _LOGGER.error("Exception writing to internal frame buffer", e);
+              onError(e);
+            }
+          }
+          public void onError(Exception e) {
+            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
+            org.apache.thrift.TSerializable msg;
+            pal_port_front_panel_port_to_dev_port_get_result result = new pal_port_front_panel_port_to_dev_port_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 (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_front_panel_port_to_dev_port_get_args args, org.apache.thrift.async.AsyncMethodCallback<Integer> resultHandler) throws org.apache.thrift.TException {
+        iface.pal_port_front_panel_port_to_dev_port_get(args.dev, args.front_port, args.front_chnl,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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((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 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 IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      case PS:
+        return isSetPs();
+      case FEC:
+        return isSetFec();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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_add_all_args implements org.apache.thrift.TBase<pal_port_add_all_args, pal_port_add_all_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_add_all_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_add_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.protocol.TField PS_FIELD_DESC = new org.apache.thrift.protocol.TField("ps", org.apache.thrift.protocol.TType.I32, (short)2);
+    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)3);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_add_all_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_add_all_argsTupleSchemeFactory();
+
+    public byte device; // 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"),
+      /**
+       * 
+       * @see pal_port_speed_t
+       */
+      PS((short)2, "ps"),
+      /**
+       * 
+       * @see pal_fec_type_t
+       */
+      FEC((short)3, "fec");
+
+      private static final java.util.Map<String, _Fields> byName = new java.util.HashMap<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: // PS
+            return PS;
+          case 3: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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")));
+      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_all_args.class, metaDataMap);
+    }
+
+    public pal_port_add_all_args() {
+    }
+
+    public pal_port_add_all_args(
+      byte device,
+      pal_port_speed_t ps,
+      pal_fec_type_t fec)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+      this.ps = ps;
+      this.fec = fec;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_add_all_args(pal_port_add_all_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+      if (other.isSetPs()) {
+        this.ps = other.ps;
+      }
+      if (other.isSetFec()) {
+        this.fec = other.fec;
+      }
+    }
+
+    public pal_port_add_all_args deepCopy() {
+      return new pal_port_add_all_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+      this.ps = null;
+      this.fec = null;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_add_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);
+    }
+
+    /**
+     * 
+     * @see pal_port_speed_t
+     */
+    public pal_port_speed_t getPs() {
+      return this.ps;
+    }
+
+    /**
+     * 
+     * @see pal_port_speed_t
+     */
+    public pal_port_add_all_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_all_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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)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 Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case PS:
+        return getPs();
+
+      case FEC:
+        return getFec();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case PS:
+        return isSetPs();
+      case FEC:
+        return isSetFec();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_add_all_args)
+        return this.equals((pal_port_add_all_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_add_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;
+      }
+
+      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 + ((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_all_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 = 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 = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_add_all_args(");
+      boolean first = true;
+
+      sb.append("device:");
+      sb.append(this.device);
+      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, 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_all_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_add_all_argsStandardScheme getScheme() {
+        return new pal_port_add_all_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_add_all_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_add_all_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_add_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;
+            case 2: // 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 3: // 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_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();
+        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_all_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_add_all_argsTupleScheme getScheme() {
+        return new pal_port_add_all_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_add_all_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_add_all_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_add_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);
+        }
+        if (struct.isSetPs()) {
+          optionals.set(1);
+        }
+        if (struct.isSetFec()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetDevice()) {
+          oprot.writeByte(struct.device);
+        }
+        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_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(3);
+        if (incoming.get(0)) {
+          struct.device = iprot.readByte();
+          struct.setDeviceIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ps = pal_port_speed_t.findByValue(iprot.readI32());
+          struct.setPsIsSet(true);
+        }
+        if (incoming.get(2)) {
+          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_all_result implements org.apache.thrift.TBase<pal_port_add_all_result, pal_port_add_all_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_add_all_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_add_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_add_all_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_add_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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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_all_result.class, metaDataMap);
+    }
+
+    public pal_port_add_all_result() {
+    }
+
+    public pal_port_add_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_add_all_result(pal_port_add_all_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_add_all_result deepCopy() {
+      return new pal_port_add_all_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_add_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_add_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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_add_all_result)
+        return this.equals((pal_port_add_all_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_add_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_add_all_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_add_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, 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_all_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_add_all_resultStandardScheme getScheme() {
+        return new pal_port_add_all_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_add_all_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_add_all_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_add_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_add_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_add_all_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_add_all_resultTupleScheme getScheme() {
+        return new pal_port_add_all_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_add_all_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_add_all_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_add_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_add_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_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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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_enable_all_args implements org.apache.thrift.TBase<pal_port_enable_all_args, pal_port_enable_all_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_enable_all_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_enable_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_enable_all_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_enable_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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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_enable_all_args.class, metaDataMap);
+    }
+
+    public pal_port_enable_all_args() {
+    }
+
+    public pal_port_enable_all_args(
+      byte device)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_enable_all_args(pal_port_enable_all_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+    }
+
+    public pal_port_enable_all_args deepCopy() {
+      return new pal_port_enable_all_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_enable_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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_enable_all_args)
+        return this.equals((pal_port_enable_all_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_enable_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_enable_all_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_enable_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, 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_all_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_enable_all_argsStandardScheme getScheme() {
+        return new pal_port_enable_all_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_enable_all_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_enable_all_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_enable_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_enable_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_enable_all_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_enable_all_argsTupleScheme getScheme() {
+        return new pal_port_enable_all_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_enable_all_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_enable_all_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_enable_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_enable_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_enable_all_result implements org.apache.thrift.TBase<pal_port_enable_all_result, pal_port_enable_all_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_enable_all_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_enable_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_enable_all_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_enable_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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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_all_result.class, metaDataMap);
+    }
+
+    public pal_port_enable_all_result() {
+    }
+
+    public pal_port_enable_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_enable_all_result(pal_port_enable_all_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_enable_all_result deepCopy() {
+      return new pal_port_enable_all_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_enable_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_enable_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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_enable_all_result)
+        return this.equals((pal_port_enable_all_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_enable_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_enable_all_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_enable_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, 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_all_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_enable_all_resultStandardScheme getScheme() {
+        return new pal_port_enable_all_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_enable_all_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_enable_all_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_enable_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_enable_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_enable_all_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_enable_all_resultTupleScheme getScheme() {
+        return new pal_port_enable_all_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_enable_all_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_enable_all_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_enable_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_enable_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_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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final 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, 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 Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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_is_valid_args implements org.apache.thrift.TBase<pal_port_is_valid_args, pal_port_is_valid_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_is_valid_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_is_valid_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_is_valid_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_is_valid_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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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_is_valid_args.class, metaDataMap);
+    }
+
+    public pal_port_is_valid_args() {
+    }
+
+    public pal_port_is_valid_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_is_valid_args(pal_port_is_valid_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+      this.dev_port = other.dev_port;
+    }
+
+    public pal_port_is_valid_args deepCopy() {
+      return new pal_port_is_valid_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_is_valid_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_is_valid_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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_is_valid_args)
+        return this.equals((pal_port_is_valid_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_is_valid_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_is_valid_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_is_valid_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, 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_is_valid_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_is_valid_argsStandardScheme getScheme() {
+        return new pal_port_is_valid_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_is_valid_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_is_valid_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_is_valid_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_is_valid_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_is_valid_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_is_valid_argsTupleScheme getScheme() {
+        return new pal_port_is_valid_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_is_valid_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_is_valid_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_is_valid_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_is_valid_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_is_valid_result implements org.apache.thrift.TBase<pal_port_is_valid_result, pal_port_is_valid_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_is_valid_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_is_valid_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (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_is_valid_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_is_valid_resultTupleSchemeFactory();
+
+    public boolean 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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.BOOL)));
+      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_is_valid_result.class, metaDataMap);
+    }
+
+    public pal_port_is_valid_result() {
+    }
+
+    public pal_port_is_valid_result(
+      boolean success,
+      InvalidPalOperation ouch)
+    {
+      this();
+      this.success = success;
+      setSuccessIsSet(true);
+      this.ouch = ouch;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_is_valid_result(pal_port_is_valid_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_is_valid_result deepCopy() {
+      return new pal_port_is_valid_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = false;
+      this.ouch = null;
+    }
+
+    public boolean isSuccess() {
+      return this.success;
+    }
+
+    public pal_port_is_valid_result setSuccess(boolean 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_is_valid_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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Boolean)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return isSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_is_valid_result)
+        return this.equals((pal_port_is_valid_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_is_valid_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) ? 131071 : 524287);
+
+      hashCode = hashCode * 8191 + ((isSetOuch()) ? 131071 : 524287);
+      if (isSetOuch())
+        hashCode = hashCode * 8191 + ouch.hashCode();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_is_valid_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_is_valid_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, 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_is_valid_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_is_valid_resultStandardScheme getScheme() {
+        return new pal_port_is_valid_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_is_valid_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_is_valid_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_is_valid_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.BOOL) {
+                struct.success = iprot.readBool();
+                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_is_valid_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.isSetSuccess()) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          oprot.writeBool(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_is_valid_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_is_valid_resultTupleScheme getScheme() {
+        return new pal_port_is_valid_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_is_valid_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_is_valid_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_is_valid_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.writeBool(struct.success);
+        }
+        if (struct.isSetOuch()) {
+          struct.ouch.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_is_valid_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.readBool();
+          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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((Integer)value);
+        }
+        break;
+
+      case AN:
+        if (value == null) {
+          unsetAn();
+        } else {
+          setAn((pal_autoneg_policy_t)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      case AN:
+        return getAn();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case DEV_PORT:
+        return isSetDev_port();
+      case AN:
+        return isSetAn();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(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 = 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 = 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 String toString() {
+      StringBuilder sb = new 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, 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();
+    }
+  }
+
+  public static class pal_port_an_set_all_args implements org.apache.thrift.TBase<pal_port_an_set_all_args, pal_port_an_set_all_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_an_set_all_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_an_set_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.protocol.TField AN_FIELD_DESC = new org.apache.thrift.protocol.TField("an", org.apache.thrift.protocol.TType.I32, (short)2);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_an_set_all_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_an_set_all_argsTupleSchemeFactory();
+
+    public byte device; // 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"),
+      /**
+       * 
+       * @see pal_autoneg_policy_t
+       */
+      AN((short)2, "an");
+
+      private static final java.util.Map<String, _Fields> byName = new java.util.HashMap<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: // 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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __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")));
+      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_all_args.class, metaDataMap);
+    }
+
+    public pal_port_an_set_all_args() {
+    }
+
+    public pal_port_an_set_all_args(
+      byte device,
+      pal_autoneg_policy_t an)
+    {
+      this();
+      this.device = device;
+      setDeviceIsSet(true);
+      this.an = an;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_an_set_all_args(pal_port_an_set_all_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.device = other.device;
+      if (other.isSetAn()) {
+        this.an = other.an;
+      }
+    }
+
+    public pal_port_an_set_all_args deepCopy() {
+      return new pal_port_an_set_all_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDeviceIsSet(false);
+      this.device = 0;
+      this.an = null;
+    }
+
+    public byte getDevice() {
+      return this.device;
+    }
+
+    public pal_port_an_set_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);
+    }
+
+    /**
+     * 
+     * @see pal_autoneg_policy_t
+     */
+    public pal_autoneg_policy_t getAn() {
+      return this.an;
+    }
+
+    /**
+     * 
+     * @see pal_autoneg_policy_t
+     */
+    public pal_port_an_set_all_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, Object value) {
+      switch (field) {
+      case DEVICE:
+        if (value == null) {
+          unsetDevice();
+        } else {
+          setDevice((Byte)value);
+        }
+        break;
+
+      case AN:
+        if (value == null) {
+          unsetAn();
+        } else {
+          setAn((pal_autoneg_policy_t)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEVICE:
+        return getDevice();
+
+      case AN:
+        return getAn();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEVICE:
+        return isSetDevice();
+      case AN:
+        return isSetAn();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_an_set_all_args)
+        return this.equals((pal_port_an_set_all_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_an_set_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;
+      }
+
+      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 + ((isSetAn()) ? 131071 : 524287);
+      if (isSetAn())
+        hashCode = hashCode * 8191 + an.getValue();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_an_set_all_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_an_set_all_args(");
+      boolean first = true;
+
+      sb.append("device:");
+      sb.append(this.device);
+      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, 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_all_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_an_set_all_argsStandardScheme getScheme() {
+        return new pal_port_an_set_all_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_an_set_all_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_an_set_all_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_an_set_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;
+            case 2: // 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_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();
+        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_all_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_an_set_all_argsTupleScheme getScheme() {
+        return new pal_port_an_set_all_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_an_set_all_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_an_set_all_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_an_set_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);
+        }
+        if (struct.isSetAn()) {
+          optionals.set(1);
+        }
+        oprot.writeBitSet(optionals, 2);
+        if (struct.isSetDevice()) {
+          oprot.writeByte(struct.device);
+        }
+        if (struct.isSetAn()) {
+          oprot.writeI32(struct.an.getValue());
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_an_set_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(2);
+        if (incoming.get(0)) {
+          struct.device = iprot.readByte();
+          struct.setDeviceIsSet(true);
+        }
+        if (incoming.get(1)) {
+          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_all_result implements org.apache.thrift.TBase<pal_port_an_set_all_result, pal_port_an_set_all_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_an_set_all_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_an_set_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_an_set_all_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_an_set_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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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_all_result.class, metaDataMap);
+    }
+
+    public pal_port_an_set_all_result() {
+    }
+
+    public pal_port_an_set_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_an_set_all_result(pal_port_an_set_all_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_all_result deepCopy() {
+      return new pal_port_an_set_all_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_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_an_set_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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_an_set_all_result)
+        return this.equals((pal_port_an_set_all_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_an_set_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_an_set_all_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_an_set_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, 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_all_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_an_set_all_resultStandardScheme getScheme() {
+        return new pal_port_an_set_all_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_an_set_all_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_an_set_all_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_an_set_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_an_set_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_an_set_all_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_an_set_all_resultTupleScheme getScheme() {
+        return new pal_port_an_set_all_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_an_set_all_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_an_set_all_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_an_set_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_an_set_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_loopback_mode_set_args implements org.apache.thrift.TBase<pal_port_loopback_mode_set_args, pal_port_loopback_mode_set_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_loopback_mode_set_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_loopback_mode_set_args");
+
+    private static final org.apache.thrift.protocol.TField DEV_FIELD_DESC = new org.apache.thrift.protocol.TField("dev", 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 MODE_FIELD_DESC = new org.apache.thrift.protocol.TField("mode", org.apache.thrift.protocol.TType.I32, (short)3);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_loopback_mode_set_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_loopback_mode_set_argsTupleSchemeFactory();
+
+    public byte dev; // required
+    public int dev_port; // required
+    /**
+     * 
+     * @see pal_loopback_mod_t
+     */
+    public pal_loopback_mod_t mode; // 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 {
+      DEV((short)1, "dev"),
+      DEV_PORT((short)2, "dev_port"),
+      /**
+       * 
+       * @see pal_loopback_mod_t
+       */
+      MODE((short)3, "mode");
+
+      private static final java.util.Map<String, _Fields> byName = new java.util.HashMap<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: // DEV
+            return DEV;
+          case 2: // DEV_PORT
+            return DEV_PORT;
+          case 3: // MODE
+            return MODE;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __DEV_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.DEV, new org.apache.thrift.meta_data.FieldMetaData("dev", 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.MODE, new org.apache.thrift.meta_data.FieldMetaData("mode", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, pal_loopback_mod_t.class)));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_loopback_mode_set_args.class, metaDataMap);
+    }
+
+    public pal_port_loopback_mode_set_args() {
+    }
+
+    public pal_port_loopback_mode_set_args(
+      byte dev,
+      int dev_port,
+      pal_loopback_mod_t mode)
+    {
+      this();
+      this.dev = dev;
+      setDevIsSet(true);
+      this.dev_port = dev_port;
+      setDev_portIsSet(true);
+      this.mode = mode;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_loopback_mode_set_args(pal_port_loopback_mode_set_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.dev = other.dev;
+      this.dev_port = other.dev_port;
+      if (other.isSetMode()) {
+        this.mode = other.mode;
+      }
+    }
+
+    public pal_port_loopback_mode_set_args deepCopy() {
+      return new pal_port_loopback_mode_set_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDevIsSet(false);
+      this.dev = 0;
+      setDev_portIsSet(false);
+      this.dev_port = 0;
+      this.mode = null;
+    }
+
+    public byte getDev() {
+      return this.dev;
+    }
+
+    public pal_port_loopback_mode_set_args setDev(byte dev) {
+      this.dev = dev;
+      setDevIsSet(true);
+      return this;
+    }
+
+    public void unsetDev() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEV_ISSET_ID);
+    }
+
+    /** Returns true if field dev is set (has been assigned a value) and false otherwise */
+    public boolean isSetDev() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEV_ISSET_ID);
+    }
+
+    public void setDevIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEV_ISSET_ID, value);
+    }
+
+    public int getDev_port() {
+      return this.dev_port;
+    }
+
+    public pal_port_loopback_mode_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_loopback_mod_t
+     */
+    public pal_loopback_mod_t getMode() {
+      return this.mode;
+    }
+
+    /**
+     * 
+     * @see pal_loopback_mod_t
+     */
+    public pal_port_loopback_mode_set_args setMode(pal_loopback_mod_t mode) {
+      this.mode = mode;
+      return this;
+    }
+
+    public void unsetMode() {
+      this.mode = null;
+    }
+
+    /** Returns true if field mode is set (has been assigned a value) and false otherwise */
+    public boolean isSetMode() {
+      return this.mode != null;
+    }
+
+    public void setModeIsSet(boolean value) {
+      if (!value) {
+        this.mode = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case DEV:
+        if (value == null) {
+          unsetDev();
+        } else {
+          setDev((Byte)value);
+        }
+        break;
+
+      case DEV_PORT:
+        if (value == null) {
+          unsetDev_port();
+        } else {
+          setDev_port((Integer)value);
+        }
+        break;
+
+      case MODE:
+        if (value == null) {
+          unsetMode();
+        } else {
+          setMode((pal_loopback_mod_t)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEV:
+        return getDev();
+
+      case DEV_PORT:
+        return getDev_port();
+
+      case MODE:
+        return getMode();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEV:
+        return isSetDev();
+      case DEV_PORT:
+        return isSetDev_port();
+      case MODE:
+        return isSetMode();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_loopback_mode_set_args)
+        return this.equals((pal_port_loopback_mode_set_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_loopback_mode_set_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_dev = true;
+      boolean that_present_dev = true;
+      if (this_present_dev || that_present_dev) {
+        if (!(this_present_dev && that_present_dev))
+          return false;
+        if (this.dev != that.dev)
+          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_mode = true && this.isSetMode();
+      boolean that_present_mode = true && that.isSetMode();
+      if (this_present_mode || that_present_mode) {
+        if (!(this_present_mode && that_present_mode))
+          return false;
+        if (!this.mode.equals(that.mode))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + (int) (dev);
+
+      hashCode = hashCode * 8191 + dev_port;
+
+      hashCode = hashCode * 8191 + ((isSetMode()) ? 131071 : 524287);
+      if (isSetMode())
+        hashCode = hashCode * 8191 + mode.getValue();
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_loopback_mode_set_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetDev()).compareTo(other.isSetDev());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDev()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dev, other.dev);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = 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 = Boolean.valueOf(isSetMode()).compareTo(other.isSetMode());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetMode()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.mode, other.mode);
+        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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_loopback_mode_set_args(");
+      boolean first = true;
+
+      sb.append("dev:");
+      sb.append(this.dev);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("dev_port:");
+      sb.append(this.dev_port);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("mode:");
+      if (this.mode == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.mode);
+      }
+      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, 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_loopback_mode_set_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_loopback_mode_set_argsStandardScheme getScheme() {
+        return new pal_port_loopback_mode_set_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_loopback_mode_set_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_loopback_mode_set_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_loopback_mode_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: // DEV
+              if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
+                struct.dev = iprot.readByte();
+                struct.setDevIsSet(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: // MODE
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.mode = pal_loopback_mod_t.findByValue(iprot.readI32());
+                struct.setModeIsSet(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_loopback_mode_set_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(DEV_FIELD_DESC);
+        oprot.writeByte(struct.dev);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(DEV_PORT_FIELD_DESC);
+        oprot.writeI32(struct.dev_port);
+        oprot.writeFieldEnd();
+        if (struct.mode != null) {
+          oprot.writeFieldBegin(MODE_FIELD_DESC);
+          oprot.writeI32(struct.mode.getValue());
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_loopback_mode_set_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_loopback_mode_set_argsTupleScheme getScheme() {
+        return new pal_port_loopback_mode_set_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_loopback_mode_set_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_loopback_mode_set_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_loopback_mode_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.isSetDev()) {
+          optionals.set(0);
+        }
+        if (struct.isSetDev_port()) {
+          optionals.set(1);
+        }
+        if (struct.isSetMode()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetDev()) {
+          oprot.writeByte(struct.dev);
+        }
+        if (struct.isSetDev_port()) {
+          oprot.writeI32(struct.dev_port);
+        }
+        if (struct.isSetMode()) {
+          oprot.writeI32(struct.mode.getValue());
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_loopback_mode_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.dev = iprot.readByte();
+          struct.setDevIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.dev_port = iprot.readI32();
+          struct.setDev_portIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.mode = pal_loopback_mod_t.findByValue(iprot.readI32());
+          struct.setModeIsSet(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_loopback_mode_set_result implements org.apache.thrift.TBase<pal_port_loopback_mode_set_result, pal_port_loopback_mode_set_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_loopback_mode_set_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_loopback_mode_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_loopback_mode_set_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_loopback_mode_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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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_loopback_mode_set_result.class, metaDataMap);
+    }
+
+    public pal_port_loopback_mode_set_result() {
+    }
+
+    public pal_port_loopback_mode_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_loopback_mode_set_result(pal_port_loopback_mode_set_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_loopback_mode_set_result deepCopy() {
+      return new pal_port_loopback_mode_set_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_loopback_mode_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_loopback_mode_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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_loopback_mode_set_result)
+        return this.equals((pal_port_loopback_mode_set_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_loopback_mode_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_loopback_mode_set_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_loopback_mode_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, 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_loopback_mode_set_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_loopback_mode_set_resultStandardScheme getScheme() {
+        return new pal_port_loopback_mode_set_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_loopback_mode_set_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_loopback_mode_set_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_loopback_mode_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_loopback_mode_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_loopback_mode_set_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_loopback_mode_set_resultTupleScheme getScheme() {
+        return new pal_port_loopback_mode_set_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_loopback_mode_set_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_loopback_mode_set_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_loopback_mode_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_loopback_mode_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();
+    }
+  }
+
+  public static class pal_port_front_panel_port_to_dev_port_get_args implements org.apache.thrift.TBase<pal_port_front_panel_port_to_dev_port_get_args, pal_port_front_panel_port_to_dev_port_get_args._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_front_panel_port_to_dev_port_get_args>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_front_panel_port_to_dev_port_get_args");
+
+    private static final org.apache.thrift.protocol.TField DEV_FIELD_DESC = new org.apache.thrift.protocol.TField("dev", org.apache.thrift.protocol.TType.BYTE, (short)1);
+    private static final org.apache.thrift.protocol.TField FRONT_PORT_FIELD_DESC = new org.apache.thrift.protocol.TField("front_port", org.apache.thrift.protocol.TType.I32, (short)2);
+    private static final org.apache.thrift.protocol.TField FRONT_CHNL_FIELD_DESC = new org.apache.thrift.protocol.TField("front_chnl", org.apache.thrift.protocol.TType.I32, (short)3);
+
+    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new pal_port_front_panel_port_to_dev_port_get_argsStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_front_panel_port_to_dev_port_get_argsTupleSchemeFactory();
+
+    public byte dev; // required
+    public int front_port; // required
+    public int front_chnl; // 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 {
+      DEV((short)1, "dev"),
+      FRONT_PORT((short)2, "front_port"),
+      FRONT_CHNL((short)3, "front_chnl");
+
+      private static final java.util.Map<String, _Fields> byName = new java.util.HashMap<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: // DEV
+            return DEV;
+          case 2: // FRONT_PORT
+            return FRONT_PORT;
+          case 3: // FRONT_CHNL
+            return FRONT_CHNL;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __DEV_ISSET_ID = 0;
+    private static final int __FRONT_PORT_ISSET_ID = 1;
+    private static final int __FRONT_CHNL_ISSET_ID = 2;
+    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.DEV, new org.apache.thrift.meta_data.FieldMetaData("dev", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BYTE          , "pal_device_t")));
+      tmpMap.put(_Fields.FRONT_PORT, new org.apache.thrift.meta_data.FieldMetaData("front_port", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "pal_front_port_t")));
+      tmpMap.put(_Fields.FRONT_CHNL, new org.apache.thrift.meta_data.FieldMetaData("front_chnl", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32          , "pal_front_chnl_t")));
+      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(pal_port_front_panel_port_to_dev_port_get_args.class, metaDataMap);
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_args() {
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_args(
+      byte dev,
+      int front_port,
+      int front_chnl)
+    {
+      this();
+      this.dev = dev;
+      setDevIsSet(true);
+      this.front_port = front_port;
+      setFront_portIsSet(true);
+      this.front_chnl = front_chnl;
+      setFront_chnlIsSet(true);
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public pal_port_front_panel_port_to_dev_port_get_args(pal_port_front_panel_port_to_dev_port_get_args other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.dev = other.dev;
+      this.front_port = other.front_port;
+      this.front_chnl = other.front_chnl;
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_args deepCopy() {
+      return new pal_port_front_panel_port_to_dev_port_get_args(this);
+    }
+
+    @Override
+    public void clear() {
+      setDevIsSet(false);
+      this.dev = 0;
+      setFront_portIsSet(false);
+      this.front_port = 0;
+      setFront_chnlIsSet(false);
+      this.front_chnl = 0;
+    }
+
+    public byte getDev() {
+      return this.dev;
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_args setDev(byte dev) {
+      this.dev = dev;
+      setDevIsSet(true);
+      return this;
+    }
+
+    public void unsetDev() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __DEV_ISSET_ID);
+    }
+
+    /** Returns true if field dev is set (has been assigned a value) and false otherwise */
+    public boolean isSetDev() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __DEV_ISSET_ID);
+    }
+
+    public void setDevIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __DEV_ISSET_ID, value);
+    }
+
+    public int getFront_port() {
+      return this.front_port;
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_args setFront_port(int front_port) {
+      this.front_port = front_port;
+      setFront_portIsSet(true);
+      return this;
+    }
+
+    public void unsetFront_port() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __FRONT_PORT_ISSET_ID);
+    }
+
+    /** Returns true if field front_port is set (has been assigned a value) and false otherwise */
+    public boolean isSetFront_port() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __FRONT_PORT_ISSET_ID);
+    }
+
+    public void setFront_portIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __FRONT_PORT_ISSET_ID, value);
+    }
+
+    public int getFront_chnl() {
+      return this.front_chnl;
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_args setFront_chnl(int front_chnl) {
+      this.front_chnl = front_chnl;
+      setFront_chnlIsSet(true);
+      return this;
+    }
+
+    public void unsetFront_chnl() {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __FRONT_CHNL_ISSET_ID);
+    }
+
+    /** Returns true if field front_chnl is set (has been assigned a value) and false otherwise */
+    public boolean isSetFront_chnl() {
+      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __FRONT_CHNL_ISSET_ID);
+    }
+
+    public void setFront_chnlIsSet(boolean value) {
+      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __FRONT_CHNL_ISSET_ID, value);
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case DEV:
+        if (value == null) {
+          unsetDev();
+        } else {
+          setDev((Byte)value);
+        }
+        break;
+
+      case FRONT_PORT:
+        if (value == null) {
+          unsetFront_port();
+        } else {
+          setFront_port((Integer)value);
+        }
+        break;
+
+      case FRONT_CHNL:
+        if (value == null) {
+          unsetFront_chnl();
+        } else {
+          setFront_chnl((Integer)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case DEV:
+        return getDev();
+
+      case FRONT_PORT:
+        return getFront_port();
+
+      case FRONT_CHNL:
+        return getFront_chnl();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case DEV:
+        return isSetDev();
+      case FRONT_PORT:
+        return isSetFront_port();
+      case FRONT_CHNL:
+        return isSetFront_chnl();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_front_panel_port_to_dev_port_get_args)
+        return this.equals((pal_port_front_panel_port_to_dev_port_get_args)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_front_panel_port_to_dev_port_get_args that) {
+      if (that == null)
+        return false;
+      if (this == that)
+        return true;
+
+      boolean this_present_dev = true;
+      boolean that_present_dev = true;
+      if (this_present_dev || that_present_dev) {
+        if (!(this_present_dev && that_present_dev))
+          return false;
+        if (this.dev != that.dev)
+          return false;
+      }
+
+      boolean this_present_front_port = true;
+      boolean that_present_front_port = true;
+      if (this_present_front_port || that_present_front_port) {
+        if (!(this_present_front_port && that_present_front_port))
+          return false;
+        if (this.front_port != that.front_port)
+          return false;
+      }
+
+      boolean this_present_front_chnl = true;
+      boolean that_present_front_chnl = true;
+      if (this_present_front_chnl || that_present_front_chnl) {
+        if (!(this_present_front_chnl && that_present_front_chnl))
+          return false;
+        if (this.front_chnl != that.front_chnl)
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      int hashCode = 1;
+
+      hashCode = hashCode * 8191 + (int) (dev);
+
+      hashCode = hashCode * 8191 + front_port;
+
+      hashCode = hashCode * 8191 + front_chnl;
+
+      return hashCode;
+    }
+
+    @Override
+    public int compareTo(pal_port_front_panel_port_to_dev_port_get_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = Boolean.valueOf(isSetDev()).compareTo(other.isSetDev());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetDev()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dev, other.dev);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetFront_port()).compareTo(other.isSetFront_port());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetFront_port()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.front_port, other.front_port);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetFront_chnl()).compareTo(other.isSetFront_chnl());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetFront_chnl()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.front_chnl, other.front_chnl);
+        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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_front_panel_port_to_dev_port_get_args(");
+      boolean first = true;
+
+      sb.append("dev:");
+      sb.append(this.dev);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("front_port:");
+      sb.append(this.front_port);
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("front_chnl:");
+      sb.append(this.front_chnl);
+      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, 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_front_panel_port_to_dev_port_get_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_front_panel_port_to_dev_port_get_argsStandardScheme getScheme() {
+        return new pal_port_front_panel_port_to_dev_port_get_argsStandardScheme();
+      }
+    }
+
+    private static class pal_port_front_panel_port_to_dev_port_get_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_front_panel_port_to_dev_port_get_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_front_panel_port_to_dev_port_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: // DEV
+              if (schemeField.type == org.apache.thrift.protocol.TType.BYTE) {
+                struct.dev = iprot.readByte();
+                struct.setDevIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // FRONT_PORT
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.front_port = iprot.readI32();
+                struct.setFront_portIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // FRONT_CHNL
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.front_chnl = iprot.readI32();
+                struct.setFront_chnlIsSet(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_front_panel_port_to_dev_port_get_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        oprot.writeFieldBegin(DEV_FIELD_DESC);
+        oprot.writeByte(struct.dev);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(FRONT_PORT_FIELD_DESC);
+        oprot.writeI32(struct.front_port);
+        oprot.writeFieldEnd();
+        oprot.writeFieldBegin(FRONT_CHNL_FIELD_DESC);
+        oprot.writeI32(struct.front_chnl);
+        oprot.writeFieldEnd();
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class pal_port_front_panel_port_to_dev_port_get_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_front_panel_port_to_dev_port_get_argsTupleScheme getScheme() {
+        return new pal_port_front_panel_port_to_dev_port_get_argsTupleScheme();
+      }
+    }
+
+    private static class pal_port_front_panel_port_to_dev_port_get_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_front_panel_port_to_dev_port_get_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_front_panel_port_to_dev_port_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.isSetDev()) {
+          optionals.set(0);
+        }
+        if (struct.isSetFront_port()) {
+          optionals.set(1);
+        }
+        if (struct.isSetFront_chnl()) {
+          optionals.set(2);
+        }
+        oprot.writeBitSet(optionals, 3);
+        if (struct.isSetDev()) {
+          oprot.writeByte(struct.dev);
+        }
+        if (struct.isSetFront_port()) {
+          oprot.writeI32(struct.front_port);
+        }
+        if (struct.isSetFront_chnl()) {
+          oprot.writeI32(struct.front_chnl);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_front_panel_port_to_dev_port_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(3);
+        if (incoming.get(0)) {
+          struct.dev = iprot.readByte();
+          struct.setDevIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.front_port = iprot.readI32();
+          struct.setFront_portIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.front_chnl = iprot.readI32();
+          struct.setFront_chnlIsSet(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_front_panel_port_to_dev_port_get_result implements org.apache.thrift.TBase<pal_port_front_panel_port_to_dev_port_get_result, pal_port_front_panel_port_to_dev_port_get_result._Fields>, java.io.Serializable, Cloneable, Comparable<pal_port_front_panel_port_to_dev_port_get_result>   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("pal_port_front_panel_port_to_dev_port_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_front_panel_port_to_dev_port_get_resultStandardSchemeFactory();
+    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new pal_port_front_panel_port_to_dev_port_get_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<String, _Fields> byName = new java.util.HashMap<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 IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    private static final int __SUCCESS_ISSET_ID = 0;
+    private 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_dev_port_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_front_panel_port_to_dev_port_get_result.class, metaDataMap);
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_result() {
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_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_front_panel_port_to_dev_port_get_result(pal_port_front_panel_port_to_dev_port_get_result other) {
+      __isset_bitfield = other.__isset_bitfield;
+      this.success = other.success;
+      if (other.isSetOuch()) {
+        this.ouch = new InvalidPalOperation(other.ouch);
+      }
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_result deepCopy() {
+      return new pal_port_front_panel_port_to_dev_port_get_result(this);
+    }
+
+    @Override
+    public void clear() {
+      setSuccessIsSet(false);
+      this.success = 0;
+      this.ouch = null;
+    }
+
+    public int getSuccess() {
+      return this.success;
+    }
+
+    public pal_port_front_panel_port_to_dev_port_get_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_front_panel_port_to_dev_port_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, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((Integer)value);
+        }
+        break;
+
+      case OUCH:
+        if (value == null) {
+          unsetOuch();
+        } else {
+          setOuch((InvalidPalOperation)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case OUCH:
+        return getOuch();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case OUCH:
+        return isSetOuch();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof pal_port_front_panel_port_to_dev_port_get_result)
+        return this.equals((pal_port_front_panel_port_to_dev_port_get_result)that);
+      return false;
+    }
+
+    public boolean equals(pal_port_front_panel_port_to_dev_port_get_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_front_panel_port_to_dev_port_get_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+
+      lastComparison = 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 = 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 String toString() {
+      StringBuilder sb = new StringBuilder("pal_port_front_panel_port_to_dev_port_get_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, 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_front_panel_port_to_dev_port_get_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_front_panel_port_to_dev_port_get_resultStandardScheme getScheme() {
+        return new pal_port_front_panel_port_to_dev_port_get_resultStandardScheme();
+      }
+    }
+
+    private static class pal_port_front_panel_port_to_dev_port_get_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<pal_port_front_panel_port_to_dev_port_get_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, pal_port_front_panel_port_to_dev_port_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 = 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_front_panel_port_to_dev_port_get_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_front_panel_port_to_dev_port_get_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
+      public pal_port_front_panel_port_to_dev_port_get_resultTupleScheme getScheme() {
+        return new pal_port_front_panel_port_to_dev_port_get_resultTupleScheme();
+      }
+    }
+
+    private static class pal_port_front_panel_port_to_dev_port_get_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<pal_port_front_panel_port_to_dev_port_get_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, pal_port_front_panel_port_to_dev_port_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);
+        }
+        if (struct.isSetOuch()) {
+          struct.ouch.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, pal_port_front_panel_port_to_dev_port_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 = 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-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_autoneg_policy_t.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_autoneg_policy_t.java
new file mode 100644
index 0000000..fc96151
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_autoneg_policy_t.java
@@ -0,0 +1,44 @@
+package org.onosproject.drivers.barefoot.pro.pal;
+
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+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-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_fec_type_t.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_fec_type_t.java
new file mode 100644
index 0000000..0c87578
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_fec_type_t.java
@@ -0,0 +1,44 @@
+package org.onosproject.drivers.barefoot.pro.pal;
+
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+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-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_loopback_mod_t.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_loopback_mod_t.java
new file mode 100644
index 0000000..0f23204
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_loopback_mod_t.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2018-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.pro.pal;
+
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+public enum pal_loopback_mod_t implements org.apache.thrift.TEnum {
+  BF_LPBK_NONE(0),
+  BF_LPBK_MAC_NEAR(1),
+  BF_LPBK_MAC_FAR(2),
+  BF_LPBK_PCS_NEAR(3),
+  BF_LPBK_SERDES_NEAR(4),
+  BF_LPBK_SERDES_FAR(5);
+
+  private final int value;
+
+  private pal_loopback_mod_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_loopback_mod_t findByValue(int value) { 
+    switch (value) {
+      case 0:
+        return BF_LPBK_NONE;
+      case 1:
+        return BF_LPBK_MAC_NEAR;
+      case 2:
+        return BF_LPBK_MAC_FAR;
+      case 3:
+        return BF_LPBK_PCS_NEAR;
+      case 4:
+        return BF_LPBK_SERDES_NEAR;
+      case 5:
+        return BF_LPBK_SERDES_FAR;
+      default:
+        return null;
+    }
+  }
+}
diff --git a/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_oper_status_t.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_oper_status_t.java
new file mode 100644
index 0000000..11df778
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_oper_status_t.java
@@ -0,0 +1,41 @@
+package org.onosproject.drivers.barefoot.pro.pal;
+
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+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-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_port_speed_t.java b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_port_speed_t.java
new file mode 100644
index 0000000..e083a84
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/java/org/onosproject/drivers/barefoot/pro/pal/pal_port_speed_t.java
@@ -0,0 +1,62 @@
+package org.onosproject.drivers.barefoot.pro.pal;
+
+/**
+ * Autogenerated by Thrift Compiler (0.11.0)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+
+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;
+    }
+  }
+}
diff --git a/drivers/barefoot-pro/src/main/resources/barefoot-pro-drivers.xml b/drivers/barefoot-pro/src/main/resources/barefoot-pro-drivers.xml
new file mode 100644
index 0000000..30a0110
--- /dev/null
+++ b/drivers/barefoot-pro/src/main/resources/barefoot-pro-drivers.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2018-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.
+  -->
+<drivers>
+    <driver name="barefoot-pro" manufacturer="Barefoot Networks" hwVersion="1.0" swVersion="1.0" extends="barefoot">
+        <behaviour api="org.onosproject.net.behaviour.PiPipelineProgrammable"
+                   impl="org.onosproject.drivers.barefoot.pro.TofinoProPipelineProgrammable"/>
+    </driver>
+</drivers>
+
diff --git a/mwc.defs b/mwc.defs
index 26017d4..2eb36ad 100644
--- a/mwc.defs
+++ b/mwc.defs
@@ -2,6 +2,7 @@
 
 MWC_APPS = [
     '//pipelines/fabric-pro:onos-pipelines-fabric-pro-oar',
+    '//drivers/barefoot-pro:onos-drivers-barefoot-pro-oar',
 ]
 
 APPS = APPS + MWC_APPS
