Adding add/remove LTP/NI support, some refactoring and other minor changes

- Adding methods to selectively add/remove LTPs/NIs
- Adding refCount to NIs to better manage removals
- Adding CLI commands to add/remove LTPs/NIs
- Refactored some LTP and NI management methods
- Some changes in response to previous review comments
- Adding CLI command to indicate if topology is packet-optical
- Renaming ‘service' to ‘evc' in CLI commands
- For OVS support: Giving higher priority to fwd/next than filtering objectives

Change-Id: Icdba6534637dd979bde60b34e257d0a29b8ef430
diff --git a/ecord/carrierethernet/pom.xml b/ecord/carrierethernet/pom.xml
index 2771b7d..ed6defa 100644
--- a/ecord/carrierethernet/pom.xml
+++ b/ecord/carrierethernet/pom.xml
@@ -29,8 +29,6 @@
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <onos.version>1.7.0-SNAPSHOT</onos.version>
         <onos.app.name>org.onosproject.ecord.carrierethernet</onos.app.name>
-        <!-- TODO App dependency not working? -->
-        <onos.app.requires>org.onosproject.incubator.rpc,org.onosproject.incubator.rpc.grpc</onos.app.requires>
         <onos.app.origin>ON.Lab</onos.app.origin>
     </properties>
 
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java
index 3888f2d..5f6b11c 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetEnni.java
@@ -187,6 +187,7 @@
                 .add("id", this.id)
                 .add("cfgId", this.cfgId)
                 .add("role", role)
+                .add("refCount", refCount)
                 .add("sVlanIds", sVlanIdSet)
                 .add("capacity", this.capacity)
                 .add("usedCapacity", this.usedCapacity).toString();
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java
index b5d5ff3..3ea947d 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetInni.java
@@ -191,6 +191,7 @@
                 .add("id", this.id)
                 .add("cfgId", this.cfgId)
                 .add("role", role)
+                .add("refCount", refCount)
                 .add("sVlanIds", sVlanIdSet)
                 .add("capacity", this.capacity)
                 .add("usedCapacity", this.usedCapacity).toString();
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetLogicalTerminationPoint.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetLogicalTerminationPoint.java
index a94c885..aad7efb 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetLogicalTerminationPoint.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetLogicalTerminationPoint.java
@@ -17,6 +17,8 @@
 
 import org.onosproject.net.ConnectPoint;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 import static com.google.common.base.MoreObjects.toStringHelper;
 import static com.google.common.base.Preconditions.checkNotNull;
 
@@ -54,6 +56,33 @@
         UNI, INNI, ENNI
     }
 
+    /*public enum Type {
+
+        UNI("UNI"), INNI("INNI"), ENNI("ENNI");
+
+        private String value;
+
+        Type(String value) {
+            this.value = value;
+        }
+
+        @Override
+        public String toString() {
+            return value;
+        }
+
+        public static Type fromString(String value) {
+            if (value != null) {
+                for (Type b : Type.values()) {
+                    if (value.equals(b.value)) {
+                        return b;
+                    }
+                }
+            }
+            throw new IllegalArgumentException("Type " + value + " is not valid");
+        }
+    }*/
+
     protected String ltpId;
     protected String ltpCfgId;
     protected Type type;
@@ -64,7 +93,7 @@
     public CarrierEthernetLogicalTerminationPoint(String ltpCfgId, CarrierEthernetNetworkInterface ni) {
         checkNotNull(ni);
         this.ni = ni;
-        // NOTE: Role is expected to be null for service-specific LTPs/NIs
+        // NOTE: Role is expected to be null for global LTPs/NIs
         if (ni instanceof CarrierEthernetUni) {
             this.type = Type.UNI;
             this.role = (ni.role() == null ? null : Role.valueOf(((CarrierEthernetUni) ni).role().name()));
@@ -79,6 +108,21 @@
         this.ltpCfgId = (ltpCfgId == null ? this.ltpId : ltpCfgId);
     }
 
+    public CarrierEthernetLogicalTerminationPoint(ConnectPoint cp, String ltpCfgId,
+                                                  CarrierEthernetLogicalTerminationPoint.Type ltpType) {
+        this.type = ltpType;
+        this.ltpId = cp.deviceId().toString() + "/" + cp.port().toString();
+        this.ltpCfgId = (ltpCfgId == null ? this.ltpId : ltpCfgId);
+        // NOTE: Role is expected to be null for service-specific LTPs/NIs
+        if (ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.UNI)) {
+            this.ni = new CarrierEthernetUni(cp, ltpId, null, null, null);
+        } else if (ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.INNI)) {
+            this.ni = new CarrierEthernetInni(cp, ltpId, null, null, null, null);
+        } else {
+            this.ni = new CarrierEthernetEnni(cp, ltpId, null, null, null, null);
+        }
+    }
+
     /**
      * Returns associated connect point.
      *
@@ -142,6 +186,24 @@
         return this.ni().scope();
     }
 
+    /**
+     * Returns counter with the number of references (from EVCs/FCs) to the associated NI.
+     *
+     * @return number of references counter
+     */
+    public AtomicInteger refCount() {
+        return ni().refCount();
+    }
+
+    /**
+     * Sets the NI associated with the LTP.
+     *
+     * @param ni the NI to set
+     */
+    public void setNi(CarrierEthernetNetworkInterface ni) {
+        this.ni = ni;
+    }
+
     public String toString() {
 
         return toStringHelper(this)
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
index 43e29fa..e1002cb 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetManager.java
@@ -16,6 +16,7 @@
 package org.onosproject.ecord.carrierethernet.app;
 
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Reference;
@@ -99,7 +100,7 @@
     private static final int OPTICAL_CONNECT_TIMEOUT_MILLIS = 7000;
 
     // If set to false, the setup of optical connectivity using the metro app is bypassed
-    private static final boolean PACKET_OPTICAL_TOPO = false;
+    private boolean pktOpticalTopo = false;
 
     // TODO: Implement distributed store for EVCs
     // The installed EVCs
@@ -115,12 +116,15 @@
     // TODO: Implement distributed store for CE UNIs
     // The installed CE UNIs
     private final Map<String, CarrierEthernetUni> uniMap = new ConcurrentHashMap<>();
+    private final Set<String> removedUniSet = Sets.newConcurrentHashSet();;
 
     // Map of connect points and corresponding VLAN tag
     private Map<ConnectPoint, VlanId> portVlanMap = new ConcurrentHashMap<>();
     // TODO: Implement distributed store for CE LTPs
     // The installed CE LTPs
     private final Map<String, CarrierEthernetLogicalTerminationPoint> ltpMap = new ConcurrentHashMap<>();
+    // The LTP ids that have been explicitly removed (or requested to be removed) from the global LTP map
+    private final Set<String> removedLtpSet = Sets.newConcurrentHashSet();;
 
     /**
      * Activate this component.
@@ -186,20 +190,11 @@
     }
 
     /**
-     * Get the map containing all installed EVCs
-     *
-     * @return the EVC map
-     */
-    public Map<String, CarrierEthernetVirtualConnection> getEvcMap() {
-        return evcMap;
-    }
-
-    /**
      * Get the map containing all global LTPs
      *
      * @return the global LTP map
      */
-    public Map<String, CarrierEthernetLogicalTerminationPoint> getLtpMap() {
+    public Map<String, CarrierEthernetLogicalTerminationPoint> ltpMap() {
         return ltpMap;
     }
 
@@ -254,7 +249,7 @@
 
         Set<CarrierEthernetUni> validatedUniSet = new HashSet<>();
 
-        // Check the UNIs of the EVC, possibly removing UNIs that are incompatible with existing ones
+        // Check the UNIs of the EVC, possibly removing UNIs that are incompatible with existing global ones
         it = evc.uniSet().iterator();
         while (it.hasNext()) {
             CarrierEthernetUni uni = it.next();
@@ -262,7 +257,7 @@
             if (uni.bwp().type().equals(CarrierEthernetBandwidthProfile.Type.EVC)) {
                 uni.bwp().setId(evc.id());
             }
-            // Check first if UNI already exists by checking against the global UNI Map
+            // Check first if corresponding global UNI already exists by checking against the global UNI Map
             if (uniMap.keySet().contains(uni.id())) {
                 CarrierEthernetUni existingUni = uniMap.get(uni.id());
                 // Check if the EVC-specific UNI is compatible with the global one
@@ -361,7 +356,7 @@
 
                 OpticalConnectivityId opticalConnectId = null;
 
-                if (PACKET_OPTICAL_TOPO) {
+                if (pktOpticalTopo) {
                     opticalConnectId = setupOpticalConnectivity(uni1.cp(), uni2.cp(), uni1.bwp().cir(), evc.latency());
 
                     if (opticalConnectId == null ||
@@ -410,6 +405,9 @@
             uniIt1.remove();
         }
 
+        // Increment the global UNI reference count
+        usedUniSet.forEach(uni -> uniMap.get(uni.id()).refCount().incrementAndGet());
+
         // Update the EVC UNI set, based on the UNIs actually used
         evc.setUniSet(usedUniSet);
 
@@ -450,7 +448,7 @@
     }
 
     /**
-     * Applies bandwidth profiles to the UNIs of an EVC and adds them if needed to the global UNI map.
+     * Applies bandwidth profiles to the UNIs of an EVC and if needed adds the UNIs to the global UNI map.
      *
      * @param  uniSet set of UNIs that are included in the EVC
      */
@@ -462,11 +460,9 @@
                 uniMap.put(uni.id(), uni);
             } else {
                 // Add UNI resources (BWP, CE-VLAN ID) to existing global UNI
-                CarrierEthernetUni newUni = uniMap.get(uni.id());
-                newUni.addEvcUni(uni);
+                uniMap.get(uni.id()).addEvcUni(uni);
                 // Update config identifier
-                newUni.setCfgId(uni.cfgId());
-                uniMap.put(uni.id(), newUni);
+                uniMap.get(uni.id()).setCfgId(uni.cfgId());
             }
         });
     }
@@ -483,9 +479,6 @@
             cePktProvisioner.removeBandwidthProfiles(evcMap.get(evcId));
 
             // Remove UNI resources (BWP, CE-VLAN ID) from global UNI
-            /*CarrierEthernetUni newUni = uniMap.get(uni.id());
-            newUni.removeEvcUni(uni);
-            uniMap.put(uni.id(), newUni);*/
             uniMap.get(uni.id()).removeEvcUni(uni);
         });
     }
@@ -503,7 +496,10 @@
             removeOpticalConnectivity(evc.metroConnectivity().id());
             removeBandwidthProfiles(evcId);
             // Avoid excessively incrementing VLAN ids
-            nextVlanId = evc.vlanId().toShort();
+            nextVlanId = (evc.vlanId().toShort() < nextVlanId ? evc.vlanId().toShort() : nextVlanId);
+            // Decrement the global UNI and corresponding NI refCount
+            // FIXME: Remove this as soon as EVCs are always made of FCs
+            evc.uniSet().forEach(uni -> uniMap.get(uni.id()).refCount().decrementAndGet());
         });
         evcMap.clear();
     }
@@ -521,7 +517,10 @@
             removeOpticalConnectivity(evc.metroConnectivity().id());
             removeBandwidthProfiles(evcId);
             // Avoid excessively incrementing VLAN ids
-            nextVlanId = evc.vlanId().toShort();
+            nextVlanId = (evc.vlanId().toShort() < nextVlanId ? evc.vlanId().toShort() : nextVlanId);
+            // Decrement the global UNI and corresponding NI refCount
+            // FIXME: Remove this as soon as EVCs are always made of FCs
+            evc.uniSet().forEach(uni -> uniMap.get(uni.id()).refCount().decrementAndGet());
             evcMap.remove(evcId);
         }
     }
@@ -693,6 +692,9 @@
         });
         fc.setLtpSet(usedLtpSet);
 
+        // Increment the global LTP and corresponding NI refCount
+        usedLtpSet.forEach(ltp -> ltpMap.get(ltp.id()).refCount().incrementAndGet());
+
         // If no pair was connected, do not register the FC
         if (fc.state().equals(CarrierEthernetForwardingConstruct.State.ACTIVE)) {
             fcMap.put(fc.id(), fc);
@@ -750,7 +752,16 @@
      * */
     public void removeFc(String fcId) {
         if (fcMap.containsKey(fcId)) {
+            // FIXME: For now, UNI refCount will be updated in removeEvc()
             removeEvc(fcMap.get(fcId).evcLite().id());
+            // Decrement the global LTP and corresponding NI refCount
+            // FIXME: Remove the UNI constraint as soon as EVCs are always constructed of FCs
+            fcMap.get(fcId).ltpSet()
+                    .forEach(ltp -> {
+                        if (!(ltp.ni() instanceof CarrierEthernetUni)) {
+                            ltpMap.get(ltp.id()).refCount().decrementAndGet();
+                        }
+                    });
             fcMap.remove(fcId);
         }
     }
@@ -803,26 +814,84 @@
     }
 
     /**
-     * Returns all potential UNIs.
+     * Remove an LTP from the set of global LTPs.
      *
-     * @return set of all potential UNIs
+     *
+     * @param ltpId the id of the LTP to be removed
+     * @return the LTP that was removed or null in case of failure (didn't exist of refCount was not 0)
      * */
-    public Set<CarrierEthernetUni> getGlobalUnis() {
+    public CarrierEthernetLogicalTerminationPoint removeGlobalLtp(String ltpId) {
+
+        if (!ltpMap.containsKey(ltpId)) {
+            log.warn("Could not remove LTP {}: Does not exist", ltpId);
+            return null;
+        }
+
+        if (ltpMap.get(ltpId).refCount().get() != 0) {
+            log.warn("Could not remove LTP {}: RefCount is not zero", ltpId);
+            return null;
+        }
+
+        // Remove LTP from ltpMap and (if needed) UNI from uniMap
+        CarrierEthernetLogicalTerminationPoint ltp = ltpMap.remove(ltpId);
+        if (ltp.ni() instanceof CarrierEthernetUni) {
+            removeGlobalUni(ltp.ni().id());
+        }
+
+        // Add LTP to removed set
+        removedLtpSet.add(ltpId);
+
+        return ltp;
+    }
+
+    /**
+     * Remove an UNI from the set of global UNIs.
+     *
+     * @param uniId the id of the UNI to be removed
+     * @return the UNI that was removed or null in case of failure (didn't exist of refCount was not 0)
+     * */
+    public CarrierEthernetUni removeGlobalUni(String uniId) {
+
+        if (!uniMap.containsKey(uniId)) {
+            log.warn("Could not remove UNI {}: Does not exist", uniId);
+            return null;
+        }
+        if (uniMap.get(uniId).refCount().get() != 0) {
+            log.warn("Could not remove UNI {}: RefCount is not zero", uniId);
+            return null;
+        }
+
+        // Remove UNI from uniMap and corresponding LTP (if any) from ltpMp
+        CarrierEthernetUni uni = uniMap.remove(uniId);
+        // FIXME: For now, find LTP assuming ltpId is the same as uniId
+        // Note: If refCount for UNI is not zero, then it should be for the corresponding LTP as well
+        ltpMap.remove(uniId);
+
+        // Add UNI to removed set
+        removedUniSet.add(uniId);
+        removedLtpSet.add(uniId);
+
+        return uni;
+    }
+
+    /**
+     * Returns all potential UNIs from the topology.
+     *
+     * @return set of all potential UNIs in the topology
+     * */
+    public Set<CarrierEthernetUni> getUnisFromTopo() {
 
         CarrierEthernetUni uni;
         Set<CarrierEthernetUni> uniSet = new HashSet<>();
         // Generate the device ID/port number identifiers
         for (Device device : deviceService.getDevices()) {
             for (Port port : deviceService.getPorts(device.id())) {
-                // Consider only physical ports which are currently active
-                if (!port.number().isLogical() && port.isEnabled()) {
+                if (!port.number().isLogical()) {
                     String cpString = device.id().toString() + "/" + port.number();
                     ConnectPoint cp = ConnectPoint.deviceConnectPoint(cpString);
-                    // Add the UNI associated with generated connect point only if it doesn't belong to any link
-                    // and only if it belongs to a packet switch
-                    if (linkService.getEgressLinks(cp).isEmpty() && linkService.getIngressLinks(cp).isEmpty() &&
-                            device.type().equals(Device.Type.SWITCH)) {
-                        uni = new CarrierEthernetUni(cp, cpString, null, null, null);
+                    uni = generateUni(cp);
+                    // Check if LTP was generated and whether it's currently removed
+                    if (uni != null && !removedUniSet.contains(uni.id())) {
                         uniSet.add(uni);
                     }
                 }
@@ -832,48 +901,89 @@
     }
 
     /**
-     * Adds a set of potential UNIs to the global UNI map if they are not already there.
+     * Creates a new UNI associated with the provided connect point.
      *
-     * @param uniSet set of potential UNIs to add to global UNI map
+     * Conditions for validating an UNI:
+     * - ConnectPoint deviceId and Port are valid
+     * - Port is enabled
+     *
+     * @param cp the connect point to be associated with the generated UNI
+     * @return a new validated UNI or null if the validation failed
      * */
-    public void addGlobalUnis(Set<CarrierEthernetUni> uniSet) {
-        uniSet.forEach(uni -> {
-            // Add UNI only if it's not already there
-            if (!uniMap.containsKey(uni.id())) {
-                uniMap.put(uni.id(), uni);
-            }
-        });
+    public CarrierEthernetUni generateUni(ConnectPoint cp) {
+
+        String uniId = cp.deviceId().toString() + "/" + cp.port().toString();
+
+        if (deviceService.getDevice(cp.deviceId()) == null) {
+            log.error("Could not generate UNI {}: Invalid deviceId {}", uniId, cp.deviceId());
+            return null;
+        }
+        if (deviceService.getPort(cp.deviceId(), cp.port()) == null) {
+            log.error("Could not generate UNI {}: Invalid port {} at device {}", uniId, cp.port(), cp.deviceId());
+            return null;
+        }
+        if (!deviceService.getDevice(cp.deviceId()).type().equals(Device.Type.SWITCH)) {
+            log.error("Could not generate UNI {}: Device {} is not a switch", uniId, cp.deviceId());
+            return null;
+        }
+
+        Port port = deviceService.getPort(cp.deviceId(), cp.port());
+
+        if (!port.isEnabled())  {
+            log.warn("Could not generate UNI {}: Port {} is not enabled", uniId, port.number().toString());
+            return null;
+        }
+
+        if (validateLtpType(cp, CarrierEthernetLogicalTerminationPoint.Type.UNI) == null) {
+            return null;
+        }
+
+        return new CarrierEthernetUni(cp, uniId);
     }
 
     /**
-     * Returns all potential LTPs.
+     * Adds a potential UNI to the global UNI map if they are not already there.
      *
-     * @return set of all potential LTPs
+     * @param uni the potential UNI to add to global UNI map
+     * @return the UNI that was added or null if UNI existed already
      * */
-    public Set<CarrierEthernetLogicalTerminationPoint> getGlobalLtps() {
+    public CarrierEthernetUni addGlobalUni(CarrierEthernetUni uni) {
+        // Add UNI only if it's not already there. If corresponding LTP already exists, link them, otherwise create it
+        if (!uniMap.containsKey(uni.id())) {
+            // Add LTP only if it's not already there
+            // FIXME: Assumes LTP and UNI id are the same
+            if (!ltpMap.containsKey(uni.id())) {
+                ltpMap.put(uni.id(), new CarrierEthernetLogicalTerminationPoint(uni.id(), uni));
+            }
+            uniMap.put(uni.id(), uni);
+            return  uni;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns all potential LTPs from the topology.
+     *
+     * @return set of all potential LTPs in the topology
+     * */
+    public Set<CarrierEthernetLogicalTerminationPoint> getLtpsFromTopo() {
 
         CarrierEthernetLogicalTerminationPoint ltp;
-        CarrierEthernetUni uni;
-        CarrierEthernetInni inni;
         Set<CarrierEthernetLogicalTerminationPoint> ltpSet = new HashSet<>();
         // Generate the device ID/port number identifiers
         for (Device device : deviceService.getDevices()) {
             for (Port port : deviceService.getPorts(device.id())) {
-                // Consider only physical ports which are currently active
-                if (!port.number().isLogical() && port.isEnabled()) {
+                if (!port.number().isLogical()) {
                     String cpString = device.id().toString() + "/" + port.number();
                     ConnectPoint cp = ConnectPoint.deviceConnectPoint(cpString);
-                    // Add LTP associated with generated connect point only if it belongs to a packet switch
-                    if (device.type().equals(Device.Type.SWITCH)) {
-                        // Add a UNI associated with generated connect point only if it doesn't belong to any link
-                        if (linkService.getEgressLinks(cp).isEmpty() && linkService.getIngressLinks(cp).isEmpty()) {
-                            uni = new CarrierEthernetUni(cp, cpString, null, null, null);
-                            ltp = new CarrierEthernetLogicalTerminationPoint(cpString, uni);
-                        } else {
-                            inni = new CarrierEthernetInni(cp, cpString, null, null, null, null);
-                            ltp = new CarrierEthernetLogicalTerminationPoint(cpString, inni);
+                    ltp = generateLtp(cp, null);
+                    // Check if LTP was generated and whether it's currently removed
+                    if (ltp != null && !removedLtpSet.contains(ltp.id())) {
+                        // Check additionally if associated UNI is currently removed
+                        if (!(ltp.ni() instanceof CarrierEthernetUni) || !removedUniSet.contains(ltp.ni().id())) {
+                            ltpSet.add(ltp);
                         }
-                        ltpSet.add(ltp);
                     }
                 }
             }
@@ -882,23 +992,116 @@
     }
 
     /**
-     * Adds a set of potential LTPs and their UNIs to the global LTP/UNI maps if they are not already there.
+     * Creates a new LTP of the provided type and associated with the provided connect point.
      *
-     * @param ltpSet set of potential LTPs to add to global LTP map
+     * Conditions for validating an LTP:
+     * - ConnectPoint deviceId and Port are valid
+     * - Port is enabled
+     *
+     * @param cp the connect point to be associated with the generated LTP
+     * @param ltpType the type of the LTP to be generated (UNI/INNI/ENNI)
+     * @return a new validated LTP or null if the validation failed
      * */
-    public void addGlobalLtps(Set<CarrierEthernetLogicalTerminationPoint> ltpSet) {
-        ltpSet.forEach(ltp -> {
-            // Add LTP only if it's not already there
-            if (!ltpMap.containsKey(ltp.id())) {
-                ltpMap.put(ltp.id(), ltp);
+    public CarrierEthernetLogicalTerminationPoint generateLtp(ConnectPoint cp,
+                                                               CarrierEthernetLogicalTerminationPoint.Type ltpType) {
+
+        String ltpId = cp.deviceId().toString() + "/" + cp.port().toString();
+
+        if (deviceService.getDevice(cp.deviceId()) == null) {
+            log.error("Could not generate LTP {}: Invalid deviceId {}", ltpId, cp.deviceId());
+            return null;
+        }
+        if (deviceService.getPort(cp.deviceId(), cp.port()) == null) {
+            log.error("Could not generate LTP {}: Invalid port {} at device {}", ltpId, cp.port(), cp.deviceId());
+            return null;
+        }
+        if (!deviceService.getDevice(cp.deviceId()).type().equals(Device.Type.SWITCH)) {
+            log.error("Could not generate LTP {}: Device {} is not a switch", ltpId, cp.deviceId());
+            return null;
+        }
+
+        Port port = deviceService.getPort(cp.deviceId(), cp.port());
+
+        if (!port.isEnabled())  {
+            log.warn("Could not generate LTP {}: Port {} is not enabled", ltpId, port.number().toString());
+            return null;
+        }
+
+        ltpType = validateLtpType(cp, ltpType);
+
+        if (ltpType == null) {
+            log.warn("Could not generate LTP {}: Type could not be validated", ltpId, port.number().toString());
+            return null;
+        }
+
+        return new CarrierEthernetLogicalTerminationPoint(cp, ltpId, ltpType);
+    }
+
+    /**
+     * Validates whether the provided connect point can be associated with an LTP of the provided type.
+     *
+     * Conditions for validating the LTP type:
+     * - If UNI: ConnectPoint is not associated with any link
+     * - If INNI/ENNI: ConnectPoint is associated with a link
+     *
+     * @param cp the connect point associated with the LTP to be validated
+     * @param ltpType the type of the LTP to be validated or null in case a type is to be decided by the method
+     * @return the ltpType if validation succeeded, a new type depending on cp and topo, or null if validation failed
+     * */
+    private CarrierEthernetLogicalTerminationPoint.Type validateLtpType(
+            ConnectPoint cp, CarrierEthernetLogicalTerminationPoint.Type ltpType) {
+        if (linkService.getEgressLinks(cp).isEmpty() && linkService.getIngressLinks(cp).isEmpty()) {
+            // A connect point can be a UNI only if it doesn't belong to any link
+            if (ltpType == null) {
+                // If provided type is null, decide about the LTP type based on connectivity
+                return CarrierEthernetLogicalTerminationPoint.Type.UNI;
+            } else if (ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.UNI)) {
+                // Validate type
+                return ltpType;
+            } else {
+                return null;
             }
-            // If LTP contains a UNI, add it only if it's not already there
-            if (ltp.ni() != null && ltp.ni() instanceof CarrierEthernetUni) {
-                if (!uniMap.containsKey(ltp.ni().id())) {
-                    uniMap.put(ltp.ni().id(), (CarrierEthernetUni) ltp.ni());
-                }
+        } else {
+            // A connect point can be an INNI or ENNI only if it belongs to a link
+            if (ltpType == null) {
+                // If provided type is null, decide about the LTP type based on connectivity
+                return CarrierEthernetLogicalTerminationPoint.Type.INNI;
+            } else if (ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.INNI) ||
+                    ltpType.equals(CarrierEthernetLogicalTerminationPoint.Type.ENNI)) {
+                // Validate type
+                return ltpType;
+            } else {
+                return null;
             }
-        });
+        }
+    }
+
+    /**
+     * Adds a potential LTP and its UNI to the global LTP/UNI maps if it's not already there.
+     *
+     * @param ltp the potential LTP to add to global LTP map
+     * @return the LTP that was added or null if it already existed
+     * */
+    public CarrierEthernetLogicalTerminationPoint addGlobalLtp(CarrierEthernetLogicalTerminationPoint ltp) {
+        // If LTP contains a UNI, add it only if it's not already there, else point to the existing UNI
+        if (ltp.ni() != null && ltp.ni() instanceof CarrierEthernetUni) {
+            if (!uniMap.containsKey(ltp.ni().id())) {
+                uniMap.put(ltp.ni().id(), (CarrierEthernetUni) ltp.ni());
+            } else {
+                ltp.setNi(uniMap.get(ltp.ni().id()));
+            }
+        }
+        // Add LTP only if it's not already there
+        if (!ltpMap.containsKey(ltp.id())) {
+            ltpMap.put(ltp.id(), ltp);
+            return ltp;
+        } else {
+            return null;
+        }
+    }
+
+    public void setPktOpticalTopo(boolean pktOpticalTopo) {
+        this.pktOpticalTopo = pktOpticalTopo;
     }
 
     /**
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetNetworkInterface.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetNetworkInterface.java
index 1dbda7d..06ce3c0 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetNetworkInterface.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetNetworkInterface.java
@@ -24,6 +24,8 @@
 import org.slf4j.Logger;
 
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 import static com.google.common.base.MoreObjects.toStringHelper;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -47,6 +49,7 @@
     protected Bandwidth capacity;
     protected Bandwidth usedCapacity;
     protected Scope scope;
+    protected AtomicInteger refCount;
 
 
     public CarrierEthernetNetworkInterface(ConnectPoint connectPoint, String cfgId) {
@@ -58,6 +61,7 @@
                 .portSpeed());
         this.usedCapacity = Bandwidth.mbps((double) 0);
         this.scope = null;
+        this.refCount = new AtomicInteger();
     }
 
     /**
@@ -129,6 +133,15 @@
     }
 
     /**
+     * Returns counter with the number of references (from EVCs/FCs) to the particular NI.
+     *
+     * @return number of references counter
+     */
+    public AtomicInteger refCount() {
+        return refCount;
+    }
+
+    /**
      * Sets NI string identifier.
      *
      * @param id the UNI string identifier to set
@@ -156,10 +169,10 @@
     }
 
     /**
-     * Returns the NI type, depending on the NI.
+     * Returns the NI role, depending on the NI.
      *
-     * @param <T> the NI type
-     * @return the NI type
+     * @param <T> the NI role
+     * @return the NI role
      */
     public abstract <T> T role();
 
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java
index 8446d80..73368a2 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetOpenFlowPacketNodeManager.java
@@ -39,7 +39,16 @@
 import org.onosproject.openflow.controller.OpenFlowSwitch;
 import org.slf4j.Logger;
 
-import java.util.*;
+import java.util.Collection;
+import java.util.Objects;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Iterator;
+import java.util.ListIterator;
 
 import org.apache.commons.lang3.tuple.Pair;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -97,15 +106,23 @@
             return;
         }
 
-        if (flowObjectiveMap.get(evc.id()) == null) {
-            flowObjectiveMap.put(evc.id(), new LinkedList<>());
-        }
+        flowObjectiveMap.putIfAbsent(evc.id(), new LinkedList<>());
 
         // TODO: Get created FlowObjectives from this method
         createFlowObjectives(evc, srcNi, dstNi, ingress, egress, first, last);
     }
 
-    // Directly creates FlowRules using GROUP actions
+    /**
+     * Creates and submits FlowObjectives depending on the role of the device in the EVC and the types of srcNi/dstNi.
+     *
+     * @param evc the EVC representation
+     * @param srcNi the source network interface (UNI, INNI or ENNI) of the EVC for this forwarding segment
+     * @param dstNi the destination network interface (UNI, INNI or ENNI) of the EVC for this forwarding segment
+     * @param ingress the ingress connect point at the current device
+     * @param egress the egress connect point at the current device
+     * @param first is true if the current device is the first node in the end-to-end path
+     * @param last is true if the current device is the last node in the end-to-end path
+     */
     private void createFlowObjectives(CarrierEthernetVirtualConnection evc, CarrierEthernetNetworkInterface srcNi,
                                       CarrierEthernetNetworkInterface dstNi, ConnectPoint ingress, ConnectPoint egress,
                                       boolean first, boolean last) {
@@ -186,13 +203,15 @@
             }
         }
 
+        // Setting higher priority to fwd/next objectives to bypass filter in case of match conflict in OVS switches
+
         Integer nextId = flowObjectiveService.allocateNextId();
 
         NextObjective nextObjective = DefaultNextObjective.builder()
                 .fromApp(appId)
                 .makePermanent()
                 .withType(NextObjective.Type.SIMPLE)
-                .withPriority(PRIORITY)
+                .withPriority(PRIORITY + 1)
                 .withMeta(fwdSelector)
                 .addTreatment(nextTreatmentBuilder.build())
                 .withId(nextId)
@@ -202,7 +221,7 @@
                 .fromApp(appId)
                 .makePermanent()
                 .withFlag(ForwardingObjective.Flag.VERSATILE)
-                .withPriority(PRIORITY)
+                .withPriority(PRIORITY + 1)
                 .withSelector(fwdSelector)
                 .nextStep(nextId)
                 .add();
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java
index 38cd370..54a0ec8 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetPacketProvisioner.java
@@ -175,7 +175,7 @@
     }
 
     /**
-     * Removes bandwidth profiles from the UNIs of an ECV.
+     * Removes bandwidth profiles from the UNIs of an EVC.
      *
      * @param evc the EVC representation
      */
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java
index 2071c8f..de67b23 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/app/CarrierEthernetUni.java
@@ -24,7 +24,6 @@
 
 
 import static com.google.common.base.MoreObjects.toStringHelper;
-import static com.google.common.base.Preconditions.checkNotNull;
 import static org.slf4j.LoggerFactory.getLogger;
 
 import java.util.Collection;
@@ -60,8 +59,8 @@
         }
     }
 
-    protected Role role;
-    protected Set<VlanId> ceVlanIdSet;
+    protected Role role = null;
+    protected Set<VlanId> ceVlanIdSet = Sets.newConcurrentHashSet();;
 
     // Note: INTERFACE BWP map can only have up to one element
     protected final Map<CarrierEthernetBandwidthProfile.Type, Map<String, CarrierEthernetBandwidthProfile>> bwpMap =
@@ -69,13 +68,12 @@
 
     // TODO: May be needed to add refCount for CoS BWPs - only applicable to global UNIs
 
-    public CarrierEthernetUni(ConnectPoint connectPoint, String uniCfgId, Role role, VlanId ceVlanId,
+    public CarrierEthernetUni(ConnectPoint cp, String uniCfgId, Role role, VlanId ceVlanId,
                               CarrierEthernetBandwidthProfile bwp) {
-        super(connectPoint, uniCfgId);
+        super(cp, uniCfgId);
         this.role = role;
         // FIXME: Set the NI scope directly instead?
         this.scope = (role == null ? Scope.GLOBAL : Scope.SERVICE);
-        this.ceVlanIdSet = Sets.newConcurrentHashSet();
         if (ceVlanId != null) {
             this.ceVlanIdSet.add(ceVlanId);
         }
@@ -102,6 +100,14 @@
         }
     }
 
+    public CarrierEthernetUni(ConnectPoint cp, String uniCfgId) {
+        super(cp, uniCfgId);
+        this.scope = Scope.GLOBAL;
+        for (CarrierEthernetBandwidthProfile.Type bwpType : CarrierEthernetBandwidthProfile.Type.values()) {
+            this.bwpMap.put(bwpType, new HashMap<>());
+        }
+    }
+
     /**
      * Adds the resources associated with an EVC-specific UNI to a global UNI.
      *
@@ -283,6 +289,7 @@
                 .add("id", this.id)
                 .add("cfgId", this.cfgId)
                 .add("role", role)
+                .add("refCount", refCount)
                 .add("ceVlanIds", ceVlanIdSet)
                 .add("capacity", this.capacity)
                 .add("usedCapacity", this.usedCapacity)
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveServiceCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveServiceCommand.java
deleted file mode 100644
index fec19c7..0000000
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveServiceCommand.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2016 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.ecord.carrierethernet.cli;
-
-import org.apache.karaf.shell.commands.Argument;
-import org.apache.karaf.shell.commands.Command;
-import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
-import org.onosproject.cli.AbstractShellCommand;
-
-/**
- * CLI command for removing a specific installed CE service.
- */
-@Command(scope = "onos", name = "ce-service-remove",
-        description = "Carrier Ethernet service removal command.")
-public class CarrierEthernetRemoveServiceCommand extends AbstractShellCommand {
-
-    @Argument(index = 0, name = "argServiceId", description = "Service ID", required = true, multiValued = false)
-    String argServiceId = null;
-
-    @Override
-    protected void execute() {
-        CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
-        ceManager.removeEvc(argServiceId);
-    }
-}
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceIdCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceIdCompleter.java
deleted file mode 100644
index ca03154..0000000
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceIdCompleter.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2015 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.ecord.carrierethernet.cli;
-
-import org.apache.karaf.shell.console.Completer;
-import org.apache.karaf.shell.console.completer.StringsCompleter;
-import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
-import org.onosproject.cli.AbstractShellCommand;
-
-import java.util.List;
-import java.util.SortedSet;
-
-public class CarrierEthernetServiceIdCompleter implements Completer {
-    @Override
-    public int complete(String buffer, int cursor, List<String> candidates) {
-
-        StringsCompleter delegate = new StringsCompleter();
-        CarrierEthernetManager ceManager = AbstractShellCommand.get(CarrierEthernetManager.class);
-        SortedSet<String> strings = delegate.getStrings();
-        ceManager.evcMap().keySet().forEach(serviceId -> strings.add(serviceId));
-        return delegate.complete(buffer, cursor, candidates);
-    }
-}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetCreateServiceCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateEvcCommand.java
similarity index 77%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetCreateServiceCommand.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateEvcCommand.java
index 477d4c3..2292bff 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetCreateServiceCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateEvcCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import com.google.common.collect.Lists;
 import org.apache.karaf.shell.commands.Argument;
@@ -33,19 +33,19 @@
 import java.util.Set;
 
 /**
- * CLI command for generating CE services.
+ * CLI command for installing EVCs.
  */
-@Command(scope = "onos", name = "ce-service-create",
-         description = "Carrier Ethernet service creation command.")
-public class CarrierEthernetCreateServiceCommand extends AbstractShellCommand {
+@Command(scope = "onos", name = "ce-evc-create",
+         description = "Carrier Ethernet EVC creation command.")
+public class CarrierEthernetCreateEvcCommand extends AbstractShellCommand {
 
-    @Argument(index = 0, name = "argServiceCfgId",
-            description = "Service configuration ID", required = true, multiValued = false)
-    String argServiceCfgId = null;
-    @Argument(index = 1, name = "argServiceType", description =
-            "Service type (defaults to POINT_TO_POINT or MULTIPOINT_TO_MULTIPOINT, depending on number of UNIs)",
+    @Argument(index = 0, name = "argEvcCfgId",
+            description = "EVC configuration ID", required = true, multiValued = false)
+    String argEvcCfgId = null;
+    @Argument(index = 1, name = "argEvcType", description =
+            "EVC type (defaults to POINT_TO_POINT or MULTIPOINT_TO_MULTIPOINT, depending on number of UNIs)",
             required = false, multiValued = false)
-    String argServiceType = null;
+    String argEvcType = null;
     @Argument(index = 2, name = "argFirstUni", description =
             "First UNI in list (if point to multipoint, this is the root)", required = true, multiValued = false)
     String argFirstUni = null;
@@ -56,9 +56,9 @@
     @Option(name = "-v", aliases = "--cevlan", description = "CE-VLAN ID (applied to all UNIs)",
             required = false, multiValued = false)
     String argCeVlanId = null;
-    @Option(name = "-id", aliases = "--service-id", description = "The ID of a service to be updated" +
-            " (if service does not exist, a new service will be installed)", required = false, multiValued = false)
-    String argServiceId = null;
+    @Option(name = "-id", aliases = "--evc-id", description = "The ID of a evc to be updated" +
+            " (if evc does not exist, a new evc will be installed)", required = false, multiValued = false)
+    String argEvcId = null;
     @Option(name = "-u", aliases = "--maxNumUni", description = "The maximum number of UNIs in the EVC",
             required = false, multiValued = false)
     String argMaxNumUni = null;
@@ -78,34 +78,34 @@
 
         CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
 
-        CarrierEthernetVirtualConnection evc = new CarrierEthernetVirtualConnection(argServiceId, argServiceCfgId,
-                generateServiceType(), generateMaxNumUni(), generateUniSet());
+        CarrierEthernetVirtualConnection evc = new CarrierEthernetVirtualConnection(argEvcId, argEvcCfgId,
+                generateEvcType(), generateMaxNumUni(), generateUniSet());
 
         ceManager.establishConnectivity(evc);
     }
 
     /**
-     * Return the CE-VLAN ID for the CE service based on the CLI-supplied argument.
+     * Return the CE-VLAN ID for the CE evc based on the CLI-supplied argument.
      *
-     * @return CE-VLAN ID for the CE service
+     * @return CE-VLAN ID for the CE evc
      */
     VlanId generateCeVlanId() {
         return ((argCeVlanId == null) ? null : VlanId.vlanId(Short.parseShort(argCeVlanId)));
     }
 
     /**
-     * Return the CE service type based on the CLI-supplied arguments.
+     * Return the CE evc type based on the CLI-supplied arguments.
      *
-     * @return the CE service type
+     * @return the CE evc type
      */
-    CarrierEthernetVirtualConnection.Type generateServiceType() {
-        if (argServiceType == null) {
+    CarrierEthernetVirtualConnection.Type generateEvcType() {
+        if (argEvcType == null) {
             return ((argUniList.size() > 2) ?
                     CarrierEthernetVirtualConnection.Type.MULTIPOINT_TO_MULTIPOINT :
                     CarrierEthernetVirtualConnection.Type.POINT_TO_POINT);
         } else {
             // TODO: Catch exception
-            return CarrierEthernetVirtualConnection.Type.fromString(argServiceType);
+            return CarrierEthernetVirtualConnection.Type.fromString(argEvcType);
         }
     }
 
@@ -116,13 +116,13 @@
      */
     Integer generateMaxNumUni() {
         if (argMaxNumUni == null) {
-            if (argServiceType == null) {
+            if (argEvcType == null) {
                 return ((argUniList.size() > 2) ?
                         CarrierEthernetVirtualConnection.MAX_NUM_UNI : 2);
             } else {
                 // TODO: Catch exception
                 CarrierEthernetVirtualConnection.Type evcType =
-                        CarrierEthernetVirtualConnection.Type.fromString(argServiceType);
+                        CarrierEthernetVirtualConnection.Type.fromString(argEvcType);
                 return (evcType.equals(CarrierEthernetVirtualConnection.Type.POINT_TO_POINT) ? 2 :
                         CarrierEthernetVirtualConnection.MAX_NUM_UNI);
             }
@@ -150,19 +150,19 @@
      */
     String generateBandwidthProfileId(String uniId) {
         // TODO: Add the CoS BW profile case
-        return ((argCeVlanId == null) ? uniId : argServiceCfgId);
+        return ((argCeVlanId == null) ? uniId : argEvcCfgId);
     }
 
     /**
-     * Return the set of UNIs for the CE service based on the CLI-supplied arguments.
+     * Return the set of UNIs for the CE EVC based on the CLI-supplied arguments.
      *
-     * @return the set of UNIs for the CE service
+     * @return the set of UNIs for the CE EVC
      */
     Set<CarrierEthernetUni> generateUniSet() {
 
         Set<CarrierEthernetUni> uniSet = new HashSet<>();
 
-        CarrierEthernetVirtualConnection.Type serviceType = generateServiceType();
+        CarrierEthernetVirtualConnection.Type evcType = generateEvcType();
 
         // We assume that first UNI supplied is always root
         uniSet.add(new CarrierEthernetUni(ConnectPoint.deviceConnectPoint(argFirstUni), null,
@@ -179,7 +179,7 @@
 
         final CarrierEthernetUni.Role uniType;
         // For E-Line and E-LAN all UNIs are roots. For E-Tree all UNIs are leafs except from one
-        uniType = ((serviceType == CarrierEthernetVirtualConnection.Type.ROOT_MULTIPOINT) ?
+        uniType = ((evcType == CarrierEthernetVirtualConnection.Type.ROOT_MULTIPOINT) ?
                 CarrierEthernetUni.Role.LEAF : CarrierEthernetUni.Role.ROOT);
 
         argUniList.forEach(argUni -> uniSet.add(new CarrierEthernetUni(ConnectPoint.deviceConnectPoint(argUni), null,
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetCreateFcCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateFcCommand.java
similarity index 96%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetCreateFcCommand.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateFcCommand.java
index d6260e2..d9a7126 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetCreateFcCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateFcCommand.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import com.google.common.collect.Lists;
 import org.apache.karaf.shell.commands.Argument;
@@ -139,7 +139,7 @@
         CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
 
         // Update list of global LTPs in the network
-        ceManager.addGlobalLtps(ceManager.getGlobalLtps());
+        ceManager.getLtpsFromTopo().forEach(ltp -> ceManager.addGlobalLtp(ltp));
 
         Set<CarrierEthernetLogicalTerminationPoint> ltpSet = new HashSet<>();
 
@@ -163,7 +163,7 @@
 
         CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
 
-        if(ceManager.getLtpMap().get(ltpId).ni() instanceof CarrierEthernetUni) {
+        if(ceManager.ltpMap().get(ltpId).ni() instanceof CarrierEthernetUni) {
             return new CarrierEthernetUni(ConnectPoint.deviceConnectPoint(ltpId), null,
                     role, generateVlanId(argCeVlanId),
                     new CarrierEthernetBandwidthProfile(
@@ -175,7 +175,7 @@
                             Long.parseLong(argCbs),
                             Long.parseLong(argEbs)
                     ));
-        } else if(ceManager.getLtpMap().get(ltpId).ni() instanceof CarrierEthernetInni) {
+        } else if(ceManager.ltpMap().get(ltpId).ni() instanceof CarrierEthernetInni) {
             // FIXME: Use role properly
             return new CarrierEthernetInni(ConnectPoint.deviceConnectPoint(ltpId), null,
                     CarrierEthernetInni.Role.TRUNK, generateVlanId(argsTag), null, Bandwidth.bps((double) 0));
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateLtpCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateLtpCommand.java
new file mode 100644
index 0000000..7f74aa1
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateLtpCommand.java
@@ -0,0 +1,73 @@
+/*
+ * 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.ecord.carrierethernet.cli.commands;
+
+import com.google.common.collect.Lists;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.ecord.carrierethernet.app.*;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * CLI command for generating Carrier Ethernet Logical Termination Points.
+ */
+@Command(scope = "onos", name = "ce-ltp-create",
+        description = "Creates Carrier Ethernet Logical Termination Points.")
+public class CarrierEthernetCreateLtpCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "argLtpType", description =
+            "The LTP type to be generated (UNI/INNI/ENNI)." +
+                    " AUTO will choose the type based based on current topology", required = true, multiValued = false)
+    String argLtpType = null;
+    @Argument(index = 1, name = "argConnectPoint", description =
+            "The connect points in the topology to be associated with"
+                    + " the generated LTPs", required = true, multiValued = true)
+    List<String> argConnectPointList = Lists.newArrayList();
+
+
+    @Override
+    protected void execute() {
+
+        CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
+
+        CarrierEthernetLogicalTerminationPoint.Type ltpType = null;
+
+        if (!argLtpType.equals("AUTO")) {
+            try {
+                ltpType = CarrierEthernetLogicalTerminationPoint.Type.valueOf(argLtpType);
+            } catch (IllegalArgumentException e) {
+                log.error("{} is not a valid LTP type, skipping LTP generation.");
+                return;
+            }
+        }
+
+        Iterator<String> cpIt = argConnectPointList.iterator();
+        while (cpIt.hasNext()) {
+            String argConnectPoint = cpIt.next();
+            CarrierEthernetLogicalTerminationPoint ltp = ceManager
+                    .generateLtp(ConnectPoint.deviceConnectPoint(argConnectPoint), ltpType);
+            if (ltp != null) {
+                ceManager.addGlobalLtp(ltp);
+            }
+        }
+    }
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateUniCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateUniCommand.java
new file mode 100644
index 0000000..ea02b81
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetCreateUniCommand.java
@@ -0,0 +1,55 @@
+/*
+ * 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.ecord.carrierethernet.cli.commands;
+
+import com.google.common.collect.Lists;
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.ecord.carrierethernet.app.*;
+import org.onosproject.net.ConnectPoint;
+
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * CLI command for generating Carrier Ethernet UNIs.
+ */
+@Command(scope = "onos", name = "ce-uni-create",
+        description = "Creates Carrier Ethernet UNIs.")
+public class CarrierEthernetCreateUniCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "argConnectPoint", description =
+            "The connect points in the topology to be associated with the"
+                    + " created UNIs", required = true, multiValued = true)
+    List<String> argConnectPointList = Lists.newArrayList();
+
+
+    @Override
+    protected void execute() {
+
+        CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
+
+        Iterator<String> cpIt = argConnectPointList.iterator();
+        while (cpIt.hasNext()) {
+            String argConnectPoint = cpIt.next();
+            CarrierEthernetUni uni = ceManager.generateUni(ConnectPoint.deviceConnectPoint(argConnectPoint));
+            if (uni != null) {
+                ceManager.addGlobalUni(uni);
+            }
+        }
+    }
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListServicesCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListEvcsCommand.java
similarity index 80%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListServicesCommand.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListEvcsCommand.java
index 9a697e4..ee1148f 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListServicesCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListEvcsCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
@@ -25,9 +25,9 @@
 /**
  * CLI command for listing all installed CE services.
  */
-@Command(scope = "onos", name = "ce-service-list",
-        description = "Lists all Carrier Ethernet services.")
-public class CarrierEthernetListServicesCommand extends AbstractShellCommand {
+@Command(scope = "onos", name = "ce-evc-list",
+        description = "Lists all installed EVCs.")
+public class CarrierEthernetListEvcsCommand extends AbstractShellCommand {
 
     @Override
     protected void execute() {
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListFcsCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListFcsCommand.java
similarity index 95%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListFcsCommand.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListFcsCommand.java
index 3e60c5b..af09013 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListFcsCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListFcsCommand.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListLtpsCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListLtpsCommand.java
similarity index 80%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListLtpsCommand.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListLtpsCommand.java
index 983e3cb..0188437 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListLtpsCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListLtpsCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetLogicalTerminationPoint;
@@ -31,10 +31,10 @@
 
     @Override
     protected void execute() {
-        CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
+        CarrierEthernetManager evcManager = get(CarrierEthernetManager.class);
         // Populate global LTP map
-        ceManager.addGlobalLtps(ceManager.getGlobalLtps());
-        printLtps(ceManager.getLtpMap().values());
+        evcManager.getLtpsFromTopo().forEach(ltp -> evcManager.addGlobalLtp(ltp));
+        printLtps(evcManager.ltpMap().values());
     }
 
     private void printLtps(Collection<CarrierEthernetLogicalTerminationPoint> ltps) {
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListUnisCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListUnisCommand.java
similarity index 87%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListUnisCommand.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListUnisCommand.java
index 3a4f409..98e600f 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetListUnisCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetListUnisCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
@@ -33,7 +33,7 @@
     protected void execute() {
         CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
         // Populate global UNI map
-        ceManager.addGlobalUnis(ceManager.getGlobalUnis());
+        ceManager.getUnisFromTopo().forEach(uni -> ceManager.addGlobalUni(uni));
         printUnis(ceManager.getUniMap().values());
     }
 
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java
similarity index 64%
copy from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
copy to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java
index 7bedc36..7b4cb86 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetPktOpticalTopoCommand.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
@@ -21,18 +21,19 @@
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
 
 /**
- * CLI command for removing an installed Carrier Ethernet Forwarding Construct.
+ * CLI command for indicating whether CE app controls a packet optical topology.
  */
-@Command(scope = "onos", name = "ce-fc-remove",
+@Command(scope = "onos", name = "ce-pkt-optical-topo",
         description = "Carrier Ethernet service removal command.")
-public class CarrierEthernetRemoveFcCommand extends AbstractShellCommand {
+public class CarrierEthernetPktOpticalTopoCommand extends AbstractShellCommand {
 
-    @Argument(index = 0, name = "argFcId", description = "Forwarding Construct ID", required = true, multiValued = false)
-    String argFcId = null;
+    @Argument(index = 0, name = "pktOptTopoArg", description = "Set to true if CE app " +
+            "controls a packet optical topology", required = true, multiValued = false)
+    String pktOptTopoArg = null;
 
     @Override
     protected void execute() {
         CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
-        ceManager.removeFc(argFcId);
+        ceManager.setPktOpticalTopo(Boolean.parseBoolean(pktOptTopoArg));
     }
 }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveAllServicesCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveAllEvcsCommand.java
similarity index 75%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveAllServicesCommand.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveAllEvcsCommand.java
index 8d047e1..21b3196 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveAllServicesCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveAllEvcsCommand.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
@@ -22,9 +22,9 @@
 /**
  * CLI command for removing all installed CE services.
  */
-@Command(scope = "onos", name = "ce-service-remove-all",
-        description = "Carrier Ethernet all services removal.")
-public class CarrierEthernetRemoveAllServicesCommand extends AbstractShellCommand {
+@Command(scope = "onos", name = "ce-evc-remove-all",
+        description = "Carrier Ethernet all EVCs removal.")
+public class CarrierEthernetRemoveAllEvcsCommand extends AbstractShellCommand {
 
     @Override
     protected void execute() {
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveAllFcsCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveAllFcsCommand.java
similarity index 95%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveAllFcsCommand.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveAllFcsCommand.java
index 09ebb8f..2cfcd55 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveAllFcsCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveAllFcsCommand.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveEvcCommand.java
similarity index 60%
copy from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
copy to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveEvcCommand.java
index 7bedc36..b17afb2 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveEvcCommand.java
@@ -13,26 +13,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
+import com.google.common.collect.Lists;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
-import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.cli.AbstractShellCommand;
+
+import java.util.List;
 
 /**
- * CLI command for removing an installed Carrier Ethernet Forwarding Construct.
+ * CLI command for removing installed EVCs.
  */
-@Command(scope = "onos", name = "ce-fc-remove",
-        description = "Carrier Ethernet service removal command.")
-public class CarrierEthernetRemoveFcCommand extends AbstractShellCommand {
+@Command(scope = "onos", name = "ce-evc-remove",
+        description = "Carrier Ethernet EVC removal command.")
+public class CarrierEthernetRemoveEvcCommand extends AbstractShellCommand {
 
-    @Argument(index = 0, name = "argFcId", description = "Forwarding Construct ID", required = true, multiValued = false)
-    String argFcId = null;
+    @Argument(index = 0, name = "argEvcIdList", description = "EVC IDs "
+            + " to be removed", required = true, multiValued = true)
+    List<String> argEvcIdList = Lists.newArrayList();
 
     @Override
     protected void execute() {
         CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
-        ceManager.removeFc(argFcId);
+        argEvcIdList.forEach(argEvcId -> ceManager.removeEvc(argEvcId));
     }
-}
+}
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveFcCommand.java
similarity index 95%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveFcCommand.java
index 7bedc36..873925d 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveFcCommand.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveLtpCommand.java
similarity index 60%
copy from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
copy to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveLtpCommand.java
index 7bedc36..dc84ef5 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveLtpCommand.java
@@ -13,26 +13,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
+import com.google.common.collect.Lists;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
-import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.cli.AbstractShellCommand;
+
+import java.util.List;
 
 /**
- * CLI command for removing an installed Carrier Ethernet Forwarding Construct.
+ * CLI command for removing LTPs.
  */
-@Command(scope = "onos", name = "ce-fc-remove",
-        description = "Carrier Ethernet service removal command.")
-public class CarrierEthernetRemoveFcCommand extends AbstractShellCommand {
+@Command(scope = "onos", name = "ce-ltp-remove",
+        description = "Carrier Ethernet LTP removal command.")
+public class CarrierEthernetRemoveLtpCommand extends AbstractShellCommand {
 
-    @Argument(index = 0, name = "argFcId", description = "Forwarding Construct ID", required = true, multiValued = false)
-    String argFcId = null;
+    @Argument(index = 0, name = "argLtpIdList", description = "LTP IDs"
+            + " to be removed", required = true, multiValued = true)
+    List<String> argLtpIdList = Lists.newArrayList();
 
     @Override
     protected void execute() {
         CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
-        ceManager.removeFc(argFcId);
+        argLtpIdList.forEach(argLtpId -> ceManager.removeGlobalLtp(argLtpId));
     }
-}
+}
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveUniCommand.java
similarity index 60%
copy from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
copy to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveUniCommand.java
index 7bedc36..701a447 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetRemoveFcCommand.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/CarrierEthernetRemoveUniCommand.java
@@ -13,26 +13,30 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.commands;
 
+import com.google.common.collect.Lists;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
-import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.cli.AbstractShellCommand;
+
+import java.util.List;
 
 /**
- * CLI command for removing an installed Carrier Ethernet Forwarding Construct.
+ * CLI command for removing UNIs.
  */
-@Command(scope = "onos", name = "ce-fc-remove",
-        description = "Carrier Ethernet service removal command.")
-public class CarrierEthernetRemoveFcCommand extends AbstractShellCommand {
+@Command(scope = "onos", name = "ce-uni-remove",
+        description = "Carrier Ethernet UNI removal command.")
+public class CarrierEthernetRemoveUniCommand extends AbstractShellCommand {
 
-    @Argument(index = 0, name = "argFcId", description = "Forwarding Construct ID", required = true, multiValued = false)
-    String argFcId = null;
+    @Argument(index = 0, name = "argUniIdList", description = "UNI IDs"
+            + " to be removed", required = true, multiValued = true)
+    List<String> argUniIdList = Lists.newArrayList();
 
     @Override
     protected void execute() {
         CarrierEthernetManager ceManager = get(CarrierEthernetManager.class);
-        ceManager.removeFc(argFcId);
+        argUniIdList.forEach(argUniId -> ceManager.removeGlobalUni(argUniId));
     }
-}
+}
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/package-info.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/package-info.java
new file mode 100644
index 0000000..3590035
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/commands/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Command classes for the Carrier Ethernet app CLI.
+ */
+package org.onosproject.ecord.carrierethernet.cli.commands;
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetBooleanCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetBooleanCompleter.java
new file mode 100644
index 0000000..f64c866
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetBooleanCompleter.java
@@ -0,0 +1,35 @@
+/*
+ * 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.ecord.carrierethernet.cli.completers;
+
+import com.google.common.collect.ImmutableList;
+import org.onosproject.cli.AbstractChoicesCompleter;
+
+import java.util.List;
+
+/**
+ * Boolean command completer.
+ */
+public class CarrierEthernetBooleanCompleter extends AbstractChoicesCompleter {
+
+    public static final String TRUE = "true";
+    public static final String FALSE = "false";
+
+    @Override
+    public List<String> choices() {
+        return ImmutableList.of(TRUE, FALSE);
+    }
+}
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetConnectPointCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetConnectPointCompleter.java
new file mode 100644
index 0000000..84873b7
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetConnectPointCompleter.java
@@ -0,0 +1,57 @@
+/*
+ * 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.ecord.carrierethernet.cli.completers;
+
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.cli.AbstractCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetLogicalTerminationPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.Port;
+import org.onosproject.net.device.DeviceService;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.SortedSet;
+
+/**
+ * Unique ConnectPoint completer.
+ */
+public class CarrierEthernetConnectPointCompleter extends AbstractCompleter {
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+
+        StringsCompleter delegate = new UniqueStringsCompleter();
+        SortedSet<String> strings = delegate.getStrings();
+
+        DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);
+
+        CarrierEthernetLogicalTerminationPoint ltp;
+        Set<CarrierEthernetLogicalTerminationPoint> ltpSet = new HashSet<>();
+        // Generate the device ID/port number identifiers
+        for (Device device : deviceService.getDevices()) {
+            for (Port port : deviceService.getPorts(device.id())) {
+                if (!port.number().isLogical()) {
+                    strings.add(device.id().toString() + "/" + port.number());
+                }
+            }
+        }
+
+        return delegate.complete(buffer, cursor, candidates);
+    }
+
+}
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetEvcCompleter.java
similarity index 81%
copy from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
copy to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetEvcCompleter.java
index 198e213..155357e 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetEvcCompleter.java
@@ -13,30 +13,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.completers;
 
+import org.apache.karaf.shell.console.Completer;
 import org.apache.karaf.shell.console.completer.StringsCompleter;
-import org.onosproject.cli.AbstractCompleter;
-import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.cli.AbstractShellCommand;
 
 import java.util.List;
 import java.util.SortedSet;
 
-/**
- * LTP ConnectPoint completer.
- */
-public class CarrierEthernetLtpCompleter extends AbstractCompleter {
+public class CarrierEthernetEvcCompleter implements Completer {
     @Override
     public int complete(String buffer, int cursor, List<String> candidates) {
 
         StringsCompleter delegate = new UniqueStringsCompleter();
-        SortedSet<String> strings = delegate.getStrings();
-
         CarrierEthernetManager ceManager = AbstractShellCommand.get(CarrierEthernetManager.class);
-        ceManager.getGlobalLtps().forEach(ltp -> strings.add(ltp.id()));
-
+        SortedSet<String> strings = delegate.getStrings();
+        ceManager.evcMap().keySet().forEach(evcId -> strings.add(evcId));
         return delegate.complete(buffer, cursor, candidates);
     }
-
 }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceTypeCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetEvcTypeCompleter.java
similarity index 86%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceTypeCompleter.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetEvcTypeCompleter.java
index e97617a..f5bdd98 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceTypeCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetEvcTypeCompleter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.completers;
 
 import org.apache.karaf.shell.console.Completer;
 import org.apache.karaf.shell.console.completer.StringsCompleter;
@@ -22,7 +22,7 @@
 import java.util.List;
 import java.util.SortedSet;
 
-public class CarrierEthernetServiceTypeCompleter implements Completer {
+public class CarrierEthernetEvcTypeCompleter implements Completer {
     @Override
     public int complete(String buffer, int cursor, List<String> candidates) {
 
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetFcCompleter.java
similarity index 81%
copy from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
copy to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetFcCompleter.java
index 198e213..ba8a7d4 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetFcCompleter.java
@@ -13,30 +13,24 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.completers;
 
+import org.apache.karaf.shell.console.Completer;
 import org.apache.karaf.shell.console.completer.StringsCompleter;
-import org.onosproject.cli.AbstractCompleter;
-import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.ecord.carrierethernet.app.CarrierEthernetManager;
+import org.onosproject.cli.AbstractShellCommand;
 
 import java.util.List;
 import java.util.SortedSet;
 
-/**
- * LTP ConnectPoint completer.
- */
-public class CarrierEthernetLtpCompleter extends AbstractCompleter {
+public class CarrierEthernetFcCompleter implements Completer {
     @Override
     public int complete(String buffer, int cursor, List<String> candidates) {
 
         StringsCompleter delegate = new UniqueStringsCompleter();
-        SortedSet<String> strings = delegate.getStrings();
-
         CarrierEthernetManager ceManager = AbstractShellCommand.get(CarrierEthernetManager.class);
-        ceManager.getGlobalLtps().forEach(ltp -> strings.add(ltp.id()));
-
+        SortedSet<String> strings = delegate.getStrings();
+        ceManager.fcMap().keySet().forEach(fcId -> strings.add(fcId));
         return delegate.complete(buffer, cursor, candidates);
     }
-
 }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpCompleter.java
similarity index 89%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpCompleter.java
index 198e213..79d5de5 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpCompleter.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.completers;
 
 import org.apache.karaf.shell.console.completer.StringsCompleter;
 import org.onosproject.cli.AbstractCompleter;
@@ -24,7 +24,7 @@
 import java.util.SortedSet;
 
 /**
- * LTP ConnectPoint completer.
+ * LTP ID completer.
  */
 public class CarrierEthernetLtpCompleter extends AbstractCompleter {
     @Override
@@ -34,7 +34,7 @@
         SortedSet<String> strings = delegate.getStrings();
 
         CarrierEthernetManager ceManager = AbstractShellCommand.get(CarrierEthernetManager.class);
-        ceManager.getGlobalLtps().forEach(ltp -> strings.add(ltp.id()));
+        ceManager.ltpMap().keySet().forEach(ltpId -> strings.add(ltpId));
 
         return delegate.complete(buffer, cursor, candidates);
     }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceTypeCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpTypeCompleter.java
similarity index 75%
copy from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceTypeCompleter.java
copy to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpTypeCompleter.java
index e97617a..d46a2cb 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetServiceTypeCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetLtpTypeCompleter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2015 Open Networking Laboratory
+ * 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.
@@ -13,16 +13,16 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.completers;
 
 import org.apache.karaf.shell.console.Completer;
 import org.apache.karaf.shell.console.completer.StringsCompleter;
-import org.onosproject.ecord.carrierethernet.app.CarrierEthernetVirtualConnection;
+import org.onosproject.ecord.carrierethernet.app.CarrierEthernetLogicalTerminationPoint;
 
 import java.util.List;
 import java.util.SortedSet;
 
-public class CarrierEthernetServiceTypeCompleter implements Completer {
+public class CarrierEthernetLtpTypeCompleter implements Completer {
     @Override
     public int complete(String buffer, int cursor, List<String> candidates) {
 
@@ -30,9 +30,10 @@
 
         SortedSet<String> strings = delegate.getStrings();
 
-        for (CarrierEthernetVirtualConnection.Type type : CarrierEthernetVirtualConnection.Type.values()) {
+        for (CarrierEthernetLogicalTerminationPoint.Type type : CarrierEthernetLogicalTerminationPoint.Type.values()) {
             strings.add(type.toString());
         }
+        strings.add("AUTO");
 
         return delegate.complete(buffer, cursor, candidates);
     }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetPotentialLtpCompleter.java
similarity index 83%
copy from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
copy to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetPotentialLtpCompleter.java
index 198e213..3e1b62f 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetPotentialLtpCompleter.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.completers;
 
 import org.apache.karaf.shell.console.completer.StringsCompleter;
 import org.onosproject.cli.AbstractCompleter;
@@ -24,9 +24,9 @@
 import java.util.SortedSet;
 
 /**
- * LTP ConnectPoint completer.
+ * Potential LTP ConnectPoint completer.
  */
-public class CarrierEthernetLtpCompleter extends AbstractCompleter {
+public class CarrierEthernetPotentialLtpCompleter extends AbstractCompleter {
     @Override
     public int complete(String buffer, int cursor, List<String> candidates) {
 
@@ -34,7 +34,7 @@
         SortedSet<String> strings = delegate.getStrings();
 
         CarrierEthernetManager ceManager = AbstractShellCommand.get(CarrierEthernetManager.class);
-        ceManager.getGlobalLtps().forEach(ltp -> strings.add(ltp.id()));
+        ceManager.getLtpsFromTopo().forEach(ltp -> strings.add(ltp.id()));
 
         return delegate.complete(buffer, cursor, candidates);
     }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetPotentialUniCompleter.java
similarity index 83%
copy from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
copy to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetPotentialUniCompleter.java
index 198e213..7a1e3e1 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetLtpCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetPotentialUniCompleter.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.completers;
 
 import org.apache.karaf.shell.console.completer.StringsCompleter;
 import org.onosproject.cli.AbstractCompleter;
@@ -24,9 +24,10 @@
 import java.util.SortedSet;
 
 /**
- * LTP ConnectPoint completer.
+ * Potential UNI ConnectPoint completer.
  */
-public class CarrierEthernetLtpCompleter extends AbstractCompleter {
+public class CarrierEthernetPotentialUniCompleter extends AbstractCompleter {
+
     @Override
     public int complete(String buffer, int cursor, List<String> candidates) {
 
@@ -34,7 +35,7 @@
         SortedSet<String> strings = delegate.getStrings();
 
         CarrierEthernetManager ceManager = AbstractShellCommand.get(CarrierEthernetManager.class);
-        ceManager.getGlobalLtps().forEach(ltp -> strings.add(ltp.id()));
+        ceManager.getUnisFromTopo().forEach(uni -> strings.add(uni.id()));
 
         return delegate.complete(buffer, cursor, candidates);
     }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetUniCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetUniCompleter.java
similarity index 85%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetUniCompleter.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetUniCompleter.java
index daca6b6..15f446c 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/CarrierEthernetUniCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/CarrierEthernetUniCompleter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.completers;
 
 import org.apache.karaf.shell.console.completer.StringsCompleter;
 import org.onosproject.cli.AbstractCompleter;
@@ -24,7 +24,7 @@
 import java.util.SortedSet;
 
 /**
- * UNI ConnectPoint completer.
+ * UNI ID completer.
  */
 public class CarrierEthernetUniCompleter extends AbstractCompleter {
 
@@ -35,7 +35,7 @@
         SortedSet<String> strings = delegate.getStrings();
 
         CarrierEthernetManager ceManager = AbstractShellCommand.get(CarrierEthernetManager.class);
-        ceManager.getGlobalUnis().forEach(uni -> strings.add(uni.id()));
+        ceManager.getUniMap().keySet().forEach(uniId -> strings.add(uniId));
 
         return delegate.complete(buffer, cursor, candidates);
     }
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/UniqueStringsCompleter.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/UniqueStringsCompleter.java
similarity index 96%
rename from ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/UniqueStringsCompleter.java
rename to ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/UniqueStringsCompleter.java
index 6522c71..038b13a 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/UniqueStringsCompleter.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/UniqueStringsCompleter.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.ecord.carrierethernet.cli;
+package org.onosproject.ecord.carrierethernet.cli.completers;
 
 import org.apache.felix.service.command.CommandSession;
 import org.apache.karaf.shell.console.CommandSessionHolder;
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/package-info.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/package-info.java
new file mode 100644
index 0000000..5ceee89
--- /dev/null
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/completers/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+/**
+ * Completer classes for the Carrier Ethernet app CLI.
+ */
+package org.onosproject.ecord.carrierethernet.cli.completers;
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/package-info.java b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/package-info.java
index 32e8e79..61562c5 100644
--- a/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/package-info.java
+++ b/ecord/carrierethernet/src/main/java/org/onosproject/ecord/carrierethernet/cli/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2016 Open Networking Laboratory
+ * 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.
@@ -15,6 +15,6 @@
  */
 
 /**
- * CLI implementation for requesting carrier ethernet services.
+ * CLI implementation for the Carrier Ethernet Application.
  */
 package org.onosproject.ecord.carrierethernet.cli;
\ No newline at end of file
diff --git a/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index fe9e145..1643486 100644
--- a/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/ecord/carrierethernet/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -1,5 +1,5 @@
 <!--
-  ~ Copyright 2016 Open Networking Laboratory
+  ~ 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.
@@ -17,23 +17,105 @@
 
     <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetCreateServiceCommand"/>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetCreateEvcCommand"/>
             <completers>
                 <ref component-id="placeholderCompleter"/>
-                <ref component-id="carrierEthernetServiceTypeCompleter"/>
-                <ref component-id="carrierEthernetUniCompleter"/>
-                <ref component-id="carrierEthernetUniCompleter"/>
+                <ref component-id="carrierEthernetEvcTypeCompleter"/>
+                <ref component-id="carrierEthernetPotentialUniCompleter"/>
+                <ref component-id="carrierEthernetPotentialUniCompleter"/>
             </completers>
         </command>
     </command-bundle>
 
     <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetCreateFcCommand"/>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetCreateFcCommand"/>
             <completers>
                 <ref component-id="placeholderCompleter"/>
-                <ref component-id="carrierEthernetServiceTypeCompleter"/>
-                <ref component-id="carrierEthernetLtpCompleter"/>
+                <ref component-id="carrierEthernetEvcTypeCompleter"/>
+                <ref component-id="carrierEthernetPotentialLtpCompleter"/>
+                <ref component-id="carrierEthernetPotentialLtpCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveEvcCommand"/>
+            <completers>
+                <ref component-id="carrierEthernetEvcCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveAllEvcsCommand"/>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetListEvcsCommand"/>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetListLtpsCommand"/>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetListUnisCommand"/>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetListFcsCommand"/>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveFcCommand"/>
+            <completers>
+                <ref component-id="carrierEthernetFcCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveAllFcsCommand"/>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetCreateLtpCommand"/>
+            <completers>
+                <ref component-id="carrierEthernetLtpTypeCompleter"/>
+                <ref component-id="carrierEthernetConnectPointCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetCreateUniCommand"/>
+            <completers>
+                <ref component-id="carrierEthernetConnectPointCompleter"/>
+            </completers>
+        </command>
+    </command-bundle>
+
+    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+        <command>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveLtpCommand"/>
+            <completers>
                 <ref component-id="carrierEthernetLtpCompleter"/>
             </completers>
         </command>
@@ -41,63 +123,34 @@
 
     <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetRemoveServiceCommand"/>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetRemoveUniCommand"/>
             <completers>
-                <ref component-id="carrierEthernetServiceIdCompleter"/>
+                <ref component-id="carrierEthernetUniCompleter"/>
             </completers>
         </command>
     </command-bundle>
 
     <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
         <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetRemoveAllServicesCommand"/>
-        </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
-        <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetListServicesCommand"/>
-        </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
-        <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetListLtpsCommand"/>
-        </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
-        <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetListUnisCommand"/>
-        </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
-        <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetListFcsCommand"/>
-        </command>
-    </command-bundle>
-
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
-        <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetRemoveFcCommand"/>
+            <action class="org.onosproject.ecord.carrierethernet.cli.commands.CarrierEthernetPktOpticalTopoCommand"/>
             <completers>
-                <ref component-id="carrierEthernetServiceIdCompleter"/>
+                <ref component-id="carrierEthernetBooleanCompleter"/>
             </completers>
         </command>
     </command-bundle>
 
-    <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
-        <command>
-            <action class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetRemoveAllFcsCommand"/>
-        </command>
-    </command-bundle>
 
     <bean id="placeholderCompleter" class="org.onosproject.cli.PlaceholderCompleter"/>
-    <bean id="carrierEthernetServiceTypeCompleter" class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetServiceTypeCompleter"/>
-    <bean id="carrierEthernetServiceIdCompleter" class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetServiceIdCompleter"/>
-    <bean id="carrierEthernetUniCompleter" class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetUniCompleter"/>
-    <bean id="carrierEthernetLtpCompleter" class="org.onosproject.ecord.carrierethernet.cli.CarrierEthernetLtpCompleter"/>
-    <bean id="connectPointCompleter" class="org.onosproject.cli.net.ConnectPointCompleter"/>
+    <bean id="carrierEthernetEvcTypeCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetEvcTypeCompleter"/>
+    <bean id="carrierEthernetEvcCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetEvcCompleter"/>
+    <bean id="carrierEthernetFcCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetFcCompleter"/>
+    <bean id="carrierEthernetPotentialUniCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetPotentialUniCompleter"/>
+    <bean id="carrierEthernetPotentialLtpCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetPotentialLtpCompleter"/>
+    <bean id="carrierEthernetConnectPointCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetConnectPointCompleter"/>
+    <bean id="carrierEthernetLtpTypeCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetLtpTypeCompleter"/>
+    <bean id="carrierEthernetUniCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetUniCompleter"/>
+    <bean id="carrierEthernetLtpCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetLtpCompleter"/>
+    <bean id="carrierEthernetBooleanCompleter" class="org.onosproject.ecord.carrierethernet.cli.completers.CarrierEthernetBooleanCompleter"/>
+
 
 </blueprint>