diff --git a/incubator/net/BUCK b/incubator/net/BUCK
index 8801df3..2a50047 100644
--- a/incubator/net/BUCK
+++ b/incubator/net/BUCK
@@ -3,6 +3,7 @@
     '//core/common:onos-core-common',
     '//incubator/api:onos-incubator-api',
     '//incubator/store:onos-incubator-store',
+    '//core/store/serializers:onos-core-serializers',
     '//utils/rest:onlab-rest',
     '//lib:concurrent-trees',
 ]
@@ -13,7 +14,6 @@
     '//lib:TEST_ADAPTERS',
     '//core/api:onos-api-tests',
     '//core/common:onos-core-common-tests',
-    '//core/store/serializers:onos-core-serializers',
 ]
 
 osgi_jar_with_tests (
diff --git a/incubator/net/pom.xml b/incubator/net/pom.xml
index 88f2d7e..d17385e 100644
--- a/incubator/net/pom.xml
+++ b/incubator/net/pom.xml
@@ -88,7 +88,11 @@
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
-
+        <dependency>
+            <groupId>org.onosproject</groupId>
+            <artifactId>onos-core-serializers</artifactId>
+            <version>${project.version}</version>
+        </dependency>
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.scr.annotations</artifactId>
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMdManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMdManager.java
new file mode 100644
index 0000000..5a125f5
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMdManager.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.cfm.impl;
+
+import java.util.Collection;
+import java.util.Optional;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.event.AbstractListenerManager;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.MdEvent;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.MdListener;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.MdStore;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.MdStoreDelegate;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Manager of Cfm Md Service - persists Maintenance Domain in distributed store.
+ */
+@Component(immediate = true)
+@Service
+public class CfmMdManager extends AbstractListenerManager<MdEvent, MdListener>
+        implements CfmMdService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private static final String APP_ID = "org.onosproject.app.cfm";
+
+    protected ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MdStore store;
+
+    protected final MdStoreDelegate delegate = new InternalStoreDelegate();
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication(APP_ID);
+
+        eventDispatcher.addSink(MdEvent.class, listenerRegistry);
+        store.setDelegate(delegate);
+
+        log.info("CFM Service Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        eventDispatcher.removeSink(MdEvent.class);
+        store.unsetDelegate(delegate);
+        log.info("CFM Service Stopped");
+    }
+
+    @Override
+    public Collection<MaintenanceDomain> getAllMaintenanceDomain() {
+        log.debug("Retrieving all MDs from distributed store");
+        return store.getAllMaintenanceDomain();
+    }
+
+    @Override
+    public Optional<MaintenanceDomain> getMaintenanceDomain(MdId mdName) {
+        log.debug("Retrieving MD {} from distributed store", mdName);
+        return store.getMaintenanceDomain(mdName);
+    }
+
+    @Override
+    public boolean deleteMaintenanceDomain(MdId mdName) throws CfmConfigException {
+        log.info("Deleting MD {} from distributed store", mdName);
+        return store.deleteMaintenanceDomain(mdName);
+    }
+
+    @Override
+    public Collection<MaintenanceAssociation> getAllMaintenanceAssociation(MdId mdName) {
+        log.debug("Retrieving all MA of MD {} from distributed store", mdName);
+        return store.getMaintenanceDomain(mdName)
+                .orElseThrow(() -> new IllegalArgumentException("Unknown MD " + mdName))
+                .maintenanceAssociationList();
+    }
+
+    @Override
+    public Optional<MaintenanceAssociation> getMaintenanceAssociation(
+                                                MdId mdName, MaIdShort maName) {
+        log.debug("Retrieving MA {} of MD {} from distributed store", maName, mdName);
+        return store.getMaintenanceDomain(mdName)
+                .orElseThrow(() -> new IllegalArgumentException("Unknown MD " + mdName))
+                .maintenanceAssociationList()
+                .stream().filter(ma -> ma.maId().equals(maName))
+                .findFirst();
+    }
+
+    @Override
+    public boolean deleteMaintenanceAssociation(MdId mdName, MaIdShort maName) throws CfmConfigException {
+        log.info("Deleting MA {} of MD {} from distributed store", maName, mdName);
+        MaintenanceDomain.MdBuilder builder = DefaultMaintenanceDomain
+                .builder(store.getMaintenanceDomain(mdName)
+                .orElseThrow(() -> new IllegalArgumentException("Unknown MD: " + mdName)));
+
+        //Check the MA is present
+        if (!builder.checkMaExists(maName)) {
+            return false;
+        }
+
+        builder = builder.deleteFromMaList(maName);
+
+        store.createUpdateMaintenanceDomain(builder.build());
+        return true;
+    }
+
+    @Override
+    public boolean createMaintenanceDomain(MaintenanceDomain newMd) throws CfmConfigException {
+        log.info("Creating/Updating MD {} in distributed store", newMd.mdId());
+        return store.createUpdateMaintenanceDomain(newMd);
+    }
+
+    @Override
+    public boolean createMaintenanceAssociation(MdId mdName, MaintenanceAssociation newMa)
+            throws CfmConfigException {
+        log.info("Updating MD {} in distributed store by adding new MA {}", mdName, newMa.maId());
+        MaintenanceDomain.MdBuilder builder = DefaultMaintenanceDomain
+                .builder(store.getMaintenanceDomain(mdName)
+                .orElseThrow(() -> new IllegalArgumentException("Unknown MD: " + mdName)));
+
+        boolean replaced = false;
+        //Check the MA is present
+        if (builder.checkMaExists(newMa.maId())) {
+            builder = builder.deleteFromMaList(newMa.maId());
+            replaced = true;
+        }
+
+        builder.addToMaList(newMa);
+        store.createUpdateMaintenanceDomain(builder.build());
+        return replaced;
+    }
+
+    private class InternalStoreDelegate implements MdStoreDelegate {
+        @Override
+        public void notify(MdEvent event) {
+            log.debug("New MD event: {}", event.subject());
+            eventDispatcher.post(event);
+        }
+    }
+
+}
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMepManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMepManager.java
new file mode 100644
index 0000000..5723466
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMepManager.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.cfm.impl;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.event.AbstractListenerManager;
+import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepEvent;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepListener;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepProgrammable;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.slf4j.Logger;
+
+/**
+ * Provides implementation of the CFM North and South Bound Interfaces.
+ */
+@Component(immediate = true)
+@Service
+public class CfmMepManager
+    extends AbstractListenerManager<CfmMepEvent, CfmMepListener>
+    implements CfmMepService {
+
+    private final Logger log = getLogger(getClass());
+
+    private final DeviceListener deviceListener = new InternalDeviceListener();
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CfmMdService cfmMdService;
+
+    private static final int DEFAULT_POLL_FREQUENCY = 30;
+    private int fallbackMepPollFrequency = DEFAULT_POLL_FREQUENCY;
+
+    private IdGenerator idGenerator;
+
+    //FIXME Get rid of this hack - we will use this in memory to emulate
+    // a store for the short term.
+    //Note: This is not distributed and will not work in a clustered system
+    //TODO Create a MepStore for this
+    private Collection<Mep> mepCollection;
+
+
+    @Activate
+    public void activate() {
+        //FIXME Get rid of this local list
+        mepCollection = new ArrayList<>();
+
+        eventDispatcher.addSink(CfmMepEvent.class, listenerRegistry);
+        deviceService.addListener(deviceListener);
+        idGenerator = coreService.getIdGenerator("mep-ids");
+        log.info("CFM MEP Manager Started");
+    }
+
+    @Deactivate
+    public void deactivate() {
+        deviceService.removeListener(deviceListener);
+        eventDispatcher.removeSink(CfmMepEvent.class);
+        log.info("CFM MEP Manager Stopped");
+        mepCollection.clear();
+    }
+
+    @Override
+    public Collection<MepEntry> getAllMeps(MdId mdName, MaIdShort maName)
+            throws CfmConfigException {
+        //Will throw IllegalArgumentException if ma does not exist
+        cfmMdService.getMaintenanceAssociation(mdName, maName);
+
+        Collection<MepEntry> mepEntryCollection = new ArrayList<>();
+
+        for (Mep mep:mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)) {
+                DeviceId mepDeviceId = mep.deviceId();
+                if (deviceService.getDevice(mepDeviceId) == null) {
+                    log.warn("Device not found/available " + mepDeviceId +
+                        " for MEP: " + mdName + "/" + maName + "/" + mep.mepId());
+                    continue;
+                } else if (!deviceService.getDevice(mepDeviceId)
+                                        .is(CfmMepProgrammable.class)) {
+                    throw new CfmConfigException("Device " + mepDeviceId +
+                            " does not support CfmMepProgrammable behaviour.");
+                }
+
+                log.debug("Retrieving MEP results for Mep {} in MD {}, MA {} "
+                    + "on Device {}", mep.mepId(), mdName, maName, mepDeviceId);
+                mepEntryCollection.add(deviceService
+                                        .getDevice(mepDeviceId)
+                                        .as(CfmMepProgrammable.class)
+                                        .getMep(mdName, maName, mep.mepId()));
+            }
+        }
+
+        return mepEntryCollection;
+    }
+
+    @Override
+    public MepEntry getMep(MdId mdName, MaIdShort maName, MepId mepId) throws CfmConfigException {
+        //Will throw IllegalArgumentException if ma does not exist
+        cfmMdService.getMaintenanceAssociation(mdName, maName);
+
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(mepId)) {
+
+                DeviceId mepDeviceId = mep.deviceId();
+                if (deviceService.getDevice(mepDeviceId) == null) {
+                    throw new CfmConfigException("Device not found " + mepDeviceId);
+                } else if (!deviceService.getDevice(mepDeviceId).is(CfmMepProgrammable.class)) {
+                    throw new CfmConfigException("Device " + mepDeviceId +
+                            " does not support CfmMepProgrammable behaviour.");
+                }
+
+                log.debug("Retrieving MEP reults for Mep {} in MD {}, MA {} on Device {}",
+                        mep.mepId(), mdName, maName, mepDeviceId);
+
+                return deviceService.getDevice(mepDeviceId)
+                        .as(CfmMepProgrammable.class).getMep(mdName, maName, mepId);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean deleteMep(MdId mdName, MaIdShort maName, MepId mepId) throws CfmConfigException {
+        //Will throw IllegalArgumentException if ma does not exist
+        cfmMdService.getMaintenanceAssociation(mdName, maName);
+
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(mepId)) {
+                Device mepDevice = deviceService.getDevice(mep.deviceId());
+                if (mepDevice == null || !mepDevice.is(CfmMepProgrammable.class)) {
+                    throw new CfmConfigException("Unexpeced fault on device drier for "
+                            + mep.deviceId());
+                }
+                boolean deleted = false;
+                try {
+                     deleted = mepDevice.as(CfmMepProgrammable.class)
+                            .deleteMep(mdName, maName, mepId);
+                } catch (CfmConfigException e) {
+                    log.warn("MEP could not be deleted on device - perhaps it "
+                            + "does not exist. Continuing");
+                    mepCollection.remove(mep);
+                    return false;
+                }
+                if (deleted) {
+                    mepCollection.remove(mep);
+                    return true;
+                } else {
+                    return false;
+                }
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public boolean createMep(MdId mdName, MaIdShort maName, Mep newMep) throws CfmConfigException {
+        log.debug("Creating MEP " + newMep.mepId() + " on MD {}, MA {} on Device {}",
+                mdName, maName, newMep.deviceId().toString());
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(newMep.mepId())) {
+                return false;
+            }
+        }
+
+        //Will throw IllegalArgumentException if ma does not exist
+        cfmMdService.getMaintenanceAssociation(mdName, maName);
+
+        DeviceId mepDeviceId = newMep.deviceId();
+        if (deviceService.getDevice(mepDeviceId) == null) {
+            throw new CfmConfigException("Device not found " + mepDeviceId);
+        } else if (!deviceService.getDevice(mepDeviceId).is(CfmMepProgrammable.class)) {
+            throw new CfmConfigException("Device " + mepDeviceId + " does not support CfmMepProgrammable behaviour.");
+        }
+
+        boolean deviceResult =
+                deviceService.getDevice(mepDeviceId).as(CfmMepProgrammable.class).createMep(mdName, maName, newMep);
+        log.debug("MEP created on {}", mepDeviceId);
+        if (deviceResult) {
+            return mepCollection.add(newMep);
+        } else {
+            return deviceResult;
+        }
+    }
+
+    @Override
+    public void transmitLoopback(MdId mdName, MaIdShort maName,
+            MepId mepId, MepLbCreate lbCreate) throws CfmConfigException {
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(mepId)) {
+                log.debug("Transmitting Loopback on MEP {}/{}/{} on Device {}",
+                        mdName, maName, mepId, mep.deviceId());
+                deviceService.getDevice(mep.deviceId())
+                    .as(CfmMepProgrammable.class)
+                    .transmitLoopback(mdName, maName, mepId, lbCreate);
+                return;
+            }
+        }
+        throw new CfmConfigException("Mep " + mdName + "/" + maName + "/"
+                + mepId + " not found when calling Transmit Loopback");
+    }
+
+    @Override
+    public void abortLoopback(MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+        for (Mep mep : mepCollection) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName)
+                    && mep.mepId().equals(mepId)) {
+                log.debug("Aborting Loopback on MEP {}/{}/{} on Device {}",
+                        mdName, maName, mepId, mep.deviceId());
+                deviceService.getDevice(mep.deviceId())
+                    .as(CfmMepProgrammable.class)
+                    .abortLoopback(mdName, maName, mepId);
+                return;
+            }
+        }
+        throw new CfmConfigException("Mep " + mdName + "/" + maName + "/"
+                + mepId + " not found when calling Transmit Loopback");
+    }
+
+    @Override
+    public void transmitLinktrace(MdId mdName, MaIdShort maName, MepId mepId,
+            MepLtCreate ltCreate) {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    private class InternalDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            switch (event.type()) {
+                case DEVICE_REMOVED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                    DeviceId deviceId = event.subject().id();
+                    if (!deviceService.isAvailable(deviceId)) {
+                        log.warn("Device {} has been removed or changed", deviceId);
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+}
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/DistributedMdStore.java b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/DistributedMdStore.java
new file mode 100644
index 0000000..964a56a
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/DistributedMdStore.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.cfm.impl;
+
+import com.google.common.net.InternetDomainName;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onlab.packet.MacAddress;
+import org.onlab.util.Identifier;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultComponent;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaId2Octet;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdIccY1731;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdPrimaryVid;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdRfc2685VpnId;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdDomainName;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdMacUint;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdNone;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.MdEvent;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.MdStore;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.MdStoreDelegate;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.AbstractStore;
+import org.onosproject.store.service.ConsistentMap;
+import org.onosproject.store.service.MapEvent;
+import org.onosproject.store.service.MapEventListener;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Maintenance Domain Store implementation backed by consistent map.
+ */
+@Component(immediate = true)
+@Service
+public class DistributedMdStore extends AbstractStore<MdEvent, MdStoreDelegate>
+    implements MdStore {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected StorageService storageService;
+
+    private ConsistentMap<MdId, MaintenanceDomain> maintenanceDomainConsistentMap;
+    private Map<MdId, MaintenanceDomain> maintenanceDomainMap;
+
+    private final InternalMdListener listener = new InternalMdListener();
+
+    @Activate
+    public void activate() {
+        maintenanceDomainConsistentMap = storageService
+                .<MdId, MaintenanceDomain>consistentMapBuilder()
+                .withName("onos-cfm-ma-map")
+                .withSerializer(Serializer.using(new KryoNamespace.Builder()
+                        .register(KryoNamespaces.API)
+                        .register(DefaultMaintenanceDomain.class)
+                        .register(MdIdCharStr.class)
+                        .register(MdIdDomainName.class)
+                        .register(MdIdMacUint.class)
+                        .register(MdIdNone.class)
+                        .register(MaintenanceDomain.MdLevel.class)
+                        .register(DefaultMaintenanceAssociation.class)
+                        .register(MaIdCharStr.class)
+                        .register(MaIdShort.class)
+                        .register(MaId2Octet.class)
+                        .register(MaIdIccY1731.class)
+                        .register(MaIdPrimaryVid.class)
+                        .register(MaIdRfc2685VpnId.class)
+                        .register(MaintenanceAssociation.CcmInterval.class)
+                        .register(DefaultComponent.class)
+                        .register(MepId.class)
+                        .register(Identifier.class)
+                        .register(InternetDomainName.class)
+                        .register(MacAddress.class)
+                        .register(ImmutablePair.class)
+                        .register(org.onosproject.incubator.net.l2monitoring
+                                            .cfm.Component.MhfCreationType.class)
+                        .register(org.onosproject.incubator.net.l2monitoring
+                                            .cfm.Component.IdPermissionType.class)
+                        .register(org.onosproject.incubator.net.l2monitoring
+                                            .cfm.Component.TagType.class)
+                        .build("md")))
+                .build();
+
+        maintenanceDomainMap = maintenanceDomainConsistentMap.asJavaMap();
+    }
+
+    @Override
+    public Collection<MaintenanceDomain> getAllMaintenanceDomain() {
+        return maintenanceDomainMap.values();
+    }
+
+    @Override
+    public Optional<MaintenanceDomain> getMaintenanceDomain(MdId mdName) {
+        return Optional.ofNullable(
+                maintenanceDomainMap.get(mdName));
+    }
+
+    @Override
+    public boolean deleteMaintenanceDomain(MdId mdName) {
+        return maintenanceDomainMap.remove(mdName) == null ? false : true;
+    }
+
+    @Override
+    public boolean createUpdateMaintenanceDomain(MaintenanceDomain md) {
+        return maintenanceDomainMap.put(md.mdId(), md) == null ? false : true;
+    }
+
+    private class InternalMdListener implements MapEventListener<MdId, MaintenanceDomain> {
+        @Override
+        public void event(MapEvent<MdId, MaintenanceDomain> mapEvent) {
+            final MdEvent.Type type;
+            switch (mapEvent.type()) {
+                case INSERT:
+                    type = MdEvent.Type.MD_ADDED;
+                    break;
+                case UPDATE:
+                    type = MdEvent.Type.MD_UPDATED;
+                    break;
+                case REMOVE:
+                default:
+                    type = MdEvent.Type.MD_REMOVED;
+                    break;
+            }
+            notifyDelegate(new MdEvent(type, mapEvent.key()));
+        }
+    }
+}
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/package-info.java b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/package-info.java
new file mode 100644
index 0000000..3542f07
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * An implementation of Layer 2 CFM (Connectivity Fault Management).
+ */
+package org.onosproject.incubator.net.l2monitoring.cfm.impl;
\ No newline at end of file
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/soam/impl/SoamManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/soam/impl/SoamManager.java
new file mode 100644
index 0000000..9a351ca
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/soam/impl/SoamManager.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.soam.impl;
+
+import java.util.Collection;
+import java.util.Optional;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepTsCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamDmProgrammable;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamService;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatCurrent;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatHistory;
+import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate;
+import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementEntry;
+import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementStatCurrent;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.device.DeviceService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * ONOS application component.
+ */
+@Component(immediate = true)
+@Service
+public class SoamManager implements SoamService {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private static final String APP_ID = "org.onosproject.app.soam";
+
+    private ApplicationId appId;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CfmMepService cfmMepService;
+
+    @Activate
+    protected void activate() {
+        appId = coreService.registerApplication(APP_ID);
+
+        log.info("SOAM Service Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        log.info("SOAM Service Stopped");
+    }
+
+    @Override
+    public Collection<DelayMeasurementEntry> getAllDms(
+            MdId mdName, MaIdShort maName, MepId mepId)
+                    throws CfmConfigException, SoamConfigException {
+        MepEntry mep = cfmMepService.getMep(mdName, maName, mepId);
+        log.debug("Retrieving DMs for MD {}, MA {}, MEP {} on Device {}",
+                mdName, maName, mepId, mep.deviceId());
+        return mep.delayMeasurementList();
+    };
+
+    @Override
+    public DelayMeasurementEntry getDm(MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
+                throws CfmConfigException, SoamConfigException {
+        MepEntry mep = cfmMepService.getMep(mdName, maName, mepId);
+        if (mep == null || mep.deviceId() == null) {
+            throw new CfmConfigException("MEP :"
+                    + mdName + "/" + maName + "/" + mepId + " does not exist");
+        } else if (deviceService.getDevice(mep.deviceId()) == null) {
+            throw new CfmConfigException("Device " + mep.deviceId() + " from MEP :"
+                    + mdName + "/" + maName + "/" + mepId + " does not exist");
+        } else if (!deviceService.getDevice(mep.deviceId()).is(SoamDmProgrammable.class)) {
+            throw new CfmConfigException("Device " + mep.deviceId() + " from MEP :"
+                    + mdName + "/" + maName + "/" + mepId +
+                    " does not implement SoamDmProgrammable");
+        }
+        log.debug("Retrieving DM for DM {} in MD {}, MA {}, MEP {} on Device {}",
+                dmId, mdName, maName, mepId, mep.deviceId());
+        return deviceService.getDevice(mep.deviceId())
+            .as(SoamDmProgrammable.class).getDm(mdName, maName, mepId, dmId);
+    }
+
+    @Override
+    public DelayMeasurementStatCurrent getDmCurrentStat(MdId mdName,
+            MaIdShort maName, MepId mepId, SoamId dmId)
+                    throws CfmConfigException, SoamConfigException {
+        MepEntry mep = cfmMepService.getMep(mdName, maName, mepId);
+        if (mep == null || mep.deviceId() == null) {
+            throw new CfmConfigException("MEP :"
+                    + mdName + "/" + maName + "/" + mepId + " does not exist");
+        } else if (deviceService.getDevice(mep.deviceId()) == null) {
+            throw new CfmConfigException("Device " + mep.deviceId() + " from MEP :"
+                    + mdName + "/" + maName + "/" + mepId + " does not exist");
+        } else if (!deviceService.getDevice(mep.deviceId()).is(SoamDmProgrammable.class)) {
+            throw new CfmConfigException("Device " + mep.deviceId() + " from MEP :"
+                    + mdName + "/" + maName + "/" + mepId +
+                    " does not implement SoamDmProgrammable");
+        }
+        log.debug("Retrieving Current Stats for DM {} in MD {}, MA {}, MEP {} "
+                + "on Device {}", dmId, mdName, maName, mepId, mep.deviceId());
+        return deviceService.getDevice(mep.deviceId())
+            .as(SoamDmProgrammable.class).getDmCurrentStat(mdName, maName, mepId, dmId);
+    }
+
+    @Override
+    public Collection<DelayMeasurementStatHistory> getDmHistoricalStats(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
+                    throws SoamConfigException, CfmConfigException {
+        MepEntry mep = cfmMepService.getMep(mdName, maName, mepId);
+        if (mep == null || mep.deviceId() == null) {
+            throw new CfmConfigException("MEP :"
+                    + mdName + "/" + maName + "/" + mepId + " does not exist");
+        } else if (deviceService.getDevice(mep.deviceId()) == null) {
+            throw new CfmConfigException("Device " + mep.deviceId() + " from MEP :"
+                    + mdName + "/" + maName + "/" + mepId + " does not exist");
+        } else if (!deviceService.getDevice(mep.deviceId()).is(SoamDmProgrammable.class)) {
+            throw new CfmConfigException("Device " + mep.deviceId() + " from MEP :"
+                    + mdName + "/" + maName + "/" + mepId +
+                    " does not implement SoamDmProgrammable");
+        }
+        log.debug("Retrieving History Stats for DM {} in MD {}, MA {}, MEP {} "
+                + "on Device {}", dmId, mdName, maName, mepId, mep.deviceId());
+        return deviceService.getDevice(mep.deviceId())
+            .as(SoamDmProgrammable.class).getDmHistoricalStats(mdName, maName, mepId, dmId);
+    }
+
+    @Override
+    public Optional<SoamId> createDm(MdId mdName, MaIdShort maName, MepId mepId,
+                                    DelayMeasurementCreate dmNew)
+                    throws CfmConfigException, SoamConfigException {
+        DeviceId mepDeviceId = cfmMepService.getMep(mdName, maName, mepId).deviceId();
+        if (mepDeviceId == null) {
+            throw new CfmConfigException("Unable to create DM. MEP :"
+                    + mdName + "/" + maName + "/" + mepId + " does not exist");
+        } else if (deviceService.getDevice(mepDeviceId) == null) {
+            throw new CfmConfigException("Device " + mepDeviceId + " from MEP :"
+                    + mdName + "/" + maName + "/" + mepId + " does not exist");
+        } else if (!deviceService.getDevice(mepDeviceId).is(SoamDmProgrammable.class)) {
+            throw new CfmConfigException("Device " + mepDeviceId + " from MEP :"
+                    + mdName + "/" + maName + "/" + mepId +
+                    " does not implement SoamDmProgrammable");
+        }
+        log.debug("Creating new DM in MD {}, MA {}, MEP {} on Device {}",
+                mdName, maName, mepId, mepDeviceId);
+        return deviceService.getDevice(mepDeviceId)
+            .as(SoamDmProgrammable.class).createDm(mdName, maName, mepId, dmNew);
+    }
+
+    @Override
+    public void abortDm(MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public void abortDm(MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
+            throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public void clearDelayHistoryStats(MdId mdName, MaIdShort maName,
+            MepId mepId) throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public void clearDelayHistoryStats(MdId mdName, MaIdShort maName,
+            MepId mepId, SoamId dmId) throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public Collection<LossMeasurementEntry> getAllLms(MdId mdName,
+            MaIdShort maName, MepId mepId) throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public LossMeasurementEntry getLm(MdId mdName, MaIdShort maName,
+            MepId mepId, SoamId lmId) throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public LossMeasurementStatCurrent getLmCurrentStat(MdId mdName,
+            MaIdShort maName, MepId mepId, SoamId lmId) {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public Collection<LossMeasurementStatCurrent> getLmHistoricalStats(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId lmId) {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public Optional<SoamId> createLm(MdId mdName, MaIdShort maName, MepId mepId,
+            LossMeasurementCreate lm) throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public void abortLm(MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public void abortLm(MdId mdName, MaIdShort maName, MepId mepId, SoamId lmId)
+            throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public void clearLossHistoryStats(MdId mdName, MaIdShort maName,
+            MepId mepId) throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public void clearLossHistoryStats(MdId mdName, MaIdShort maName,
+            MepId mepId, SoamId lmId) throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public void createTestSignal(MdId mdName, MaIdShort maName, MepId mepId,
+            MepTsCreate tsCreate) throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+
+    @Override
+    public void abortTestSignal(MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+        throw new UnsupportedOperationException("Not yet implemented");
+    }
+}
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/soam/impl/package-info.java b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/soam/impl/package-info.java
new file mode 100644
index 0000000..fd932e0
--- /dev/null
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/l2monitoring/soam/impl/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * An implementation of Layer 2 CFM Service Operations and Maintenance (SOAM).
+ */
+package org.onosproject.incubator.net.l2monitoring.soam.impl;
\ No newline at end of file
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMdManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMdManagerTest.java
new file mode 100644
index 0000000..a0de513
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMdManagerTest.java
@@ -0,0 +1,386 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.cfm.impl;
+
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.IpAddress;
+import org.onosproject.cluster.ClusterServiceAdapter;
+import org.onosproject.cluster.ControllerNode;
+import org.onosproject.cluster.DefaultControllerNode;
+import org.onosproject.cluster.NodeId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.l2monitoring.cfm.Component;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultComponent;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceDomain;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceDomain;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.DeviceId;
+import org.onosproject.store.service.TestStorageService;
+
+import java.util.Collection;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static junit.framework.TestCase.assertFalse;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+
+/**
+ * CFM MD Manager test.
+ */
+public class CfmMdManagerTest {
+    private static final NodeId NID_LOCAL = new NodeId("local");
+    private static final IpAddress LOCALHOST = IpAddress.valueOf("127.0.0.1");
+
+    private DistributedMdStore mdStore;
+    private CfmMdService service;
+    private CfmMdManager manager;
+
+    @Before
+    public void setup() throws Exception, CfmConfigException {
+        mdStore = new DistributedMdStore();
+
+        MaintenanceAssociation maTest11 = DefaultMaintenanceAssociation
+                .builder(MaIdCharStr.asMaId("test-ma-1-1"), 9)
+                .ccmInterval(MaintenanceAssociation.CcmInterval.INTERVAL_10MIN)
+                .maNumericId((short) 1)
+                .addToRemoteMepIdList(MepId.valueOf((short) 101))
+                .addToRemoteMepIdList(MepId.valueOf((short) 102))
+                .addToComponentList(
+                        DefaultComponent.builder(1)
+                                .tagType(Component.TagType.VLAN_CTAG)
+                                .build())
+                .build();
+
+        MaintenanceAssociation maTest12 = DefaultMaintenanceAssociation
+                .builder(MaIdCharStr.asMaId("test-ma-1-2"), 9)
+                .ccmInterval(MaintenanceAssociation.CcmInterval.INTERVAL_10MIN)
+                .maNumericId((short) 2)
+                .addToRemoteMepIdList(MepId.valueOf((short) 201))
+                .addToRemoteMepIdList(MepId.valueOf((short) 202))
+                .addToComponentList(
+                        DefaultComponent.builder(2)
+                                .tagType(Component.TagType.VLAN_CTAG)
+                                .build())
+                .build();
+
+        MaintenanceDomain mdTest1 = DefaultMaintenanceDomain
+                .builder(MdIdCharStr.asMdId("test-md-1"))
+                .mdLevel(MaintenanceDomain.MdLevel.LEVEL1)
+                .mdNumericId((short) 1)
+                .addToMaList(maTest11)
+                .addToMaList(maTest12)
+                .build();
+
+        TestUtils.setField(mdStore, "storageService", new TestStorageService());
+        TestUtils.setField(mdStore, "clusterService", new CfmMdManagerTest.TestClusterService());
+        TestUtils.setField(mdStore, "mastershipService", new CfmMdManagerTest.TestMastershipService());
+        mdStore.activate();
+        mdStore.createUpdateMaintenanceDomain(mdTest1);
+
+        manager = new CfmMdManager();
+        manager.store = mdStore;
+        service = manager;
+        TestUtils.setField(manager, "storageService", new TestStorageService());
+        TestUtils.setField(manager, "coreService", new TestCoreService());
+        injectEventDispatcher(manager, new TestEventDispatcher());
+
+        manager.appId = new CfmMdManagerTest.TestApplicationId(0, "CfmMdManagerTest");
+        manager.activate();
+    }
+
+    @After
+    public void tearDown() {
+
+        manager.deactivate();
+        injectEventDispatcher(manager, null);
+
+    }
+
+    @Test
+    public void testGetAllMaintenanceDomain() {
+        Collection<MaintenanceDomain> mdList = service.getAllMaintenanceDomain();
+        assertEquals(1, mdList.size());
+
+        MaintenanceDomain md = mdList.iterator().next();
+        assertEquals(1, md.mdNumericId());
+
+        assertEquals(2, md.maintenanceAssociationList().size());
+
+        md.maintenanceAssociationList().iterator().forEachRemaining(ma ->
+                assertTrue(ma.maId().maName().endsWith(String.valueOf(ma.maNumericId())))
+        );
+    }
+
+    @Test
+    public void testGetMaintenanceDomain() {
+        Optional<MaintenanceDomain> md =
+                service.getMaintenanceDomain(MdIdCharStr.asMdId("test-md-1"));
+        assertTrue(md.isPresent());
+
+        assertEquals(1, md.get().mdNumericId());
+
+        assertEquals(2, md.get().maintenanceAssociationList().size());
+
+
+
+        //Now try an invalid name
+        Optional<MaintenanceDomain> mdInvalid =
+                service.getMaintenanceDomain(MdIdCharStr.asMdId("test-md-3"));
+        assertFalse(mdInvalid.isPresent());
+    }
+
+    @Test
+    public void testDeleteMaintenanceDomain() {
+        try {
+            assertTrue(service.deleteMaintenanceDomain(
+                    MdIdCharStr.asMdId("test-md-1")));
+        } catch (CfmConfigException e) {
+            fail("Should not have thrown exception: " + e.getMessage());
+        }
+
+        //Now try an invalid name
+        try {
+            assertFalse(service.deleteMaintenanceDomain(
+                    MdIdCharStr.asMdId("test-md-3")));
+        } catch (CfmConfigException e) {
+            fail("Should not have thrown exception: " + e.getMessage());
+        }
+    }
+
+    @Test
+    public void testCreateMaintenanceDomain() throws CfmConfigException {
+
+        MaintenanceAssociation maTest21 = DefaultMaintenanceAssociation
+                .builder(MaIdCharStr.asMaId("test-ma-2-1"), 9)
+                .ccmInterval(MaintenanceAssociation.CcmInterval.INTERVAL_1S)
+                .maNumericId((short) 1)
+                .addToRemoteMepIdList(MepId.valueOf((short) 101))
+                .addToRemoteMepIdList(MepId.valueOf((short) 102))
+                .addToComponentList(
+                        DefaultComponent.builder(1)
+                                .tagType(Component.TagType.VLAN_STAG)
+                                .build())
+                .build();
+
+        MaintenanceDomain mdTest2 = DefaultMaintenanceDomain
+                .builder(MdIdCharStr.asMdId("test-md-2"))
+                .mdLevel(MaintenanceDomain.MdLevel.LEVEL2)
+                .mdNumericId((short) 2)
+                .addToMaList(maTest21)
+                .build();
+
+
+        //We expect false here because there should have been no previous value
+        //with that ID in the store
+        assertFalse(service.createMaintenanceDomain(mdTest2));
+    }
+
+    @Test
+    public void testGetAllMaintenanceAssociation() {
+        Collection<MaintenanceAssociation> maListMd1 =
+            service.getAllMaintenanceAssociation(
+                    MdIdCharStr.asMdId("test-md-1"));
+
+        assertEquals(2, maListMd1.size());
+
+        maListMd1.iterator().forEachRemaining(ma ->
+            assertTrue(ma.maId().maName().endsWith(String.valueOf(ma.maNumericId())))
+        );
+
+        //Now try with an invalid name
+        try {
+            service.getAllMaintenanceAssociation(
+                    MdIdCharStr.asMdId("test-md-2"));
+        } catch (IllegalArgumentException e) {
+            assertEquals("Unknown MD test-md-2", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testGetMaintenanceAssociation() {
+        Optional<MaintenanceAssociation> ma =
+                service.getMaintenanceAssociation(
+                        MdIdCharStr.asMdId("test-md-1"),
+                        MaIdCharStr.asMaId("test-ma-1-2"));
+
+        assertTrue(ma.isPresent());
+
+        //Now try an invalid MD Name
+        try {
+            service.getMaintenanceAssociation(
+                    MdIdCharStr.asMdId("test-md-2"),
+                    MaIdCharStr.asMaId("test-ma-1-2"));
+        } catch (IllegalArgumentException e) {
+            assertEquals("Unknown MD test-md-2", e.getMessage());
+        }
+
+        //Now try an invalid MA Name with a valid MD Name
+        try {
+            Optional<MaintenanceAssociation> maInvalid =
+                    service.getMaintenanceAssociation(
+                    MdIdCharStr.asMdId("test-md-1"),
+                    MaIdCharStr.asMaId("test-ma-1-3"));
+            assertFalse(maInvalid.isPresent());
+        } catch (IllegalArgumentException e) {
+            fail("Should not throw exception: " + e.getMessage());
+        }
+    }
+
+    @Test
+    public void testDeleteMaintenanceAssociation() throws CfmConfigException {
+        assertTrue(service.deleteMaintenanceAssociation(
+                MdIdCharStr.asMdId("test-md-1"),
+                MaIdCharStr.asMaId("test-ma-1-2")));
+
+        //Now check it has actually been removed
+        Collection<MaintenanceAssociation> maListUpdated =
+                service.getAllMaintenanceAssociation(
+                        MdIdCharStr.asMdId("test-md-1"));
+        assertEquals(1, maListUpdated.size());
+        maListUpdated.stream().findFirst().ifPresent(ma ->
+                assertEquals("test-ma-1-1", ma.maId().maName())
+        );
+
+        //Now try with an invalid mdName
+        try {
+            service.deleteMaintenanceAssociation(
+                    MdIdCharStr.asMdId("test-md-2"),
+                    MaIdCharStr.asMaId("test-ma-1-2"));
+        } catch (IllegalArgumentException e) {
+            assertEquals("Unknown MD: test-md-2", e.getMessage());
+        }
+
+        //Now try with an invalid maName
+        try {
+            assertFalse(service.deleteMaintenanceAssociation(
+                            MdIdCharStr.asMdId("test-md-1"),
+                            MaIdCharStr.asMaId("test-ma-1-3")));
+        } catch (IllegalArgumentException e) {
+            fail("Should not throw exception: " + e.getMessage());
+        }
+    }
+
+    @Test
+    public void testCreateMaintenanceAssociation() throws CfmConfigException {
+        MaintenanceAssociation maTest41 = DefaultMaintenanceAssociation
+                .builder(MaIdCharStr.asMaId("test-ma-1-4"), 9)
+                .ccmInterval(MaintenanceAssociation.CcmInterval.INTERVAL_1S)
+                .maNumericId((short) 4)
+                .addToRemoteMepIdList(MepId.valueOf((short) 401))
+                .addToRemoteMepIdList(MepId.valueOf((short) 402))
+                .addToComponentList(
+                        DefaultComponent.builder(4)
+                                .tagType(Component.TagType.VLAN_STAG)
+                                .build())
+                .build();
+
+        //Should return false, as this MA did not exist before
+        assertFalse(service.createMaintenanceAssociation(
+                            MdIdCharStr.asMdId("test-md-1"), maTest41));
+        assertEquals(3, service.getAllMaintenanceAssociation(
+                                MdIdCharStr.asMdId("test-md-1")).size());
+
+        //Now try with an invalid mdName
+        try {
+            service.createMaintenanceAssociation(
+                    MdIdCharStr.asMdId("test-md-2"), maTest41);
+        } catch (IllegalArgumentException e) {
+            assertEquals("Unknown MD: test-md-2", e.getMessage());
+        }
+
+        //Now try replacing an MA with some new values or Remote MEP
+        MaintenanceAssociation maTest11 = DefaultMaintenanceAssociation
+                .builder(MaIdCharStr.asMaId("test-ma-1-1"), 9)
+                .ccmInterval(MaintenanceAssociation.CcmInterval.INTERVAL_10MIN)
+                .maNumericId((short) 1)
+                .addToRemoteMepIdList(MepId.valueOf((short) 111)) //Changed
+                .addToRemoteMepIdList(MepId.valueOf((short) 112)) //Changed
+                .addToComponentList(
+                        DefaultComponent.builder(1)
+                                .tagType(Component.TagType.VLAN_CTAG)
+                                .build())
+                .build();
+
+        //Should return true, as this MA did exist before
+        assertTrue(service.createMaintenanceAssociation(
+                MdIdCharStr.asMdId("test-md-1"), maTest11));
+        assertEquals(3, service.getAllMaintenanceAssociation(
+                MdIdCharStr.asMdId("test-md-1")).size());
+    }
+
+
+    public class TestApplicationId extends DefaultApplicationId {
+        public TestApplicationId(int id, String name) {
+            super(id, name);
+        }
+    }
+
+    private final class TestClusterService extends ClusterServiceAdapter {
+
+        ControllerNode local = new DefaultControllerNode(NID_LOCAL, LOCALHOST);
+
+        @Override
+        public ControllerNode getLocalNode() {
+            return local;
+        }
+
+        @Override
+        public Set<ControllerNode> getNodes() {
+            return Sets.newHashSet();
+        }
+
+    }
+
+    private class TestMastershipService extends MastershipServiceAdapter {
+        @Override
+        public NodeId getMasterFor(DeviceId deviceId) {
+            return NID_LOCAL;
+        }
+    }
+
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMepManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMepManagerTest.java
new file mode 100644
index 0000000..a825858
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/CfmMepManagerTest.java
@@ -0,0 +1,381 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.cfm.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.ChassisId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMaintenanceAssociation;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMep;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLbCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepLtCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
+import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepProgrammable;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamDmProgrammable;
+import org.onosproject.incubator.net.l2monitoring.soam.impl.TestSoamDmProgrammable;
+import org.onosproject.net.AbstractProjectableModel;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.DefaultDriver;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.provider.ProviderId;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static junit.framework.TestCase.fail;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+
+/**
+ * CFM MEP Manager test.
+ */
+public class CfmMepManagerTest {
+    private static final String TEST_MFR = "testMfr";
+    private static final String TEST_HW_VERSION = "testHwVersion";
+    private static final String TEST_SW_VERSION = "testSwVersion";
+    private static final String TEST_SN = "testSn";
+    private static final String TEST_DRIVER = "testDriver";
+    public static final String TEST_DRIVER_3 = "testDriver3";
+    public static final String TEST_SW_3 = "testSw3";
+    private final CfmMdService mdService = createMock(CfmMdService.class);
+    private final DeviceService deviceService = createMock(DeviceService.class);
+    private final DriverService driverService = createMock(DriverService.class);
+
+    private CfmMepService mepService;
+    private CfmMepManager mepManager;
+
+    protected static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
+    protected static final MaIdShort MANAME1 = MaIdCharStr.asMaId("ma-1-1");
+
+    private MaintenanceAssociation ma1;
+    protected static final MepId MEPID1 = MepId.valueOf((short) 10);
+    protected static final MepId MEPID2 = MepId.valueOf((short) 20);
+    protected static final DeviceId DEVICE_ID1 = DeviceId.deviceId("netconf:1.2.3.4:830");
+    protected static final DeviceId DEVICE_ID2 = DeviceId.deviceId("netconf:2.2.3.4:830");
+
+    private Mep mep1;
+    private Mep mep2;
+
+    private Device device1;
+    private Device device2;
+
+    private Driver testDriver;
+
+    @Before
+    public void setup() throws CfmConfigException {
+        mepManager = new CfmMepManager();
+
+        ma1 = DefaultMaintenanceAssociation.builder(MANAME1, MDNAME1.getNameLength()).build();
+
+        TestUtils.setField(mepManager, "coreService", new TestCoreService());
+        TestUtils.setField(mepManager, "deviceService", deviceService);
+        TestUtils.setField(mepManager, "cfmMdService", mdService);
+        injectEventDispatcher(mepManager, new TestEventDispatcher());
+
+        mepService = mepManager;
+        mepManager.activate();
+
+        mep1 = DefaultMep.builder(MEPID1, DEVICE_ID1, PortNumber.P0,
+                Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build();
+        mep2 = DefaultMep.builder(MEPID2, DEVICE_ID2, PortNumber.portNumber(2),
+                Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build();
+        List<Mep> mepList = new ArrayList<>();
+        mepList.add(mep1);
+        mepList.add(mep2);
+        TestUtils.setField(mepManager, "mepCollection", mepList);
+
+        device1 = new DefaultDevice(
+                ProviderId.NONE, DEVICE_ID1, Device.Type.SWITCH,
+                TEST_MFR, TEST_HW_VERSION, TEST_SW_VERSION, TEST_SN,
+                new ChassisId(1),
+                DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, TEST_DRIVER).build());
+
+        device2 = new DefaultDevice(
+                ProviderId.NONE, DEVICE_ID2, Device.Type.SWITCH,
+                TEST_MFR, TEST_HW_VERSION, TEST_SW_VERSION, TEST_SN,
+                new ChassisId(2),
+                DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, TEST_DRIVER).build());
+
+        AbstractProjectableModel.setDriverService(null, driverService);
+
+        Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours = new HashMap<>();
+        behaviours.put(DeviceDescriptionDiscovery.class, TestDeviceDiscoveryBehavior.class);
+        behaviours.put(CfmMepProgrammable.class, TestCfmMepProgrammable.class);
+        behaviours.put(SoamDmProgrammable.class, TestSoamDmProgrammable.class);
+
+        testDriver = new DefaultDriver(
+                TEST_DRIVER, new ArrayList<Driver>(),
+                TEST_MFR, TEST_HW_VERSION, TEST_SW_VERSION,
+                behaviours, new HashMap<>());
+    }
+
+
+    @After
+    public void tearDown() {
+//        mepManager.deactivate();
+    }
+
+    @Test
+    public void testGetAllMeps() throws CfmConfigException {
+
+        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
+                .andReturn(Optional.ofNullable(ma1))
+                .anyTimes();
+        replay(mdService);
+
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        expect(deviceService.getDevice(DEVICE_ID2)).andReturn(device2).anyTimes();
+        replay(deviceService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        Collection<MepEntry> mepEntries = mepManager.getAllMeps(MDNAME1, MANAME1);
+
+        assertEquals(2, mepEntries.size());
+    }
+
+    @Test
+    public void testGetMep() throws CfmConfigException {
+
+        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
+                .andReturn(Optional.ofNullable(ma1))
+                .anyTimes();
+        replay(mdService);
+
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        MepEntry mepEntry = mepManager.getMep(MDNAME1, MANAME1, MEPID1);
+
+        assertEquals(MEPID1.value(), mepEntry.mepId().value());
+    }
+
+    @Test
+    public void testGetMepMissing() {
+
+        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
+                .andReturn(Optional.ofNullable(ma1))
+                .anyTimes();
+        replay(mdService);
+
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(null).anyTimes();
+        replay(deviceService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        try {
+            mepManager.getMep(MDNAME1, MANAME1, MEPID1);
+            fail("Expecting CfmConfigException because device does not exist");
+        } catch (CfmConfigException e) {
+            assertEquals("Device not found netconf:1.2.3.4:830", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testDeleteMep() throws CfmConfigException {
+        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
+                .andReturn(Optional.ofNullable(ma1))
+                .anyTimes();
+        replay(mdService);
+
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        assertTrue(mepManager.deleteMep(MDNAME1, MANAME1, MEPID1));
+    }
+
+    @Test
+    public void testCreateMep() throws CfmConfigException {
+        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
+                .andReturn(Optional.ofNullable(ma1))
+                .anyTimes();
+        replay(mdService);
+
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        MepId mepId3 = MepId.valueOf((short) 3);
+        Mep mep3 = DefaultMep.builder(mepId3, DEVICE_ID1, PortNumber.portNumber(1),
+                Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build();
+
+        assertTrue(mepManager.createMep(MDNAME1, MANAME1, mep3));
+    }
+
+    @Test
+    public void testCreateMepBehaviorNotSupported() throws CfmConfigException {
+        final DeviceId deviceId3 = DeviceId.deviceId("netconf:3.2.3.4:830");
+
+        Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours = new HashMap<>();
+        behaviours.put(DeviceDescriptionDiscovery.class, TestDeviceDiscoveryBehavior.class);
+
+        Driver testDriver3 = new DefaultDriver(
+                TEST_DRIVER_3, new ArrayList<Driver>(),
+                TEST_MFR, TEST_HW_VERSION, TEST_SW_3,
+                behaviours, new HashMap<>());
+
+        Device device3 = new DefaultDevice(
+                ProviderId.NONE, deviceId3, Device.Type.SWITCH,
+                TEST_MFR, TEST_HW_VERSION, TEST_SW_3, TEST_SN,
+                new ChassisId(2),
+                DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, TEST_DRIVER_3).build());
+
+        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
+                .andReturn(Optional.ofNullable(ma1))
+                .anyTimes();
+        replay(mdService);
+
+        expect(deviceService.getDevice(deviceId3)).andReturn(device3).anyTimes();
+        replay(deviceService);
+
+        expect(driverService.getDriver(TEST_DRIVER_3)).andReturn(testDriver3).anyTimes();
+        replay(driverService);
+
+        MepId mepId3 = MepId.valueOf((short) 3);
+        Mep mep3 = DefaultMep.builder(mepId3, deviceId3, PortNumber.portNumber(1),
+                Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build();
+
+        try {
+            mepManager.createMep(MDNAME1, MANAME1, mep3);
+            fail("Expecting CfmConfigException because driver does not support behavior");
+        } catch (CfmConfigException e) {
+            assertEquals("Device netconf:3.2.3.4:830 does not support " +
+                    "CfmMepProgrammable behaviour.", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testTransmitLoopback() {
+        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
+                .andReturn(Optional.ofNullable(ma1))
+                .anyTimes();
+        replay(mdService);
+
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        MepLbCreate lbCreate = DefaultMepLbCreate.builder(MepId.valueOf((short) 11)).build();
+        try {
+            mepService.transmitLoopback(MDNAME1, MANAME1, MEPID1, lbCreate);
+        } catch (CfmConfigException e) {
+            fail("Not expecting an exception");
+        }
+    }
+
+    @Test
+    public void testAbortLoopback() {
+        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
+                .andReturn(Optional.ofNullable(ma1))
+                .anyTimes();
+        replay(mdService);
+
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        try {
+            mepService.abortLoopback(MDNAME1, MANAME1, MEPID1);
+        } catch (CfmConfigException e) {
+            fail("Not expecting an exception");
+        }
+    }
+
+    @Test
+    public void testTransmitLinktrace() throws CfmConfigException {
+        expect(mdService.getMaintenanceAssociation(MDNAME1, MANAME1))
+                .andReturn(Optional.ofNullable(ma1))
+                .anyTimes();
+        replay(mdService);
+
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        MepLtCreate ltCreate = DefaultMepLtCreate.builder(MepId.valueOf((short) 11)).build();
+        try {
+            mepService.transmitLinktrace(MDNAME1, MANAME1, MEPID1, ltCreate);
+        } catch (UnsupportedOperationException e) {
+            assertEquals("Not yet implemented", e.getMessage());
+        }
+    }
+
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/TestCfmMepProgrammable.java b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/TestCfmMepProgrammable.java
new file mode 100644
index 0000000..8d0f765
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/TestCfmMepProgrammable.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.cfm.impl;
+
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMep;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
+import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepLbCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepLtCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepProgrammable;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import static org.onosproject.incubator.net.l2monitoring.cfm.impl.CfmMepManagerTest.*;
+
+/**
+ * A dummy implementation of the CfmMepProgrammable for test purposes.
+ */
+public class TestCfmMepProgrammable extends AbstractHandlerBehaviour implements CfmMepProgrammable {
+
+    private List<Mep> deviceMepList;
+
+    public TestCfmMepProgrammable() throws CfmConfigException {
+        deviceMepList = new ArrayList<>();
+
+        deviceMepList.add(DefaultMep.builder(MEPID1, DEVICE_ID1, PortNumber.P0,
+                Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build());
+        deviceMepList.add(DefaultMep.builder(MEPID2, DEVICE_ID2, PortNumber.portNumber(2),
+                Mep.MepDirection.UP_MEP, MDNAME1, MANAME1).build());
+    }
+
+    @Override
+    public Collection<MepEntry> getAllMeps(MdId mdName, MaIdShort maName) throws CfmConfigException {
+        return null;
+    }
+
+    @Override
+    public MepEntry getMep(MdId mdName, MaIdShort maName, MepId mepId) throws CfmConfigException {
+        for (Mep mep:deviceMepList) {
+            if (mep.mdId().equals(mdName) && mep.maId().equals(maName) && mep.mepId().equals(mepId)) {
+                return DefaultMepEntry.builder(mep).buildEntry();
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public boolean deleteMep(MdId mdName, MaIdShort maName, MepId mepId) throws CfmConfigException {
+        return true;
+    }
+
+    @Override
+    public boolean createMep(MdId mdName, MaIdShort maName, Mep mep) throws CfmConfigException {
+        return true;
+    }
+
+    @Override
+    public void transmitLoopback(MdId mdName, MaIdShort maName, MepId mepId, MepLbCreate lbCreate)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public void abortLoopback(MdId mdName, MaIdShort maName, MepId mepId) throws CfmConfigException {
+
+    }
+
+    @Override
+    public void transmitLinktrace(MdId mdName, MaIdShort maName, MepId mepId, MepLtCreate ltCreate)
+            throws CfmConfigException {
+
+    }
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/TestDeviceDiscoveryBehavior.java b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/TestDeviceDiscoveryBehavior.java
new file mode 100644
index 0000000..01d3d01
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/cfm/impl/TestDeviceDiscoveryBehavior.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.cfm.impl;
+
+import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.PortDescription;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+
+import java.util.List;
+
+public class TestDeviceDiscoveryBehavior extends AbstractHandlerBehaviour
+        implements DeviceDescriptionDiscovery {
+
+    @Override
+    public DeviceDescription discoverDeviceDetails() {
+        return null;
+    }
+
+    @Override
+    public List<PortDescription> discoverPortDetails() {
+        return null;
+    }
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/soam/impl/SoamManagerTest.java b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/soam/impl/SoamManagerTest.java
new file mode 100644
index 0000000..251cc71
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/soam/impl/SoamManagerTest.java
@@ -0,0 +1,470 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.soam.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.packet.ChassisId;
+import org.onosproject.common.event.impl.TestEventDispatcher;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.incubator.net.l2monitoring.cfm.DefaultMepEntry;
+import org.onosproject.incubator.net.l2monitoring.cfm.MaintenanceAssociation;
+import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepEntry;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdIdCharStr;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
+import org.onosproject.incubator.net.l2monitoring.cfm.impl.TestCfmMepProgrammable;
+import org.onosproject.incubator.net.l2monitoring.cfm.impl.TestDeviceDiscoveryBehavior;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMdService;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepProgrammable;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmMepService;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamDmProgrammable;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamService;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementCreate;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementEntry;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatCurrent;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatHistory;
+import org.onosproject.net.AbstractProjectableModel;
+import org.onosproject.net.AnnotationKeys;
+import org.onosproject.net.DefaultAnnotations;
+import org.onosproject.net.DefaultDevice;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.device.DeviceDescriptionDiscovery;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.Behaviour;
+import org.onosproject.net.driver.DefaultDriver;
+import org.onosproject.net.driver.Driver;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.provider.ProviderId;
+
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicLong;
+
+import static junit.framework.TestCase.assertEquals;
+import static junit.framework.TestCase.assertNotNull;
+import static junit.framework.TestCase.fail;
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.NetTestTools.injectEventDispatcher;
+
+/**
+ * Services OAM Manager test.
+ */
+public class SoamManagerTest {
+    private static final String TEST_MFR = "testMfr";
+    private static final String TEST_HW_VERSION = "testHwVersion";
+    private static final String TEST_SW_VERSION = "testSwVersion";
+    private static final String TEST_SN = "testSn";
+    private static final String TEST_DRIVER = "testDriver";
+    public static final String TEST_DRIVER_3 = "testDriver3";
+    public static final String TEST_SW_3 = "testSw3";
+
+
+    protected static final MdId MDNAME1 = MdIdCharStr.asMdId("md-1");
+    protected static final MaIdShort MANAME1 = MaIdCharStr.asMaId("ma-1-1");
+    protected static final MepId MEPID1 = MepId.valueOf((short) 10);
+    protected static final DeviceId DEVICE_ID1 = DeviceId.deviceId("netconf:1.2.3.4:830");
+    protected static final SoamId DMID101 = SoamId.valueOf(101);
+    protected static final SoamId DMID102 = SoamId.valueOf(102);
+    protected static final SoamId LMID101 = SoamId.valueOf(201);
+
+    private MaintenanceAssociation ma1;
+    private MepEntry mep1;
+
+    private SoamManager soamManager;
+    private SoamService soamService;
+
+    private final CfmMdService mdService = createMock(CfmMdService.class);
+    private CfmMepService mepService = createMock(CfmMepService.class);
+    private final DeviceService deviceService = createMock(DeviceService.class);
+    private final DriverService driverService = createMock(DriverService.class);
+    private Device device1;
+    private Driver testDriver;
+
+    @Before
+    public void setup() throws CfmConfigException, SoamConfigException {
+        soamManager = new SoamManager();
+        TestUtils.setField(soamManager, "coreService", new TestCoreService());
+        TestUtils.setField(soamManager, "cfmMepService", mepService);
+        TestUtils.setField(soamManager, "deviceService", deviceService);
+
+        injectEventDispatcher(soamManager, new TestEventDispatcher());
+        soamService = soamManager;
+        soamManager.activate();
+
+        DelayMeasurementEntry dmEntry1 = DefaultDelayMeasurementEntry
+                .builder(DMID101, DelayMeasurementCreate.DmType.DM1DMTX,
+                        DelayMeasurementCreate.Version.Y17312011,
+                        MepId.valueOf((short) 11), Mep.Priority.PRIO5).build();
+        DelayMeasurementEntry dmEntry2 = DefaultDelayMeasurementEntry
+                .builder(DMID102, DelayMeasurementCreate.DmType.DM1DMTX,
+                        DelayMeasurementCreate.Version.Y17312011,
+                        MepId.valueOf((short) 11), Mep.Priority.PRIO6).build();
+
+        mep1 = DefaultMepEntry.builder(MEPID1, DEVICE_ID1, PortNumber.P0,
+                Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
+                .addToDelayMeasurementList(dmEntry1)
+                .addToDelayMeasurementList(dmEntry2)
+                .buildEntry();
+
+        device1 = new DefaultDevice(
+                ProviderId.NONE, DEVICE_ID1, Device.Type.SWITCH,
+                TEST_MFR, TEST_HW_VERSION, TEST_SW_VERSION, TEST_SN,
+                new ChassisId(1),
+                DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, TEST_DRIVER).build());
+
+        AbstractProjectableModel.setDriverService(null, driverService);
+
+        Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours = new HashMap<>();
+        behaviours.put(DeviceDescriptionDiscovery.class, TestDeviceDiscoveryBehavior.class);
+        behaviours.put(CfmMepProgrammable.class, TestCfmMepProgrammable.class);
+        behaviours.put(SoamDmProgrammable.class, TestSoamDmProgrammable.class);
+
+        testDriver = new DefaultDriver(
+                TEST_DRIVER, new ArrayList<Driver>(),
+                TEST_MFR, TEST_HW_VERSION, TEST_SW_VERSION,
+                behaviours, new HashMap<>());
+
+    }
+
+    @After
+    public void tearDown() {
+//        soamManager.deactivate();
+    }
+
+    @Test
+    public void testGetAllDms() throws CfmConfigException, SoamConfigException {
+
+        expect(mepService.getMep(MDNAME1, MANAME1, MEPID1)).andReturn(mep1).anyTimes();
+        replay(mepService);
+
+        Collection<DelayMeasurementEntry> dmEntries =
+                soamManager.getAllDms(MDNAME1, MANAME1, MEPID1);
+        assertEquals(2, dmEntries.size());
+    }
+
+    @Test
+    public void testGetDm() throws CfmConfigException, SoamConfigException {
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(mepService.getMep(MDNAME1, MANAME1, MEPID1)).andReturn(mep1).anyTimes();
+        replay(mepService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        DelayMeasurementEntry dmEntry =
+                soamManager.getDm(MDNAME1, MANAME1, MEPID1, DMID101);
+
+        assertNotNull(dmEntry);
+        assertEquals(DMID101, dmEntry.dmId());
+    }
+
+    @Test
+    public void testGetDmCurrentStat() throws CfmConfigException, SoamConfigException {
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(mepService.getMep(MDNAME1, MANAME1, MEPID1)).andReturn(mep1).anyTimes();
+        replay(mepService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        DelayMeasurementStatCurrent dmCurrentStat =
+                soamManager.getDmCurrentStat(MDNAME1, MANAME1, MEPID1, DMID101);
+
+        assertNotNull(dmCurrentStat);
+        assertTrue(dmCurrentStat.startTime().isBefore(Instant.now()));
+    }
+
+    @Test
+    public void testGetDmHistoryStats() throws CfmConfigException, SoamConfigException {
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(mepService.getMep(MDNAME1, MANAME1, MEPID1)).andReturn(mep1).anyTimes();
+        replay(mepService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        Collection<DelayMeasurementStatHistory> dmHistoricalStats =
+                soamManager.getDmHistoricalStats(MDNAME1, MANAME1, MEPID1, DMID101);
+
+        assertNotNull(dmHistoricalStats);
+        assertEquals(2, dmHistoricalStats.size());
+    }
+
+    @Test
+    public void testCreateDm() throws CfmConfigException, SoamConfigException {
+        expect(deviceService.getDevice(DEVICE_ID1)).andReturn(device1).anyTimes();
+        replay(deviceService);
+
+        expect(mepService.getMep(MDNAME1, MANAME1, MEPID1)).andReturn(mep1).anyTimes();
+        replay(mepService);
+
+        expect(driverService.getDriver(TEST_DRIVER)).andReturn(testDriver).anyTimes();
+        replay(driverService);
+
+        DelayMeasurementCreate dmCreate1 = DefaultDelayMeasurementCreate
+                .builder(DelayMeasurementCreate.DmType.DM1DMTX,
+                    DelayMeasurementCreate.Version.Y17312011,
+                    MepId.valueOf((short) 11), Mep.Priority.PRIO3)
+                .binsPerFdInterval((short) 4)
+                .binsPerFdrInterval((short) 5)
+                .binsPerIfdvInterval((short) 6)
+                .build();
+
+        assertEquals(1000, soamManager.createDm(
+                    MDNAME1, MANAME1, MEPID1, dmCreate1).get().value());
+    }
+
+    @Test
+    public void testCreateDmNoBehavior() throws CfmConfigException, SoamConfigException {
+        final DeviceId deviceId3 = DeviceId.deviceId("netconf:3.2.3.4:830");
+        final MepId mepId3 = MepId.valueOf((short) 3);
+
+        Map<Class<? extends Behaviour>, Class<? extends Behaviour>> behaviours = new HashMap<>();
+        behaviours.put(DeviceDescriptionDiscovery.class, TestDeviceDiscoveryBehavior.class);
+
+        Driver testDriver3 = new DefaultDriver(
+                TEST_DRIVER_3, new ArrayList<Driver>(),
+                TEST_MFR, TEST_HW_VERSION, TEST_SW_3,
+                behaviours, new HashMap<>());
+
+        Device device3 = new DefaultDevice(
+                ProviderId.NONE, deviceId3, Device.Type.SWITCH,
+                TEST_MFR, TEST_HW_VERSION, TEST_SW_3, TEST_SN,
+                new ChassisId(2),
+                DefaultAnnotations.builder().set(AnnotationKeys.DRIVER, TEST_DRIVER_3).build());
+
+        expect(deviceService.getDevice(deviceId3)).andReturn(device3).anyTimes();
+        replay(deviceService);
+
+        MepEntry mep3 = DefaultMepEntry.builder(mepId3, deviceId3, PortNumber.P0,
+                Mep.MepDirection.UP_MEP, MDNAME1, MANAME1)
+                .buildEntry();
+
+        expect(mepService.getMep(MDNAME1, MANAME1, mepId3)).andReturn(mep3).anyTimes();
+        replay(mepService);
+
+        expect(driverService.getDriver(TEST_DRIVER_3)).andReturn(testDriver3).anyTimes();
+        replay(driverService);
+
+        DelayMeasurementCreate dmCreate1 = DefaultDelayMeasurementCreate
+                .builder(DelayMeasurementCreate.DmType.DM1DMTX,
+                        DelayMeasurementCreate.Version.Y17312011,
+                        MepId.valueOf((short) 11), Mep.Priority.PRIO3)
+                .binsPerFdInterval((short) 4)
+                .binsPerFdrInterval((short) 5)
+                .binsPerIfdvInterval((short) 6)
+                .build();
+
+        try {
+            soamManager.createDm(MDNAME1, MANAME1, mepId3, dmCreate1);
+            fail("Expecting exception since device does not support behavior");
+        } catch (CfmConfigException e) {
+            assertEquals("Device netconf:3.2.3.4:830 from MEP :md-1/" +
+                    "ma-1-1/3 does not implement SoamDmProgrammable", e.getMessage());
+        }
+    }
+
+    @Test
+    public void testAbortAllDmOnMep() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.abortDm(MDNAME1, MANAME1, MEPID1);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testAbortOneDm() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.abortDm(MDNAME1, MANAME1, MEPID1, DMID101);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testClearAllDmHistoriesOnMep() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.clearDelayHistoryStats(MDNAME1, MANAME1, MEPID1);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testClearOneDmHistories() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.clearDelayHistoryStats(MDNAME1, MANAME1, MEPID1, DMID101);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testGetAllLmsOnMep() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.getAllLms(MDNAME1, MANAME1, MEPID1);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testGetLm() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.getLm(MDNAME1, MANAME1, MEPID1, LMID101);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testGetLmCurrentStat() {
+        //TODO: Implement underlying method
+        try {
+            soamManager.getLmCurrentStat(MDNAME1, MANAME1, MEPID1, LMID101);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testGetLmhistoricalStats() {
+        //TODO: Implement underlying method
+        try {
+            soamManager.getLmHistoricalStats(MDNAME1, MANAME1, MEPID1, LMID101);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testCreateLm() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.createLm(MDNAME1, MANAME1, MEPID1, null);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testAbortAllLmOnMep() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.abortLm(MDNAME1, MANAME1, MEPID1);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testAbortOneLm() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.abortLm(MDNAME1, MANAME1, MEPID1, LMID101);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testClearAllLossHistoryStatsOnMep() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.clearLossHistoryStats(MDNAME1, MANAME1, MEPID1);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testClearLossHistoryStatsOnLm() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.clearLossHistoryStats(MDNAME1, MANAME1, MEPID1, LMID101);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testCreateTestSignal() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.createTestSignal(MDNAME1, MANAME1, MEPID1, null);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    @Test
+    public void testAbortTestSignal() throws CfmConfigException {
+        //TODO: Implement underlying method
+        try {
+            soamManager.abortTestSignal(MDNAME1, MANAME1, MEPID1);
+            fail("Expecting UnsupportedOperationException");
+        } catch (UnsupportedOperationException e) {
+        }
+    }
+
+    protected class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public IdGenerator getIdGenerator(String topic) {
+            return new IdGenerator() {
+                private AtomicLong counter = new AtomicLong(0);
+
+                @Override
+                public long getNewId() {
+                    return counter.getAndIncrement();
+                }
+            };
+        }
+    }
+}
diff --git a/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/soam/impl/TestSoamDmProgrammable.java b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/soam/impl/TestSoamDmProgrammable.java
new file mode 100644
index 0000000..8d010de
--- /dev/null
+++ b/incubator/net/src/test/java/org/onosproject/incubator/net/l2monitoring/soam/impl/TestSoamDmProgrammable.java
@@ -0,0 +1,238 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.incubator.net.l2monitoring.soam.impl;
+
+import org.onosproject.incubator.net.l2monitoring.cfm.Mep;
+import org.onosproject.incubator.net.l2monitoring.cfm.MepTsCreate;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MaIdShort;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MdId;
+import org.onosproject.incubator.net.l2monitoring.cfm.identifier.MepId;
+import org.onosproject.incubator.net.l2monitoring.cfm.service.CfmConfigException;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamConfigException;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamDmProgrammable;
+import org.onosproject.incubator.net.l2monitoring.soam.SoamId;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementEntry;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementStatCurrent;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DefaultDelayMeasurementStatHistory;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementCreate;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementEntry;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatCurrent;
+import org.onosproject.incubator.net.l2monitoring.soam.delay.DelayMeasurementStatHistory;
+import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementCreate;
+import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementEntry;
+import org.onosproject.incubator.net.l2monitoring.soam.loss.LossMeasurementStatCurrent;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Optional;
+
+import static org.onosproject.incubator.net.l2monitoring.soam.impl.SoamManagerTest.*;
+
+/**
+ * A dummy implementation of the SoamDmProgrammable for test purposes.
+ */
+public class TestSoamDmProgrammable extends AbstractHandlerBehaviour implements SoamDmProgrammable {
+    private DelayMeasurementEntry dmEntry1;
+
+    public TestSoamDmProgrammable() throws SoamConfigException {
+        long nowMs = System.currentTimeMillis();
+        long lastSecond = nowMs - nowMs % 1000;
+        DelayMeasurementStatCurrent current =
+                (DelayMeasurementStatCurrent) DefaultDelayMeasurementStatCurrent
+                        .builder(Duration.ofSeconds(37), false)
+                    .startTime(Instant.ofEpochMilli(lastSecond))
+                    .build();
+
+        long lastMinute = nowMs - nowMs % (60 * 1000);
+        DelayMeasurementStatHistory history1 =
+                (DelayMeasurementStatHistory) DefaultDelayMeasurementStatHistory
+                .builder(SoamId.valueOf(67), Duration.ofSeconds(60), false)
+                .endTime(Instant.ofEpochMilli(lastMinute))
+                .frameDelayForwardMin(Duration.ofMillis(107))
+                .frameDelayForwardMax(Duration.ofMillis(109))
+                .frameDelayForwardAvg(Duration.ofMillis(108))
+                .build();
+
+        long lastMinute2 = lastMinute - (60 * 1000);
+        DelayMeasurementStatHistory history2 =
+                (DelayMeasurementStatHistory) DefaultDelayMeasurementStatHistory
+                        .builder(SoamId.valueOf(66), Duration.ofSeconds(60), false)
+                        .endTime(Instant.ofEpochMilli(lastMinute2))
+                        .frameDelayForwardMin(Duration.ofMillis(117))
+                        .frameDelayForwardMax(Duration.ofMillis(119))
+                        .frameDelayForwardAvg(Duration.ofMillis(118))
+                        .build();
+
+        dmEntry1 = DefaultDelayMeasurementEntry
+                .builder(DMID101, DelayMeasurementCreate.DmType.DM1DMTX,
+                        DelayMeasurementCreate.Version.Y17312011,
+                        MepId.valueOf((short) 11), Mep.Priority.PRIO5)
+                .currentResult(current)
+                .addToHistoricalResults(history1)
+                .addToHistoricalResults(history2)
+                .build();
+    }
+
+    @Override
+    public Collection<DelayMeasurementEntry> getAllDms(
+            MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException, SoamConfigException {
+        return null;
+    }
+
+    @Override
+    public DelayMeasurementEntry getDm(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
+            throws CfmConfigException, SoamConfigException {
+        if (mdName.equals(MDNAME1) && maName.equals(MANAME1) && mepId.equals(MEPID1)) {
+            return dmEntry1;
+        }
+        return null;
+    }
+
+    @Override
+    public DelayMeasurementStatCurrent getDmCurrentStat(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
+            throws CfmConfigException, SoamConfigException {
+        if (mdName.equals(MDNAME1) && maName.equals(MANAME1) && mepId.equals(MEPID1)) {
+            return dmEntry1.currentResult();
+        }
+        return null;
+    }
+
+    @Override
+    public Collection<DelayMeasurementStatHistory> getDmHistoricalStats(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
+            throws CfmConfigException, SoamConfigException {
+        if (mdName.equals(MDNAME1) && maName.equals(MANAME1) && mepId.equals(MEPID1)) {
+            return dmEntry1.historicalResults();
+        }
+        return null;
+    }
+
+    @Override
+    public Optional<SoamId> createDm(
+            MdId mdName, MaIdShort maName, MepId mepId, DelayMeasurementCreate dm)
+            throws CfmConfigException, SoamConfigException {
+        return Optional.ofNullable(SoamId.valueOf(1000));
+    }
+
+    @Override
+    public void abortDm(
+            MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public void abortDm(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public void clearDelayHistoryStats(
+            MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public void clearDelayHistoryStats(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId dmId)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public Collection<LossMeasurementEntry> getAllLms(
+            MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException, SoamConfigException {
+        return null;
+    }
+
+    @Override
+    public LossMeasurementEntry getLm(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId lmId)
+            throws CfmConfigException, SoamConfigException {
+        return null;
+    }
+
+    @Override
+    public LossMeasurementStatCurrent getLmCurrentStat(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId lmId) {
+        return null;
+    }
+
+    @Override
+    public Collection<LossMeasurementStatCurrent> getLmHistoricalStats(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId lmId) {
+        return new ArrayList<LossMeasurementStatCurrent>();
+    }
+
+    @Override
+    public Optional<SoamId> createLm(
+            MdId mdName, MaIdShort maName, MepId mepId, LossMeasurementCreate lm)
+            throws CfmConfigException, SoamConfigException {
+        return Optional.empty();
+    }
+
+    @Override
+    public void abortLm(
+            MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public void abortLm(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId lmId)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public void clearLossHistoryStats(
+            MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public void clearLossHistoryStats(
+            MdId mdName, MaIdShort maName, MepId mepId, SoamId lmId)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public void createTestSignal(
+            MdId mdName, MaIdShort maName, MepId mepId, MepTsCreate tsCreate)
+            throws CfmConfigException {
+
+    }
+
+    @Override
+    public void abortTestSignal(
+            MdId mdName, MaIdShort maName, MepId mepId)
+            throws CfmConfigException {
+
+    }
+}
\ No newline at end of file
