diff --git a/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000FlowRuleProgrammable.java b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000FlowRuleProgrammable.java
new file mode 100644
index 0000000..4df22ec
--- /dev/null
+++ b/drivers/microsemi/src/main/java/org/onosproject/drivers/microsemi/EA1000FlowRuleProgrammable.java
@@ -0,0 +1,974 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * 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.microsemi;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.math.BigInteger;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+
+import org.onlab.packet.EthType;
+import org.onlab.packet.EthType.EtherType;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.drivers.microsemi.yang.MseaSaFilteringNetconfService;
+import org.onosproject.drivers.microsemi.yang.MseaUniEvcServiceNetconfService;
+import org.onosproject.drivers.microsemi.yang.UniSide;
+import org.onosproject.drivers.microsemi.yang.custom.CustomEvcPerUnic;
+import org.onosproject.drivers.microsemi.yang.custom.CustomEvcPerUnin;
+import org.onosproject.drivers.microsemi.yang.utils.CeVlanMapUtils;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowEntry.FlowEntryState;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleProgrammable;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.Criterion.Type;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanHeaderInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
+import org.onosproject.net.meter.MeterId;
+import org.onosproject.netconf.DatastoreId;
+import org.onosproject.netconf.NetconfController;
+import org.onosproject.netconf.NetconfDevice;
+import org.onosproject.netconf.NetconfException;
+import org.onosproject.netconf.NetconfSession;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.MseaSaFilteringOpParam;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.DefaultSourceIpaddressFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.SourceIpaddressFiltering;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.DefaultInterfaceEth0;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.InterfaceEth0;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.DefaultSourceAddressRange;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.FilterAdminStateEnum;
+import org.onosproject.yang.gen.v1.mseasafiltering.rev20160412.mseasafiltering.sourceipaddressfiltering.interfaceeth0.SourceAddressRange;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.Identifier45;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.ServiceListType;
+import org.onosproject.yang.gen.v1.mseatypes.rev20160229.mseatypes.VlanIdType;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcService;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.MseaUniEvcServiceOpParam;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.DefaultMefServices;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.MefServices;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.DefaultFlowMapping;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.FlowMapping;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.TagManipulation;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.DefaultTagOverwrite;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.DefaultTagPop;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.DefaultTagPush;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.TagOverwrite;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.TagPop;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.TagPush;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.evcperuniextensionattributes.tagmanipulation.tagpush.tagpush.PushTagTypeEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.DefaultProfiles;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.DefaultUni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.Profiles;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.Uni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.BwpGroup;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.profiles.DefaultBwpGroup;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.DefaultEvc;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.Evc;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.UniSideInterfaceAssignmentEnum;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.DefaultEvcPerUni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.EvcPerUni;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.evcperuni.EvcPerUnic;
+import org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice.mefservices.uni.evc.evcperuni.EvcPerUnin;
+import org.slf4j.Logger;
+
+/**
+ * An implementation of the FlowRuleProgrammable behaviour for the EA10000 device.
+ *
+ * This device is not a native Open Flow device. It has only a NETCONF interface for configuration
+ * status retrieval and notifications. It supports only a small subset of OpenFlow rules.<br>
+ *
+ * The device supports only:<br>
+ * 1) Open flow rules that blocks certain IP address ranges, but only those incoming on Port 0
+ *    and has a limit of 10 such rules<br>
+ * 2) Open flow rules that PUSH, POP and OVERWRITE VLAN tags on both ports. This can push and overwrite
+ *    both C-TAGs (0x8100) and S-TAGs (0x88a8).
+ */
+public class EA1000FlowRuleProgrammable extends AbstractHandlerBehaviour implements FlowRuleProgrammable {
+
+    protected final Logger log = getLogger(getClass());
+    public static final String MICROSEMI_DRIVERS = "com.microsemi.drivers";
+    public static final int PRIORITY_DEFAULT = 50000;
+    //To protect the NETCONF session from concurrent access across flow addition and removal
+    static Semaphore sessionMutex = new Semaphore(1);
+
+    /**
+     * Get the flow entries that are present on the EA1000.
+     * Since the EA1000 does not have any 'real' flow entries these are retrieved from 2 configuration
+     * areas on the EA1000 NETCONF model - from SA filtering YANG model and from EVC UNI YANG model.<br>
+     * The flow entries must match exactly the FlowRule entries in the ONOS store. If they are not an
+     * exact match the device will be requested to remove those flows and the FlowRule will stay in a
+     * PENDING_ADD state.
+     * @return A collection of Flow Entries
+     */
+    @Override
+    public Collection<FlowEntry> getFlowEntries() {
+        Collection<FlowEntry> flowEntryCollection = new HashSet<FlowEntry>();
+
+        UniSideInterfaceAssignmentEnum portAssignment = UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST;
+        NetconfController controller = checkNotNull(handler().get(NetconfController.class));
+        NetconfDevice ncDevice = controller.getDevicesMap().get(handler().data().deviceId());
+        if (ncDevice == null) {
+            log.error("Internal ONOS Error. Device has been marked as reachable, " +
+                            "but deviceID {} is not in Devices Map. Continuing with empty description",
+                    handler().data().deviceId());
+            return flowEntryCollection;
+        }
+        NetconfSession session = ncDevice.getSession();
+        CoreService coreService = checkNotNull(handler().get(CoreService.class));
+        ApplicationId appId = coreService.getAppId(MICROSEMI_DRIVERS);
+        MseaSaFilteringNetconfService mseaSaFilteringService =
+                (MseaSaFilteringNetconfService) checkNotNull(handler().get(MseaSaFilteringNetconfService.class));
+        MseaUniEvcServiceNetconfService mseaUniEvcServiceSvc =
+                (MseaUniEvcServiceNetconfService) checkNotNull(handler().get(MseaUniEvcServiceNetconfService.class));
+        log.debug("getFlowEntries() called on EA1000FlowRuleProgrammable");
+
+        //First get the MseaSaFiltering rules
+        SourceIpaddressFiltering sip =
+                new DefaultSourceIpaddressFiltering();
+
+        MseaSaFilteringOpParam op =
+                new MseaSaFilteringOpParam();
+        op.sourceIpaddressFiltering(sip);
+
+        try {
+            MseaSaFiltering saFilteringCurrent =
+                    mseaSaFilteringService.getMseaSaFiltering(op, session);
+            if (saFilteringCurrent != null &&
+                    saFilteringCurrent.sourceIpaddressFiltering() != null) {
+                flowEntryCollection.addAll(
+                        convertSaFilteringToFlowRules(saFilteringCurrent, appId));
+            }
+        } catch (NetconfException e) {
+            if (e.getCause() instanceof TimeoutException) {
+                log.warn("Timeout exception getting SA Filt Flow Entries from {}",
+                        handler().data().deviceId());
+                return flowEntryCollection;
+            } else {
+                log.error("Unexpected error on SA Filt getFlowEntries on {}",
+                        handler().data().deviceId(), e);
+            }
+        }
+
+
+        //Then get the EVCs - there will be a flow entry per EVC
+        MefServices mefServices = new DefaultMefServices();
+        mefServices.uni(new DefaultUni());
+
+        MseaUniEvcServiceOpParam mseaUniEvcServiceFilter = new MseaUniEvcServiceOpParam();
+        mseaUniEvcServiceFilter.mefServices(mefServices);
+        try {
+            MseaUniEvcService uniEvcCurrent =
+                    mseaUniEvcServiceSvc.getConfigMseaUniEvcService(mseaUniEvcServiceFilter,
+                            session, DatastoreId.RUNNING);
+
+            flowEntryCollection.addAll(
+                    convertEvcUniToFlowRules(uniEvcCurrent, portAssignment));
+
+        } catch (NetconfException e) {
+            if (e.getCause() instanceof TimeoutException) {
+                log.warn("Timeout exception getting EVC Flow Entries from {}",
+                        handler().data().deviceId());
+                return flowEntryCollection;
+            } else {
+                log.error("Unexpected error on EVC getFlowEntries on {}",
+                        handler().data().deviceId(), e);
+            }
+        }
+
+        return flowEntryCollection;
+    }
+
+    /**
+     * Apply the flow entries to the EA1000.
+     * Since the EA1000 does not have any 'real' flow entries these are converted 2 configuration
+     * areas on the EA1000 NETCONF model - to SA filtering YANG model and to EVC UNI YANG model.<br>
+     * Only a subset of the possible OpenFlow rules are supported. Any rule that's not handled
+     * will not be in the returned set.
+     *
+     * @param rules A collection of Flow Rules to be applied to the EA1000
+     * @return A collection of the Flow Rules that have been added.
+     */
+    @Override
+    public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) {
+        Collection<FlowRule> frAdded = new HashSet<FlowRule>();
+        if (rules == null || rules.size() == 0) {
+            return rules;
+        }
+        NetconfController controller = checkNotNull(handler().get(NetconfController.class));
+        NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
+        MseaSaFilteringNetconfService mseaSaFilteringService =
+                (MseaSaFilteringNetconfService) checkNotNull(handler().get(MseaSaFilteringNetconfService.class));
+        MseaUniEvcServiceNetconfService mseaUniEvcServiceSvc =
+                (MseaUniEvcServiceNetconfService) checkNotNull(handler().get(MseaUniEvcServiceNetconfService.class));
+        log.debug("applyFlowRules() called on EA1000FlowRuleProgrammable with {} rules.", rules.size());
+        // FIXME: Change this so it's dynamically driven
+        UniSideInterfaceAssignmentEnum portAssignment = UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST;
+
+        List<SourceAddressRange> saRangeList = new ArrayList<SourceAddressRange>();
+        Map<Integer, Evc> evcMap = new HashMap<>();
+
+        //Retrieve the list of actual EVCs and the CeVlanMaps from device
+        List<Evc> activeEvcs = new ArrayList<>();
+        try {
+            sessionMutex.acquire();
+            MseaUniEvcService evcResponse =
+                    mseaUniEvcServiceSvc.getmseaUniEvcCeVlanMaps(session, DatastoreId.RUNNING);
+            //There could be zero or more EVCs
+            if (evcResponse != null && evcResponse.mefServices() != null && evcResponse.mefServices().uni() != null) {
+                activeEvcs.addAll(evcResponse.mefServices().uni().evc());
+            }
+        } catch (NetconfException | InterruptedException e1) {
+            log.warn("Unexpected error on applyFlowRules", e1);
+        }
+
+        for (FlowRule fr : rules) {
+
+            // IP SA Filtering can only apply to Port 0 optics
+            if (fr.selector().getCriterion(Type.IPV4_SRC) != null &&
+                    fr.selector().getCriterion(Type.IN_PORT) != null &&
+                    ((PortCriterion) fr.selector().getCriterion(Type.IN_PORT)).port().toLong() == 0) {
+                parseFrForSaRange(frAdded, saRangeList, fr);
+
+            // EVCs will be defined by Flow Rules relating to VIDs
+            } else if (fr.selector().getCriterion(Type.VLAN_VID) != null &&
+                    fr.selector().getCriterion(Type.IN_PORT) != null) {
+                //There could be many Flow Rules for one EVC depending on the ceVlanMap
+                //Cannot build up the EVC until we know the details - the key is the tableID and port
+                parseFrForEvcs(frAdded, evcMap, activeEvcs, portAssignment, fr);
+            } else {
+                log.info("Unexpected Flow Rule type applied: " + fr);
+            }
+        }
+
+        //If there are IPv4 Flow Rules created commit them now through the
+        //MseaSaFiltering service
+        if (saRangeList.size() > 0) {
+            try {
+                mseaSaFilteringService.setMseaSaFiltering(
+                            buildSaFilteringObject(saRangeList), session, DatastoreId.RUNNING);
+            } catch (NetconfException e) {
+                log.error("Error applying Flow Rules to SA Filtering - will try again: " + e.getMessage());
+                sessionMutex.release();
+                return frAdded;
+            }
+        }
+        //If there are EVC flow rules then populate the MseaUniEvc part of EA1000
+        if (evcMap.size() > 0) {
+            List<Evc> evcList = evcMap.entrySet().stream()
+                    .map(x -> x.getValue())
+                    .collect(Collectors.toList());
+            Uni uni = new DefaultUni();
+            URI deviceName = handler().data().deviceId().uri();
+            uni.name(new Identifier45("Uni-on-"
+                    + deviceName.getSchemeSpecificPart()));
+            uni.evc(evcList);
+
+            List<BwpGroup> bwpGroupList = new ArrayList<BwpGroup>();
+            BwpGroup bwpGrp = new DefaultBwpGroup();
+            bwpGrp.groupIndex((short) 0);
+            bwpGroupList.add(bwpGrp);
+            Profiles profiles = new DefaultProfiles();
+            profiles.bwpGroup(bwpGroupList);
+
+            MefServices mefServices = new DefaultMefServices();
+            mefServices.uni(uni);
+            mefServices.profiles(profiles);
+
+            MseaUniEvcServiceOpParam mseaUniEvcServiceFilter = new MseaUniEvcServiceOpParam();
+            mseaUniEvcServiceFilter.mefServices(mefServices);
+            try {
+                mseaUniEvcServiceSvc.setMseaUniEvcService(mseaUniEvcServiceFilter, session, DatastoreId.RUNNING);
+            } catch (NetconfException e) {
+                log.error("Error applying Flow Rules to EVC - will try again: " + e.getMessage());
+                sessionMutex.release();
+                return frAdded;
+            }
+        }
+        sessionMutex.release();
+        return frAdded;
+    }
+
+    /**
+     * Remove flow rules from the EA1000.
+     * Since the EA1000 does not have any 'real' flow entries these are converted 2 configuration
+     * areas on the EA1000 NETCONF model - to SA filtering YANG model and to EVC UNI YANG model.
+     *
+     * @param rulesToRemove A collection of Flow Rules to be removed to the EA1000
+     * @return A collection of the Flow Rules that have been removed.
+     */
+    @Override
+    public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rulesToRemove) {
+        NetconfController controller = checkNotNull(handler().get(NetconfController.class));
+        NetconfSession session = controller.getDevicesMap().get(handler().data().deviceId()).getSession();
+        MseaSaFilteringNetconfService mseaSaFilteringService =
+                (MseaSaFilteringNetconfService) checkNotNull(handler().get(MseaSaFilteringNetconfService.class));
+        MseaUniEvcServiceNetconfService mseaUniEvcServiceSvc =
+                (MseaUniEvcServiceNetconfService) checkNotNull(handler().get(MseaUniEvcServiceNetconfService.class));
+        UniSideInterfaceAssignmentEnum portAssignment = UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST;
+        log.debug("removeFlowRules() called on EA1000FlowRuleProgrammable with {} rules.", rulesToRemove.size());
+
+        if (rulesToRemove.size() == 0) {
+            return rulesToRemove;
+        }
+
+        //Retrieve the list of actual EVCs and the CeVlanMaps from device
+        List<Evc> activeEvcs = new ArrayList<>();
+        List<Short> acvtiveFiltRanges = new ArrayList<>();
+        try {
+            sessionMutex.acquire();
+            MseaUniEvcService evcResponse =
+                    mseaUniEvcServiceSvc.getmseaUniEvcCeVlanMaps(session, DatastoreId.RUNNING);
+            //There could be zero or more EVCs
+            if (evcResponse != null && evcResponse.mefServices() != null && evcResponse.mefServices().uni() != null) {
+                activeEvcs.addAll(evcResponse.mefServices().uni().evc());
+            }
+            mseaSaFilteringService.getConfigMseaSaFilterIds(session).forEach(
+                    r -> acvtiveFiltRanges.add(r.rangeId()));
+
+        } catch (NetconfException | InterruptedException e1) {
+            log.warn("Error on removeFlowRules.", e1);
+        }
+
+        List<SourceAddressRange> saRangeList = new ArrayList<SourceAddressRange>();
+        Map<Integer, String> ceVlanMapMap = new HashMap<>();
+        Map<Integer, List<Short>> flowIdMap = new HashMap<>();
+
+        Collection<FlowRule> rulesRemoved = new HashSet<FlowRule>();
+        for (FlowRule ruleToRemove : rulesToRemove) {
+            // IP SA Filtering can only apply to Port 0 optics
+            if (ruleToRemove.selector().getCriterion(Type.IPV4_SRC) != null &&
+                    ruleToRemove.selector().getCriterion(Type.IN_PORT) != null &&
+                    ((PortCriterion) ruleToRemove.selector().getCriterion(Type.IN_PORT)).port().toLong() == 0) {
+                SourceAddressRange sar = new DefaultSourceAddressRange();
+                sar.rangeId((short) ruleToRemove.tableId());
+                acvtiveFiltRanges.remove(Short.valueOf((short) ruleToRemove.tableId()));
+                rulesRemoved.add(ruleToRemove);
+                saRangeList.add(sar);
+
+            } else if (ruleToRemove.selector().getCriterion(Type.VLAN_VID) != null &&
+                    ruleToRemove.selector().getCriterion(Type.IN_PORT) != null) {
+                PortNumber portNumber = ((PortCriterion) ruleToRemove.selector().getCriterion(Type.IN_PORT)).port();
+                VlanId vlanId = ((VlanIdCriterion) ruleToRemove.selector().getCriterion(Type.VLAN_VID)).vlanId();
+                int evcId = ruleToRemove.tableId();
+                int evcKey = (evcId << 2) + (int) portNumber.toLong();
+                String activeCeVlanMap = "";
+                //If this is one of many VLANs belonging to an EVC then we should only remove this VLAN
+                // from the ceVlanMap and not the whole EVC
+                if (!ceVlanMapMap.containsKey(evcKey)) {
+                    for (Evc activeEvc:activeEvcs) {
+                        if (activeEvc.evcIndex() == evcId) {
+                            if (Ea1000Port.fromNum(portNumber.toLong()).nOrC(portAssignment) ==
+                                    UniSide.CUSTOMER) {
+                                activeCeVlanMap = activeEvc.evcPerUni().evcPerUnic().ceVlanMap().string();
+                            } else if (Ea1000Port.fromNum(portNumber.toLong()).nOrC(portAssignment) ==
+                                    UniSide.NETWORK) {
+                                activeCeVlanMap = activeEvc.evcPerUni().evcPerUnin().ceVlanMap().string();
+                            }
+                        }
+                    }
+                }
+
+                ceVlanMapMap.put(evcKey, CeVlanMapUtils.removeFromCeVlanMap(activeCeVlanMap, vlanId.id()));
+                if (!flowIdMap.containsKey(evcKey)) {
+                    flowIdMap.put(evcKey, new ArrayList<>());
+                }
+                flowIdMap.get(evcKey).add(vlanId.id());
+                rulesRemoved.add(ruleToRemove);
+
+            } else {
+                log.info("Unexpected Flow Rule type removal: " + ruleToRemove);
+            }
+        }
+
+        //If there are IPv4 Flow Rules created commit them now through the
+        //MseaSaFiltering service
+        if (saRangeList.size() > 0 && acvtiveFiltRanges.size() == 0) {
+            try {
+                SourceIpaddressFiltering saFilter =
+                        new DefaultSourceIpaddressFiltering();
+                MseaSaFilteringOpParam mseaSaFiltering = new MseaSaFilteringOpParam();
+                mseaSaFiltering.sourceIpaddressFiltering(saFilter);
+
+                mseaSaFilteringService.deleteMseaSaFilteringRange(
+                        mseaSaFiltering, session, DatastoreId.RUNNING);
+            } catch (NetconfException e) {
+                log.warn("Remove FlowRule on MseaSaFilteringService could not delete all SARules - "
+                        + "they may already have been deleted: " + e.getMessage());
+            }
+        } else if (saRangeList.size() > 0) {
+            try {
+                mseaSaFilteringService.deleteMseaSaFilteringRange(
+                        buildSaFilteringObject(saRangeList), session, DatastoreId.RUNNING);
+            } catch (NetconfException e) {
+                log.warn("Remove FlowRule on MseaSaFilteringService could not delete SARule - "
+                        + "it may already have been deleted: " + e.getMessage());
+            }
+        }
+
+        if (ceVlanMapMap.size() > 0) {
+            try {
+                mseaUniEvcServiceSvc.removeEvcUniFlowEntries(ceVlanMapMap, flowIdMap,
+                        session, DatastoreId.RUNNING, portAssignment);
+            } catch (NetconfException e) {
+                log.warn("Remove FlowRule on MseaUniEvcService could not delete EVC - "
+                        + "it may already have been deleted: " + e.getMessage());
+            }
+        }
+
+        sessionMutex.release();
+        return rulesRemoved;
+    }
+
+    /**
+     * An internal method for extracting one EVC from a list and returning its ceVlanMap.
+     *
+     * @param evcList - the list of known EVCs
+     * @param evcIndex - the index of the EVC we're looking for
+     * @param side - the side of the UNI
+     * @return - the CEVlanMap we're looking for
+     */
+    private String getCeVlanMapForIdxFromEvcList(List<Evc> evcList, long evcIndex, UniSide side) {
+        if (evcList != null && evcList.size() > 0) {
+            for (Evc evc:evcList) {
+                if (evc.evcIndex() == evcIndex && evc.evcPerUni() != null) {
+                    if (side == UniSide.CUSTOMER &&
+                        evc.evcPerUni().evcPerUnic() != null &&
+                        evc.evcPerUni().evcPerUnic().ceVlanMap() != null) {
+                        return evc.evcPerUni().evcPerUnic().ceVlanMap().string();
+                    } else if (side == UniSide.NETWORK &&
+                        evc.evcPerUni().evcPerUnin() != null &&
+                        evc.evcPerUni().evcPerUnin().ceVlanMap() != null) {
+                        return evc.evcPerUni().evcPerUnin().ceVlanMap().string();
+                    }
+                }
+            }
+        }
+
+        return ""; //The EVC required was not in the list
+    }
+
+    /**
+     * An internal method to convert from a FlowRule to SARange.
+     *
+     * @param frList A collection of flow rules
+     * @param saRangeList A list of SARanges
+     * @param fr A flow rule
+     */
+    private void parseFrForSaRange(Collection<FlowRule> frList, List<SourceAddressRange> saRangeList, FlowRule fr) {
+        String ipAddrStr = fr.selector().getCriterion(Type.IPV4_SRC).toString().substring(9);
+        log.debug("Applying IP address to " + ipAddrStr
+                + " (on Port 0) to IP SA Filtering on EA1000 through NETCONF");
+
+        SourceAddressRange sar =
+                new DefaultSourceAddressRange();
+
+        sar.rangeId((short) fr.tableId());
+        sar.name("Flow:" + fr.id().toString());
+        sar.ipv4AddressPrefix(ipAddrStr);
+
+        frList.add(fr);
+        saRangeList.add(sar);
+    }
+
+    private void parseFrForEvcs(Collection<FlowRule> frList, Map<Integer, Evc> evcMap,
+            List<Evc> activeEvcs, UniSideInterfaceAssignmentEnum portAssignment, FlowRule fr) {
+        //There could be many Flow Rules for one EVC depending on the ceVlanMap
+        //Cannot build up the EVC until we know the details - the key is the tableID and port
+        Ea1000Port port = Ea1000Port.fromNum(
+                ((PortCriterion) fr.selector().getCriterion(Type.IN_PORT)).port().toLong());
+        Integer evcKey = (fr.tableId() << 2) + port.portNum();
+        VlanId sourceVid = ((VlanIdCriterion) fr.selector().getCriterion(Type.VLAN_VID)).vlanId();
+        FlowMapping fm = new DefaultFlowMapping();
+        fm.ceVlanId(VlanIdType.of(sourceVid.id()));
+        fm.flowId(BigInteger.valueOf(fr.id().value()));
+
+        if (evcMap.containsKey(evcKey)) { //Is there an entry already for this EVC and port?
+            //Replace ceVlanMap
+            if (port.nOrC(portAssignment) == UniSide.CUSTOMER) {
+                evcMap.get(evcKey).evcPerUni().evcPerUnic().addToFlowMapping(fm);
+                ServiceListType newCeVlanMap = new ServiceListType(
+                        CeVlanMapUtils.addtoCeVlanMap(
+                                evcMap.get(evcKey).evcPerUni().evcPerUnic().ceVlanMap().toString(),
+                                sourceVid.toShort()));
+                evcMap.get(evcKey).evcPerUni().evcPerUnic().ceVlanMap(newCeVlanMap);
+            } else {
+                evcMap.get(evcKey).evcPerUni().evcPerUnin().addToFlowMapping(fm);
+                ServiceListType newCeVlanMap = new ServiceListType(
+                        CeVlanMapUtils.addtoCeVlanMap(
+                                evcMap.get(evcKey).evcPerUni().evcPerUnin().ceVlanMap().toString(),
+                                sourceVid.toShort()));
+                evcMap.get(evcKey).evcPerUni().evcPerUnin().ceVlanMap(newCeVlanMap);
+            }
+        } else if (evcMap.containsKey((evcKey ^ 1))) { //Is there an entry for this EVC but the opposite port?
+            TagManipulation tm = getTagManipulation(fr);
+            if (port.nOrC(portAssignment) == UniSide.NETWORK) {
+                ServiceListType newCeVlanMap = new ServiceListType(
+                        CeVlanMapUtils.addtoCeVlanMap(
+                                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().ceVlanMap().toString(),
+                                sourceVid.toShort()));
+                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().ceVlanMap(newCeVlanMap);
+                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().tagManipulation(tm);
+                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().addToFlowMapping(fm);
+                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnin().ingressBwpGroupIndex(getMeterId(fr.treatment()));
+            } else {
+                ServiceListType newCeVlanMap = new ServiceListType(
+                        CeVlanMapUtils.addtoCeVlanMap(
+                                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().ceVlanMap().toString(),
+                                sourceVid.toShort()));
+                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().ceVlanMap(newCeVlanMap);
+                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().tagManipulation(tm);
+                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().addToFlowMapping(fm);
+                evcMap.get(evcKey ^ 1).evcPerUni().evcPerUnic().ingressBwpGroupIndex(getMeterId(fr.treatment()));
+            }
+        } else {
+            Evc evc = new DefaultEvc();
+            EvcPerUnin epun = new CustomEvcPerUnin();
+            EvcPerUnic epuc = new CustomEvcPerUnic();
+            TagManipulation tm = getTagManipulation(fr);
+
+            UniSide side = port.nOrC(portAssignment);
+            String oldCeVlanMap = getCeVlanMapForIdxFromEvcList(activeEvcs, fr.tableId(), side);
+            String newCeVlanMap =
+                    CeVlanMapUtils.addtoCeVlanMap(oldCeVlanMap, sourceVid.id());
+            String oppositeCeVlanMap =
+                    getCeVlanMapForIdxFromEvcList(activeEvcs, fr.tableId(),
+                            port.opposite().nOrC(portAssignment));
+            oppositeCeVlanMap = oppositeCeVlanMap.isEmpty() ? "0" : oppositeCeVlanMap;
+            if (side == UniSide.NETWORK) {
+                epun.ceVlanMap(new ServiceListType(newCeVlanMap));
+                epun.tagManipulation(tm);
+                epun.addToFlowMapping(fm);
+                epun.ingressBwpGroupIndex(getMeterId(fr.treatment()));
+
+                epuc.ceVlanMap(new ServiceListType(oppositeCeVlanMap));
+                epuc.ingressBwpGroupIndex(new Long(0));
+            } else {
+                epuc.ceVlanMap(new ServiceListType(newCeVlanMap));
+                epuc.tagManipulation(tm);
+                epuc.addToFlowMapping(fm);
+                epuc.ingressBwpGroupIndex(getMeterId(fr.treatment()));
+
+                epun.ceVlanMap(new ServiceListType(oppositeCeVlanMap));
+                epun.ingressBwpGroupIndex(new Long(0));
+            }
+
+            evc.evcIndex(fr.tableId());
+            evc.name(new Identifier45("EVC-" + String.valueOf(fr.tableId())));
+
+            DefaultEvcPerUni epu = new DefaultEvcPerUni();
+            epu.evcPerUnin(epun);
+            epu.evcPerUnic(epuc);
+            evc.evcPerUni(epu);
+
+            evcMap.put(evcKey, evc);
+        }
+
+        frList.add(fr);
+    }
+
+
+    private MseaSaFilteringOpParam buildSaFilteringObject(List<SourceAddressRange> saRangeList) {
+        InterfaceEth0 saIf = new DefaultInterfaceEth0();
+        for (SourceAddressRange sa:saRangeList) {
+            saIf.addToSourceAddressRange(sa);
+        }
+        saIf.filterAdminState(FilterAdminStateEnum.BLACKLIST);
+
+        SourceIpaddressFiltering saFilter =
+                new DefaultSourceIpaddressFiltering();
+        saFilter.interfaceEth0(saIf);
+
+        MseaSaFilteringOpParam mseaSaFiltering = new MseaSaFilteringOpParam();
+        mseaSaFiltering.sourceIpaddressFiltering(saFilter);
+
+        return mseaSaFiltering;
+    }
+
+    private Collection<FlowEntry> convertSaFilteringToFlowRules(
+            MseaSaFiltering saFilteringCurrent, ApplicationId appId) {
+        Collection<FlowEntry> flowEntryCollection = new HashSet<FlowEntry>();
+
+        List<SourceAddressRange> saRangelist =
+                saFilteringCurrent.sourceIpaddressFiltering().interfaceEth0().sourceAddressRange();
+        Criterion matchInPort = Criteria.matchInPort(PortNumber.portNumber(0));
+        TrafficSelector.Builder tsBuilder = DefaultTrafficSelector.builder();
+
+        if (saRangelist != null) {
+            for (SourceAddressRange sa : saRangelist) {
+                Criterion matchIpSrc = Criteria.matchIPSrc(IpPrefix.valueOf(sa.ipv4AddressPrefix()));
+
+                TrafficSelector selector = tsBuilder.add(matchIpSrc).add(matchInPort).build();
+
+                TrafficTreatment.Builder trBuilder = DefaultTrafficTreatment.builder();
+                TrafficTreatment treatment = trBuilder.drop().build();
+
+                FlowRule.Builder feBuilder = new DefaultFlowRule.Builder();
+                if (sa.name() != null && sa.name().startsWith("Flow:")) {
+                    String[] nameParts = sa.name().split(":");
+                    Long cookie = Long.valueOf(nameParts[1], 16);
+                    feBuilder = feBuilder.withCookie(cookie);
+                } else {
+                    feBuilder = feBuilder.fromApp(appId);
+                }
+
+                FlowRule fr = feBuilder
+                        .forDevice(handler().data().deviceId())
+                        .withSelector(selector)
+                        .withTreatment(treatment)
+                        .forTable(sa.rangeId())
+                        .makePermanent()
+                        .withPriority(PRIORITY_DEFAULT)
+                        .build();
+
+                flowEntryCollection.add(
+                        new DefaultFlowEntry(fr, FlowEntryState.ADDED, 0, 0, 0));
+            }
+        }
+        return flowEntryCollection;
+    }
+
+
+    private Collection<FlowEntry> convertEvcUniToFlowRules(
+            MseaUniEvcService uniEvcCurrent, UniSideInterfaceAssignmentEnum portAssignment) {
+        Collection<FlowEntry> flowEntryCollection = new HashSet<FlowEntry>();
+
+        if (uniEvcCurrent == null || uniEvcCurrent.mefServices() == null ||
+                uniEvcCurrent.mefServices().uni() == null || uniEvcCurrent.mefServices().uni().evc() == null) {
+            log.info("No EVC's found when getting flow rules");
+            return flowEntryCollection;
+        }
+
+        for (Evc evc:uniEvcCurrent.mefServices().uni().evc()) {
+            FlowRule.Builder frBuilder = new DefaultFlowRule.Builder();
+            TrafficSelector.Builder tsBuilder = DefaultTrafficSelector.builder();
+
+            TrafficTreatment uniNTreatment = treatmentForUniSde(evc.evcPerUni(), true);
+            //Depending on the ceVlanMap there may be multiple VLans and hence multiple flow entries
+            Short[] vlanIdsUniN =
+                    CeVlanMapUtils.getVlanSet(ceVlanMapForUniSide(evc.evcPerUni(), true));
+            for (Short vlanId:vlanIdsUniN) {
+                if (vlanId == 0) {
+                    continue;
+                }
+                Criterion uniNportCriterion = criterionPortForUniSide(portAssignment, true);
+                TrafficSelector tsUniN = tsBuilder.matchVlanId(VlanId.vlanId(vlanId)).add(uniNportCriterion).build();
+                long flowId = getFlowIdForVlan(evc.evcPerUni().evcPerUnin().flowMapping(), vlanId);
+
+                FlowRule frUniN = frBuilder
+                    .forDevice(handler().data().deviceId())
+                    .withSelector(tsUniN)
+                    .withTreatment(uniNTreatment)
+                    .forTable(new Long(evc.evcIndex()).intValue()) //narrowing to int
+                    .makePermanent()
+                    .withPriority(PRIORITY_DEFAULT)
+                    .withCookie(flowId)
+                    .build();
+                flowEntryCollection.add(new DefaultFlowEntry(frUniN, FlowEntryState.ADDED, 0, 0, 0));
+            }
+
+            TrafficTreatment uniCTreatment = treatmentForUniSde(evc.evcPerUni(), false);
+            //Depending on the ceVlanMap there may be multiple VLans and hence multiple flow entries
+            Short[] vlanIdsUniC =
+                    CeVlanMapUtils.getVlanSet(ceVlanMapForUniSide(evc.evcPerUni(), false));
+            if (vlanIdsUniC != null && vlanIdsUniC.length > 0) {
+                for (Short vlanId:vlanIdsUniC) {
+                    if (vlanId == 0) {
+                        continue;
+                    }
+                    Criterion uniCportCriterion = criterionPortForUniSide(portAssignment, false);
+                    TrafficSelector tsUniC =
+                            tsBuilder.matchVlanId(VlanId.vlanId(vlanId)).add(uniCportCriterion).build();
+                    long flowId = getFlowIdForVlan(evc.evcPerUni().evcPerUnic().flowMapping(), vlanId);
+
+                    FlowRule frUniC = frBuilder
+                            .forDevice(handler().data().deviceId())
+                            .withSelector(tsUniC)
+                            .withTreatment(uniCTreatment)
+                            .forTable(new Long(evc.evcIndex()).intValue()) //narrowing to int
+                            .makePermanent()
+                            .withPriority(PRIORITY_DEFAULT)
+                            .withCookie(flowId)
+                            .build();
+                    flowEntryCollection.add(new DefaultFlowEntry(frUniC, FlowEntryState.ADDED, 0, 0, 0));
+                }
+            }
+        }
+
+        return flowEntryCollection;
+    }
+
+    private long getFlowIdForVlan(List<FlowMapping> fmList, Short vlanId) {
+        if (fmList == null || vlanId == null) {
+            log.warn("Flow Mapping list is null when reading EVCs");
+            return -1L;
+        }
+        for (FlowMapping fm:fmList) {
+            if (fm.ceVlanId().uint16() == vlanId.intValue()) {
+                return fm.flowId().longValue();
+            }
+        }
+        return 0L;
+    }
+
+    private String ceVlanMapForUniSide(
+            EvcPerUni evcPerUni, boolean portN) {
+        if (portN) {
+            return evcPerUni.evcPerUnin().ceVlanMap().string();
+        } else {
+            return evcPerUni.evcPerUnic().ceVlanMap().string();
+        }
+    }
+
+    private Criterion criterionPortForUniSide(
+            UniSideInterfaceAssignmentEnum portAssignment, boolean portN) {
+        boolean cOnOptics = (portAssignment == UniSideInterfaceAssignmentEnum.UNI_C_ON_OPTICS);
+        int portNum = ((cOnOptics && portN) || (!cOnOptics && !portN)) ? 1 : 0;
+        return Criteria.matchInPort(PortNumber.portNumber(portNum));
+    }
+
+    private TrafficTreatment treatmentForUniSde(
+            EvcPerUni evcPerUni, boolean portN) {
+        TrafficTreatment.Builder trBuilder = DefaultTrafficTreatment.builder();
+
+        TagManipulation tm = null;
+        short meterId = 0;
+        if (portN) {
+            tm = evcPerUni.evcPerUnin().tagManipulation();
+            meterId = (short) evcPerUni.evcPerUnin().ingressBwpGroupIndex();
+        } else {
+            tm = evcPerUni.evcPerUnic().tagManipulation();
+            meterId = (short) evcPerUni.evcPerUnic().ingressBwpGroupIndex();
+        }
+
+        if (meterId > 0L) {
+            trBuilder = trBuilder.meter(MeterId.meterId((long) meterId));
+//            trBuilder = trBuilder.meter(MeterId.meterId(meterId)).transition(0);
+        }
+
+        if (tm == null) {
+            return trBuilder.build(); //no tag manipulation found
+        }
+
+        if (tm.getClass().equals(DefaultTagPush.class)) {
+            VlanId pushVlanNum = VlanId.vlanId((short) ((TagPush) tm).tagPush().outerTagVlan().uint16());
+            PushTagTypeEnum pushTagType = ((TagPush) tm).tagPush().pushTagType();
+            //Note - the order of elements below MUST match the order of the Treatment in the stored FlowRule
+            // to be an exactMatch. See DefaultFlowRule.exactMatch()
+            trBuilder = trBuilder
+                    .pushVlan(pushTagType.equals(PushTagTypeEnum.PUSHCTAG) ?
+                            EtherType.VLAN.ethType() : EtherType.QINQ.ethType())
+                    .setVlanId(pushVlanNum).transition(Integer.valueOf(0));
+
+        } else if (tm.getClass().equals(DefaultTagPop.class)) {
+            trBuilder = trBuilder.popVlan();
+
+        } else if (tm.getClass().equals(DefaultTagOverwrite.class)) {
+            TagOverwrite to = (TagOverwrite) tm;
+            VlanId ovrVlanNum = VlanId
+                    .vlanId((short) (
+                            //There are 2 classes TagOverwrite - the other one is already imported
+                            to
+                            .tagOverwrite()
+                            .outerTagVlan()
+                            .uint16()));
+            trBuilder = trBuilder.setVlanId(ovrVlanNum);
+
+        }
+
+        return trBuilder.build();
+    }
+
+    private static TagManipulation getTagManipulation(FlowRule fr) {
+        boolean isPop = false;
+        boolean isPush = false;
+        VlanId vlanId = null;
+        EthType ethType = EtherType.VLAN.ethType(); //Default
+        for (Instruction inst:fr.treatment().allInstructions()) {
+            if (inst.type() == Instruction.Type.L2MODIFICATION) {
+                L2ModificationInstruction l2Mod = (L2ModificationInstruction) inst;
+                if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_POP) {
+                    isPop = true;
+                } else if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_PUSH) {
+                    isPush = true;
+                    ethType = ((ModVlanHeaderInstruction) l2Mod).ethernetType();
+                } else if (l2Mod.subtype() == L2ModificationInstruction.L2SubType.VLAN_ID) {
+                    vlanId = ((ModVlanIdInstruction) l2Mod).vlanId();
+                }
+            }
+        }
+
+        if (isPop) {
+            //The should be no vlanId in this case
+            TagPop pop = new DefaultTagPop();
+            org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice
+                .evcperuniextensionattributes.tagmanipulation
+                .tagpop.TagPop popInner =
+                    new org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317
+                        .mseaunievcservice.evcperuniextensionattributes
+                        .tagmanipulation.tagpop.DefaultTagPop();
+            pop.tagPop(popInner);
+            return pop;
+
+        } else if (isPush && vlanId != null) {
+            TagPush push = new DefaultTagPush();
+            org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice
+                .evcperuniextensionattributes.tagmanipulation
+                .tagpush.TagPush pushInner =
+                    new org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317
+                        .mseaunievcservice.evcperuniextensionattributes
+                        .tagmanipulation.tagpush.DefaultTagPush();
+            pushInner.outerTagVlan(new VlanIdType(vlanId.id()));
+            pushInner.pushTagType(ethType.equals(EtherType.VLAN.ethType()) ?
+                                PushTagTypeEnum.PUSHCTAG : PushTagTypeEnum.PUSHSTAG);
+            push.tagPush(pushInner);
+            return push;
+
+        } else if (vlanId != null) { //This is overwrite, as it has vlanId, but not push or pop
+            TagOverwrite ovr = new DefaultTagOverwrite();
+            org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317.mseaunievcservice
+                .evcperuniextensionattributes.tagmanipulation
+                .tagoverwrite.TagOverwrite ovrInner =
+                    new org.onosproject.yang.gen.v1.mseaunievcservice.rev20160317
+                        .mseaunievcservice.evcperuniextensionattributes
+                        .tagmanipulation.tagoverwrite.DefaultTagOverwrite();
+            ovrInner.outerTagVlan(new VlanIdType(vlanId.id()));
+            ovr.tagOverwrite(ovrInner);
+            return ovr;
+        }
+
+        return null;
+    }
+
+    private static long getMeterId(TrafficTreatment treatment) {
+        return (treatment.metered() != null && treatment.metered().meterId() != null)
+                ? treatment.metered().meterId().id() : 0L;
+    }
+
+    /**
+     * An enumerated type that characterises the 2 port layout of the EA1000 device.
+     * The device is in an SFP package and has only 2 ports, the HOST port which
+     * plugs in to the chassis (Port 1) and the Optics Port on the rear (Port 0).
+     */
+    public enum Ea1000Port {
+        HOST(1),
+        OPTICS(0);
+
+        private int num = 0;
+        private Ea1000Port(int num) {
+            this.num = num;
+        }
+
+        /**
+         * The numerical assignment of this port.
+         * @return The port number
+         */
+        public int portNum() {
+            return num;
+        }
+
+        /**
+         * Return the enumerated value from a port number.
+         * @param num The port number
+         * @return An enumerated value
+         */
+        public static Ea1000Port fromNum(long num) {
+            for (Ea1000Port a:Ea1000Port.values()) {
+                if (a.num == num) {
+                    return a;
+                }
+            }
+            return HOST;
+        }
+
+        /**
+         * Get the port that the UNI-N is present on.
+         * @param side The assignment of UNI-side to port
+         * @return An enumerated value
+         */
+        public static Ea1000Port uniNNum(UniSideInterfaceAssignmentEnum side) {
+            if (side.equals(UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST)) {
+                return OPTICS;
+            } else {
+                return HOST;
+            }
+        }
+
+        /**
+         * Get the port that the UNI-C is present on.
+         * @param side The assignment of UNI-side to port
+         * @return An enumerated value
+         */
+        public static Ea1000Port uniCNum(UniSideInterfaceAssignmentEnum side) {
+            if (side.equals(UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST)) {
+                return HOST;
+            } else {
+                return OPTICS;
+            }
+        }
+
+        /**
+         * Get the port opposite the current port.
+         * @return An enumerated value for the opposite side
+         */
+        public Ea1000Port opposite() {
+            if (this.equals(HOST)) {
+                return OPTICS;
+            } else {
+                return HOST;
+            }
+        }
+
+        /**
+         * Evaluate which side of the UNI on the EA1000 device this port refers to.
+         * @param side The assignment of UNI-side to port
+         * @return An enumerated value representing the UniSide
+         */
+        public UniSide nOrC(UniSideInterfaceAssignmentEnum side) {
+            if ((this == HOST && side == UniSideInterfaceAssignmentEnum.UNI_C_ON_HOST) ||
+                    (this == OPTICS && side == UniSideInterfaceAssignmentEnum.UNI_C_ON_OPTICS)) {
+                return UniSide.CUSTOMER;
+            } else {
+                return UniSide.NETWORK;
+            }
+        }
+    }
+}
