diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
index 85d6e1e..f820bcb 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/RoutingRulePopulator.java
@@ -589,15 +589,20 @@
             return false;
         }
         fwdObjs.addAll(fwdObjsMpls);
-        // Generates the transit rules used by the MPLS Pwaas. For now it is
-        // the only case !BoS supported.
-        /*
-        fwdObjsMpls = handleMpls(targetSwId, destSwId, nextHops, segmentId, routerIp, false);
+
+        // Generates the transit rules used by the MPLS Pwaas.
+        int pwSrLabel;
+        try {
+            pwSrLabel = config.getPWRoutingLabel(destSwId);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting populateMplsRule. No label for PseudoWire traffic.");
+            return false;
+        }
+        fwdObjsMpls = handleMpls(targetSwId, destSwId, nextHops, pwSrLabel, routerIp, false);
         if (fwdObjsMpls.isEmpty()) {
             return false;
         }
         fwdObjs.addAll(fwdObjsMpls);
-        */
 
         for (ForwardingObjective fwdObj : fwdObjs) {
             log.debug("Sending MPLS fwd obj {} for SID {}-> next {} in sw: {}",
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index cd34844..6092716 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -31,6 +31,7 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
 
+import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.collect.Sets;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -105,6 +106,8 @@
 import org.onosproject.segmentrouting.grouphandler.DefaultGroupHandler;
 import org.onosproject.segmentrouting.grouphandler.DestinationSet;
 import org.onosproject.segmentrouting.grouphandler.NextNeighbors;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
 import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
 import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
 import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
@@ -429,7 +432,9 @@
                         TunnelPolicy.class,
                         Policy.Type.class,
                         PortNextObjectiveStoreKey.class,
-                        XConnectStoreKey.class
+                        XConnectStoreKey.class,
+                        DefaultL2Tunnel.class,
+                        DefaultL2TunnelPolicy.class
                 );
     }
 
@@ -504,6 +509,67 @@
     }
 
     @Override
+    public List<DefaultL2Tunnel> getL2Tunnels() {
+        return l2TunnelHandler.getL2Tunnels();
+    }
+
+    @Override
+    public List<DefaultL2TunnelPolicy> getL2Policies() {
+        return l2TunnelHandler.getL2Policies();
+    }
+
+    @Override
+    public L2TunnelHandler.Result addPseudowire(String tunnelId, String pwLabel, String cP1,
+                                         String cP1InnerVlan, String cP1OuterVlan, String cP2,
+                                         String cP2InnerVlan, String cP2OuterVlan,
+                                         String mode, String sdTag) {
+
+        PwaasConfig config = cfgService.getConfig(appId(), PwaasConfig.class);
+        if (config == null) {
+            log.warn("Configuration for Pwaas class could not be found!");
+            return L2TunnelHandler.Result.CONFIG_NOT_FOUND;
+        }
+
+        ObjectNode object = config.addPseudowire(tunnelId, pwLabel,
+                                                 cP1, cP1InnerVlan, cP1OuterVlan,
+                                                 cP2, cP2InnerVlan, cP2OuterVlan,
+                                                 mode, sdTag);
+        if (object == null) {
+            log.warn("Could not add pseudowire to the configuration!");
+            return L2TunnelHandler.Result.ADDITION_ERROR;
+        }
+
+        // inform everyone about the valid change in the pw configuration
+        cfgService.applyConfig(appId(), PwaasConfig.class, object);
+        return L2TunnelHandler.Result.SUCCESS;
+    }
+
+    @Override
+    public L2TunnelHandler.Result removePseudowire(String pwId) {
+
+        PwaasConfig config = cfgService.getConfig(appId(), PwaasConfig.class);
+        if (config == null) {
+            log.warn("Configuration for Pwaas class could not be found!");
+            return L2TunnelHandler.Result.CONFIG_NOT_FOUND;
+        }
+
+        ObjectNode object = config.removePseudowire(pwId);
+        if (object == null) {
+            log.warn("Could not delete pseudowire from configuration!");
+            return L2TunnelHandler.Result.REMOVAL_ERROR;
+        }
+
+        // sanity check, this should never fail since we removed a pw
+        // and we always check when we update the configuration
+        config.isValid();
+
+        // inform everyone
+        cfgService.applyConfig(appId(), PwaasConfig.class, object);
+
+        return L2TunnelHandler.Result.SUCCESS;
+    }
+
+    @Override
     public void rerouteNetwork() {
         cfgListener.configureNetwork();
     }
@@ -711,7 +777,7 @@
      * @param cp connect point
      * @return true if current instance is the master of given connect point
      */
-    boolean isMasterOf(ConnectPoint cp) {
+    public boolean isMasterOf(ConnectPoint cp) {
         boolean isMaster = mastershipService.isLocalMaster(cp.deviceId());
         if (!isMaster) {
             log.debug(NOT_MASTER, cp);
@@ -1244,6 +1310,7 @@
         }
 
         mcastHandler.processLinkDown(link);
+        l2TunnelHandler.processLinkDown(link);
     }
 
     private void processDeviceAdded(Device device) {
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
index 3668ba2..4ef6079 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
@@ -18,6 +18,9 @@
 import org.onlab.packet.IpPrefix;
 import org.onosproject.net.DeviceId;
 import org.onosproject.segmentrouting.grouphandler.NextNeighbors;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
 import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
 
 import com.google.common.collect.ImmutableMap;
@@ -79,6 +82,49 @@
     List<Policy> getPolicies();
 
     /**
+     * Returns all l2 tunnels of pseudowires.
+     *
+     * @return list of l2 tunnels
+     */
+    List<DefaultL2Tunnel> getL2Tunnels();
+
+    /**
+     * Returns all l2 policie of pseudowires.
+     *
+     * @return list of l2 policies.
+     */
+    List<DefaultL2TunnelPolicy> getL2Policies();
+
+    /**
+     * Removes pw. Essentially updates configuration for PwaasConfig
+     * and sends event for removal. The rest are handled by L2TunnelHandler
+     *
+     * @param pwId The pseudowire id
+     * @return SUCCESS if operation successful or a descriptive error otherwise.
+     */
+    L2TunnelHandler.Result removePseudowire(String pwId);
+
+    /**
+     * Adds a Pseudowire to the configuration.
+     *
+     * @param tunnelId The pseudowire id
+     * @param pwLabel Pw label
+     * @param cP1 Connection Point 1 of pw
+     * @param cP1InnerVlan Outer vlan of cp2
+     * @param cP1OuterVlan Outer vlan of cp1
+     * @param cP2 Connection Point 2 of pw
+     * @param cP2InnerVlan Inner vlan of cp2
+     * @param cP2OuterVlan Outer vlan of cp1
+     * @param mode Mode of pw
+     * @param sdTag Service Delimiting tag of pw
+     * @return SUCCESS if operation is successful or a descriptive error otherwise.
+     */
+    L2TunnelHandler.Result addPseudowire(String tunnelId, String pwLabel, String cP1,
+                                         String cP1InnerVlan, String cP1OuterVlan, String cP2,
+                                         String cP2InnerVlan, String cP2OuterVlan,
+                                         String mode, String sdTag);
+
+    /**
      * Creates a policy.
      *
      * @param policy policy reference to create
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
new file mode 100644
index 0000000..d612475
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
@@ -0,0 +1,105 @@
+/*
+ * 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.segmentrouting.cli;
+
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
+
+
+/**
+ * Command to add a pseuwodire.
+ */
+@Command(scope = "onos", name = "pseudowire-add",
+        description = "Add a pseudowire to the network configuration, if it already exists update it.")
+public class PseudowireAddCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "pwId",
+            description = "Pseudowire ID",
+            required = true, multiValued = false)
+    String pwId;
+
+    @Argument(index = 1, name = "pwLabel",
+            description = "Pseudowire Label",
+            required = true, multiValued = false)
+    String pwLabel;
+
+    @Argument(index = 2, name = "mode",
+            description = "Mode used for pseudowire",
+            required = true, multiValued = false)
+    String mode;
+
+    @Argument(index = 3, name = "sDTag",
+            description = "Service delimiting tag",
+            required = true, multiValued = false)
+    String sDTag;
+
+    @Argument(index = 4, name = "cP1",
+            description = "Connection Point 1",
+            required = true, multiValued = false)
+    String cP1;
+
+    @Argument(index = 5, name = "cP1InnerVlan",
+            description = "Inner Vlan of Connection Point 1",
+            required = true, multiValued = false)
+    String cP1InnerVlan;
+
+    @Argument(index = 6, name = "cP1OuterVlan",
+            description = "Outer Vlan of Connection Point 1",
+            required = true, multiValued = false)
+    String cP1OuterVlan;
+
+    @Argument(index = 7, name = "cP2",
+            description = "Connection Point 2",
+            required = true, multiValued = false)
+    String cP2;
+
+    @Argument(index = 8, name = "cP2InnerVlan",
+            description = "Inner Vlan of Connection Point 2",
+            required = true, multiValued = false)
+    String cP2InnerVlan;
+
+    @Argument(index = 9, name = "cP2OuterVlan",
+            description = "Outer Vlan of Connection Point 2",
+            required = true, multiValued = false)
+    String cP2OuterVlan;
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        L2TunnelHandler.Result res = srService.addPseudowire(pwId, pwLabel,
+                                                             cP1, cP1InnerVlan, cP1OuterVlan,
+                                                             cP2, cP2InnerVlan, cP2OuterVlan,
+                                                             mode, sDTag);
+        switch (res) {
+            case ADDITION_ERROR:
+                print("Pseudowire could not be added, error in configuration, please check logs for more details!");
+                break;
+            case CONFIG_NOT_FOUND:
+                print("Configuration for pwaas was not found! Initialize the configuration first through netcfg.");
+                break;
+            default:
+                print("Pseudowire was added to the configuration succesfully, please do check logs for any errors!");
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireIdCompleter.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireIdCompleter.java
new file mode 100644
index 0000000..9022bec
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireIdCompleter.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2014-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.segmentrouting.cli;
+
+import org.apache.karaf.shell.console.Completer;
+import org.apache.karaf.shell.console.completer.StringsCompleter;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.stream.Collectors;
+
+/**
+ * Device ID completer.
+ */
+public class PseudowireIdCompleter implements Completer {
+    @Override
+    public int complete(String buffer, int cursor, List<String> candidates) {
+        // Delegate string completer
+        StringsCompleter delegate = new StringsCompleter();
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+
+        List<DefaultL2Tunnel> tunnels = srService.getL2Tunnels();
+
+        // combine polices and tunnels to pseudowires
+        Iterator<String> pseudowires = tunnels.stream()
+                .map(l2Tunnel -> Long.toString(l2Tunnel.tunnelId()))
+                .collect(Collectors.toList()).iterator();
+
+        SortedSet<String> strings = delegate.getStrings();
+        while (pseudowires.hasNext()) {
+            strings.add(pseudowires.next());
+        }
+
+        // Now let the completer do the work for figuring out what to offer.
+        return delegate.complete(buffer, cursor, candidates);
+    }
+
+}
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireListCommand.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireListCommand.java
new file mode 100644
index 0000000..18625db
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireListCommand.java
@@ -0,0 +1,84 @@
+/*
+ * 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.segmentrouting.cli;
+
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * Command to show the pseudowires.
+ */
+@Command(scope = "onos", name = "pseudowires",
+        description = "Lists all pseudowires")
+public class PseudowireListCommand extends AbstractShellCommand {
+
+    private static final String FORMAT_PSEUDOWIRE =
+            "Pseudowire id = %s \n" +
+                    "   mode : %s, sdTag : %s, pwLabel : %s \n" +
+                    "   cP1 : %s , cP1OuterTag : %s, cP1InnerTag : %s \n" +
+                    "   cP2 : %s , cP2OuterTag : %s, cP2InnerTag : %s \n" /* +
+                    "   Path used : (%s - %s) <-> (%s - %s) \n" */;
+
+                    // TODO:  uncomment string when path failures are fixed also for the links
+                    // TODO:  used in spine for pw traffic.
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        List<DefaultL2Tunnel> tunnels = srService.getL2Tunnels();
+        List<DefaultL2TunnelPolicy> policies = srService.getL2Policies();
+
+        // combine polices and tunnels to pseudowires
+        List<DefaultL2TunnelDescription> pseudowires = tunnels.stream()
+                                    .map(l2Tunnel -> {
+                                            DefaultL2TunnelPolicy policy = null;
+                                            for (DefaultL2TunnelPolicy l2Policy : policies) {
+                                                if (l2Policy.tunnelId() == l2Tunnel.tunnelId()) {
+                                                    policy = l2Policy;
+                                                    break;
+                                                }
+                                            }
+
+                                            return new DefaultL2TunnelDescription(l2Tunnel, policy);
+                                    })
+                                    .collect(Collectors.toList());
+
+        pseudowires.forEach(pw -> printPseudowire(pw));
+    }
+
+    private void printPseudowire(DefaultL2TunnelDescription pseudowire) {
+
+
+        print(FORMAT_PSEUDOWIRE, pseudowire.l2Tunnel().tunnelId(), pseudowire.l2Tunnel().pwMode(),
+              pseudowire.l2Tunnel().sdTag(), pseudowire.l2Tunnel().pwLabel(),
+              pseudowire.l2TunnelPolicy().cP1(), pseudowire.l2TunnelPolicy().cP1OuterTag(),
+              pseudowire.l2TunnelPolicy().cP1InnerTag(), pseudowire.l2TunnelPolicy().cP2(),
+              pseudowire.l2TunnelPolicy().cP2OuterTag(), pseudowire.l2TunnelPolicy().cP2InnerTag()/*,
+              pseudowire.l2Tunnel().pathUsed().get(0).src(), pseudowire.l2Tunnel().pathUsed().get(0).dst(),
+              pseudowire.l2Tunnel().pathUsed().get(1).src(), pseudowire.l2Tunnel().pathUsed().get(1).dst()*/);
+
+        // TODO: uncomment arguments when path issue is fixed for spine switches
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
new file mode 100644
index 0000000..782b339
--- /dev/null
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.segmentrouting.cli;
+
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.segmentrouting.SegmentRoutingManager;
+import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
+
+
+/**
+ * Command to remove a pseudowire.
+ */
+@Command(scope = "onos", name = "pseudowire-remove",
+        description = "Remove a pseudowire")
+public class PseudowireRemoveCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "pwId",
+            description = "pseudowire ID",
+            required = true, multiValued = false)
+    String pwId;
+
+    @Override
+    protected void execute() {
+
+        SegmentRoutingService srService =
+                AbstractShellCommand.get(SegmentRoutingService.class);
+
+        // remove the pseudowire
+        SegmentRoutingManager mngr = (SegmentRoutingManager) srService;
+        L2TunnelHandler.Result res = mngr.removePseudowire(pwId);
+
+        switch (res) {
+            case REMOVAL_ERROR:
+                error("Error in deletion, pseudowire not found!");
+                break;
+            case CONFIG_NOT_FOUND:
+                error("Could not fetch pseudowire class configuration!");
+                break;
+            default:
+                return;
+            }
+    }
+}
\ No newline at end of file
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
index 18169bb..321cf40 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
@@ -77,6 +77,7 @@
         Map<Integer, Set<Integer>> adjacencySids;
         DeviceId pairDeviceId;
         PortNumber pairLocalPort;
+        int pwRoutingLabel;
 
         public SegmentRouterInfo() {
             gatewayIps = HashMultimap.create();
@@ -113,6 +114,7 @@
             info.adjacencySids = config.adjacencySids();
             info.pairDeviceId = config.pairDeviceId();
             info.pairLocalPort = config.pairLocalPort();
+            info.pwRoutingLabel = info.ipv4NodeSid + 1000;
             deviceConfigMap.put(info.deviceId, info);
             log.debug("Read device config for device: {}", info.deviceId);
             /*
@@ -188,6 +190,7 @@
     @Override
     public int getIPv4SegmentId(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        log.info("DEVICE MAP IS {}", deviceConfigMap);
         if (srinfo != null) {
             log.trace("getIPv4SegmentId for device{} is {}", deviceId, srinfo.ipv4NodeSid);
             return srinfo.ipv4NodeSid;
@@ -209,6 +212,18 @@
         }
     }
 
+    @Override
+    public int getPWRoutingLabel(DeviceId deviceId) throws DeviceConfigNotFoundException {
+        SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
+        if (srinfo != null) {
+            log.trace("pwRoutingLabel for device{} is {}", deviceId, srinfo.pwRoutingLabel);
+            return srinfo.pwRoutingLabel;
+        } else {
+            String message = "getPWRoutingLabel fails for device: " + deviceId + ".";
+            throw new DeviceConfigNotFoundException(message);
+        }
+    }
+
     /**
      * Returns the IPv4 Node segment id of a segment router given its Router mac address.
      *
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java
index 64a2df7..2d0bbd2 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/DeviceProperties.java
@@ -66,6 +66,14 @@
     MacAddress getDeviceMac(DeviceId deviceId) throws DeviceConfigNotFoundException;
 
     /**
+     *
+     * @param deviceId device identifier
+     * @throws DeviceConfigNotFoundException if the device configuration is not found
+     * @return the pseudowire routing label for a leaf node
+     */
+    int getPWRoutingLabel(DeviceId deviceId) throws DeviceConfigNotFoundException;
+
+    /**
      * Returns the router ipv4 address of a segment router.
      *
      * @param deviceId device identifier
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java
index 74541cd..ed2c067 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java
@@ -17,13 +17,19 @@
 package org.onosproject.segmentrouting.config;
 
 import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.node.JsonNodeFactory;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.collect.ImmutableSet;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.onlab.packet.MplsLabel;
 import org.onlab.packet.VlanId;
+import org.onosproject.cli.AbstractShellCommand;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.config.Config;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.intf.InterfaceService;
 import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
 import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
 import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
@@ -31,13 +37,23 @@
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * App configuration object for Pwaas.
  */
 public class PwaasConfig extends Config<ApplicationId> {
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public InterfaceService intfService;
+
     private static Logger log = LoggerFactory
             .getLogger(PwaasConfig.class);
 
@@ -48,10 +64,24 @@
     private static final String SRC_INNER_TAG = "cP1InnerTag";
     private static final String DST_INNER_TAG = "cP2InnerTag";
     private static final String MODE = "mode";
-    private static final String ALL_VLAN = "allVlan";
     private static final String SD_TAG = "sdTag";
     private static final String PW_LABEL = "pwLabel";
 
+    public PwaasConfig(DeviceService devS, InterfaceService intfS) {
+
+        super();
+
+        deviceService = devS;
+        intfService = intfS;
+    }
+
+    public PwaasConfig() {
+
+        super();
+
+        deviceService = AbstractShellCommand.get(DeviceService.class);
+        intfService = AbstractShellCommand.get(InterfaceService.class);
+    }
     /**
      * Error message for missing parameters.
      */
@@ -63,21 +93,377 @@
     private static final String INVALID_L2_MODE = "Invalid pseudo wire mode";
 
     /**
+     * Error message for invalid VLAN.
+     */
+    private static final String INVALID_VLAN = "Vlan should be either int or */-";
+
+    /**
+     * Error message for invalid PW label.
+     */
+    private static final String INVALID_PW_LABEL = "Pseudowire label should be an integer";
+
+    /**
      * Verify if the pwaas configuration block is valid.
      *
+     * Here we try to ensure that the provided pseudowires will get instantiated
+     * correctly in the network. We also check for any collisions with already used
+     * interfaces and also between different pseudowires. Most of the restrictions stem
+     * from the fact that all vlan matching is done in table 10 of ofdpa.
+     *
      * @return true, if the configuration block is valid.
      *         False otherwise.
      */
     @Override
     public boolean isValid() {
+
+        Set<DefaultL2TunnelDescription> pseudowires;
         try {
-            getPwIds().forEach(this::getPwDescription);
+            pseudowires = getPwIds().stream()
+                    .map(this::getPwDescription)
+                    .collect(Collectors.toSet());
+
         } catch (IllegalArgumentException e) {
             log.warn("{}", e.getMessage());
             return false;
         }
-        return true;
 
+        // check semantics now and return
+        return configurationValidity(pseudowires);
+    }
+
+    /**
+     * Helper method to verify if the tunnel is whether or not
+     * supported.
+     *
+     * @param l2Tunnel the tunnel to verify
+     * @return the result of the verification
+     */
+    private void verifyTunnel(DefaultL2Tunnel l2Tunnel) {
+
+        // Service delimiting tag not supported yet.
+        if (!l2Tunnel.sdTag().equals(VlanId.NONE)) {
+            throw new IllegalArgumentException(String.format("Service delimiting tag not supported yet for " +
+                                                             "pseudowire %d.", l2Tunnel.tunnelId()));
+        }
+
+        // Tag mode not supported yet.
+        if (l2Tunnel.pwMode() == L2Mode.TAGGED) {
+            throw new IllegalArgumentException(String.format("Tagged mode not supported yet for pseudowire %d.",
+                                                                            l2Tunnel.tunnelId()));
+        }
+
+        // Raw mode without service delimiting tag
+        // is the only mode supported for now.
+    }
+
+    /**
+     * Helper method to verify if the policy is whether or not
+     * supported and if policy will be successfully instantiated in the
+     * network.
+     *
+     * @param ingressInner the ingress inner tag
+     * @param ingressOuter the ingress outer tag
+     * @param egressInner the egress inner tag
+     * @param egressOuter the egress outer tag
+     * @return the result of verification
+     */
+    private void verifyPolicy(ConnectPoint cP1,
+                              ConnectPoint cP2,
+                              VlanId ingressInner,
+                              VlanId ingressOuter,
+                              VlanId egressInner,
+                              VlanId egressOuter,
+                              Long tunnelId) {
+
+        if (cP1.deviceId().equals(cP2.deviceId())) {
+            throw new IllegalArgumentException(String.format("Pseudowire connection points can not reside in the " +
+                                                             "same node, in pseudowire %d.", tunnelId));
+        }
+
+        // We can have multiple tags, all of them can be NONE,
+        // indicating untagged traffic, however, the outer tag can
+        // not have value if the inner tag is None
+        if (ingressInner.equals(VlanId.NONE) && !ingressOuter.equals(VlanId.NONE)) {
+            throw new IllegalArgumentException(String.format("Inner tag should not be empty when " +
+                                                             "outer tag is set for pseudowire %d for cP1.",
+                                                              tunnelId));
+        }
+
+        if (egressInner.equals(VlanId.NONE) && !egressOuter.equals(VlanId.NONE)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Inner tag should not be empty when" +
+                                                                            " outer tag is set for pseudowire %d " +
+                                                                            "for cP2.", tunnelId)));
+        }
+
+        if (ingressInner.equals(VlanId.ANY) ||
+                ingressOuter.equals(VlanId.ANY) ||
+                egressInner.equals(VlanId.ANY) ||
+                egressOuter.equals(VlanId.ANY)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Wildcard VLAN matching not yet " +
+                                                                            "supported for pseudowire %d.",
+                                                                            tunnelId)));
+        }
+
+        if (((!ingressOuter.equals(VlanId.NONE) && !ingressOuter.equals(VlanId.NONE)) &&
+                (egressOuter.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE)))
+                || ((ingressOuter.equals(VlanId.NONE) && ingressOuter.equals(VlanId.NONE)) &&
+                (!egressOuter.equals(VlanId.NONE) && !egressInner.equals(VlanId.NONE)))) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Support for double tag <-> untag is not" +
+                                                                                    "supported for pseudowire %d.",
+                                                                            tunnelId)));
+        }
+        if ((!ingressInner.equals(VlanId.NONE) &&
+                ingressOuter.equals(VlanId.NONE) &&
+                !egressOuter.equals(VlanId.NONE))
+           || (!ingressOuter.equals(VlanId.NONE) &&
+                egressOuter.equals(VlanId.NONE) &&
+                !ingressOuter.equals(VlanId.NONE))) {
+                throw new IllegalArgumentException(String.valueOf(String.format("Support for double-tag<->" +
+                                                                                "single-tag is not supported" +
+                                                                                " for pseudowire %d.", tunnelId)));
+        }
+
+        if ((ingressInner.equals(VlanId.NONE) && !egressInner.equals(VlanId.NONE))
+                || (!ingressInner.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE))) {
+            throw new IllegalArgumentException(String.valueOf(String.format("single-tag <-> untag is not supported" +
+                                                                            " for pseudowire %d.", tunnelId)));
+        }
+
+
+        if (!ingressInner.equals(egressInner) && !ingressOuter.equals(egressOuter)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("We do not support changing both tags " +
+                                                                             "in double tagged pws, only the outer," +
+                                                                             " for pseudowire %d.", tunnelId)));
+        }
+
+        // check if cp1 and port of cp1 exist
+        if (deviceService.getDevice(cP1.deviceId()) == null) {
+            throw new IllegalArgumentException(String.valueOf(String.format("cP1 device %s does not exist for" +
+                                                                            " pseudowire %d.", cP1.deviceId(),
+                                                                            tunnelId)));
+        }
+
+        if (deviceService.getPort(cP1) == null) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Port %s for cP1 device %s does not" +
+                                                                            " exist for pseudowire %d.", cP1.port(),
+                                                                            cP1.deviceId(), tunnelId)));
+        }
+
+        // check if cp2 and port of cp2 exist
+        if (deviceService.getDevice(cP2.deviceId()) == null) {
+            throw new IllegalArgumentException(String.valueOf(String.format("cP2 device %s does not exist for" +
+                                                                            " pseudowire %d.", cP2.deviceId(),
+                                                                            tunnelId)));
+        }
+
+        if (deviceService.getPort(cP2) == null) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Port %s for cP2 device %s does " +
+                                                                            "not exist for pseudowire %d.",
+                                                                            cP2.port(), cP2.deviceId(), tunnelId)));
+        }
+    }
+
+    /**
+     * Verifies that the pseudowires will not conflict with each other.
+     *
+     * Further, check if vlans for connect points are already used.
+     *
+     * @param tunnel Tunnel for pw
+     * @param policy Policy for pw
+     * @param labelSet Label set used so far with this configuration
+     * @param vlanSet Vlan set used with this configuration
+     * @param tunnelSet Tunnel set used with this configuration
+     */
+    private void verifyGlobalValidity(DefaultL2Tunnel tunnel,
+                                      DefaultL2TunnelPolicy policy,
+                                      Set<MplsLabel> labelSet,
+                                      Map<ConnectPoint, Set<VlanId>> vlanSet,
+                                      Set<Long> tunnelSet) {
+
+        if (tunnelSet.contains(tunnel.tunnelId())) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Tunnel Id %d already used by" +
+                                                                           " another pseudowire, in " +
+                                                                           "pseudowire %d!", tunnel.tunnelId(),
+                                                                            tunnel.tunnelId())));
+        }
+        tunnelSet.add(tunnel.tunnelId());
+
+        // check if tunnel id is used again
+        ConnectPoint cP1 = policy.cP1();
+        ConnectPoint cP2 = policy.cP2();
+
+        // insert cps to hashmap if this is the first time seen
+        if (!vlanSet.containsKey(cP1)) {
+            vlanSet.put(cP1, new HashSet<VlanId>());
+        }
+        if (!vlanSet.containsKey(cP2)) {
+            vlanSet.put(cP2, new HashSet<VlanId>());
+        }
+
+        // if single tagged or untagged vlan is the inner
+        // if double tagged vlan is the outer
+        VlanId vlanToCheckCP1;
+        if (policy.cP1OuterTag().equals(VlanId.NONE)) {
+            vlanToCheckCP1 = policy.cP1InnerTag();
+        } else {
+            vlanToCheckCP1 = policy.cP1OuterTag();
+        }
+
+        VlanId vlanToCheckCP2;
+        if (policy.cP2OuterTag().equals(VlanId.NONE)) {
+            vlanToCheckCP2 = policy.cP2InnerTag();
+        } else {
+            vlanToCheckCP2 = policy.cP2OuterTag();
+        }
+
+        if (labelSet.contains(tunnel.pwLabel())) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Label %s already used by another" +
+                                                                            " pseudowire, in pseudowire %d!",
+                                                                            tunnel.pwLabel(), tunnel.tunnelId())));
+        }
+        labelSet.add(tunnel.pwLabel());
+
+        if (vlanSet.get(cP1).contains(vlanToCheckCP1)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP1 %s already used " +
+                                                                            "by another pseudowire, in pseudowire" +
+                                                                            " %d!", vlanToCheckCP1,  cP1,
+                                                                            tunnel.tunnelId())));
+        }
+        vlanSet.get(cP1).add(vlanToCheckCP1);
+
+        if (vlanSet.get(cP2).contains(vlanToCheckCP2)) {
+            throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP2 %s already used" +
+                                                                            " by another pseudowire, in" +
+                                                                            " pseudowire %d!", vlanToCheckCP2, cP2,
+                                                                            tunnel.tunnelId())));
+        }
+        vlanSet.get(cP2).add(vlanToCheckCP2);
+
+        // check that vlans for the connect points are not used
+        intfService.getInterfacesByPort(cP1).stream()
+                .forEach(intf -> {
+
+                    // check if tagged pw affects tagged interface
+                    if (intf.vlanTagged().contains(vlanToCheckCP1)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP1 %s already" +
+                                                                                        " used for this interface, in" +
+                                                                                        " pseudowire %d!",
+                                                                                        vlanToCheckCP1, cP1,
+                                                                                        tunnel.tunnelId())));
+                    }
+
+                    // if vlanNative != null this interface is configured with untagged traffic also
+                    // check if it collides with untagged interface
+                    if ((intf.vlanNative() != null) && vlanToCheckCP1.equals(VlanId.NONE)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP1 " +
+                                                                                         "%s already used for this " +
+                                                                                         "interface, in pseudowire " +
+                                                                                         "%d!", cP1,
+                                                                                         tunnel.tunnelId())));
+                    }
+
+                    // if vlanUntagged != null this interface is configured only with untagged traffic
+                    // check if it collides with untagged interface
+                    if ((intf.vlanUntagged() != null) && vlanToCheckCP1.equals(VlanId.NONE)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for " +
+                                                                                         "cP1 %s already" +
+                                                                                         " used for this interface," +
+                                                                                         " in pseudowire %d!",
+                                                                                         cP1, tunnel.tunnelId())));
+                    }
+                });
+
+        intfService.getInterfacesByPort(cP2).stream()
+                .forEach(intf -> {
+                    if (intf.vlanTagged().contains(vlanToCheckCP2)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Vlan '%s' for cP2 %s already" +
+                                                                                        " used for  this interface, " +
+                                                                                        "in pseudowire %d!",
+                                                                                        vlanToCheckCP2, cP2,
+                                                                                        tunnel.tunnelId())));
+                    }
+
+                    // if vlanNative != null this interface is configured with untagged traffic also
+                    // check if it collides with untagged interface
+                    if ((intf.vlanNative() != null) && vlanToCheckCP2.equals(VlanId.NONE)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP2 %s " +
+                                                                                        "already used for this" +
+                                                                                        " interface, " +
+                                                                                        "in pseudowire %d!",
+                                                                                        cP2, tunnel.tunnelId())));
+                    }
+
+                    // if vlanUntagged != null this interface is configured only with untagged traffic
+                    // check if it collides with untagged interface
+                    if ((intf.vlanUntagged() != null) && vlanToCheckCP2.equals(VlanId.NONE)) {
+                        throw new IllegalArgumentException(String.valueOf(String.format("Untagged traffic for cP2 %s" +
+                                                                                        " already" +
+                                                                                        " used for this interface, " +
+                                                                                        "in pseudowire %d!",
+                                                                                        cP2, tunnel.tunnelId())));
+                    }
+                });
+
+    }
+
+    /**
+     * Helper method to verify the integrity of the pseudo wire.
+     *
+     * @param l2TunnelDescription the pseudo wire description
+     * @return the result of the check
+     */
+    private void verifyPseudoWire(DefaultL2TunnelDescription l2TunnelDescription,
+                                  Set<MplsLabel> labelSet,
+                                  Map<ConnectPoint, Set<VlanId>> vlanset,
+                                  Set<Long> tunnelSet) {
+
+        DefaultL2Tunnel l2Tunnel = l2TunnelDescription.l2Tunnel();
+        DefaultL2TunnelPolicy l2TunnelPolicy = l2TunnelDescription.l2TunnelPolicy();
+
+        verifyTunnel(l2Tunnel);
+
+        verifyPolicy(
+                l2TunnelPolicy.cP1(),
+                l2TunnelPolicy.cP2(),
+                l2TunnelPolicy.cP1InnerTag(),
+                l2TunnelPolicy.cP1OuterTag(),
+                l2TunnelPolicy.cP2InnerTag(),
+                l2TunnelPolicy.cP2OuterTag(),
+                l2Tunnel.tunnelId()
+        );
+
+        verifyGlobalValidity(l2Tunnel,
+                             l2TunnelPolicy,
+                             labelSet,
+                             vlanset,
+                             tunnelSet);
+
+    }
+
+    /**
+     * Checks if the configured pseudowires will create problems in the network.
+     * If yes, then no pseudowires is deployed from this configuration.
+     *
+     * @param pseudowires Set of pseudowries to validate
+     * @return returns true if everything goes well.
+     */
+    public boolean configurationValidity(Set<DefaultL2TunnelDescription> pseudowires) {
+
+        // structures to keep pw information
+        // in order to see if instantiating them will create
+        // problems
+        Set<Long> tunIds = new HashSet<>();
+        Set<MplsLabel> labelsUsed = new HashSet<>();
+        Map<ConnectPoint, Set<VlanId>> vlanIds = new HashMap<>();
+
+        // check that pseudowires can be instantiated in the network
+        // we try to guarantee that all the pws will work before
+        // instantiating any of them
+        for (DefaultL2TunnelDescription pw : pseudowires) {
+            verifyPseudoWire(pw, labelsUsed, vlanIds, tunIds);
+        }
+
+        return true;
     }
 
     /**
@@ -96,6 +482,61 @@
     }
 
     /**
+     * Parses a vlan as a string. Returns the VlanId if
+     * provided String can be parsed as an integer or is '' / '*'
+     *
+     * @param vlan string as read from configuration
+     * @return VlanId
+     * @throws IllegalArgumentException if wrong format of vlan
+     */
+    public VlanId parseVlan(String vlan) {
+
+        if (vlan.equals("*") || vlan.equals("Any")) {
+            return VlanId.vlanId("Any");
+        } else if (vlan.equals("") || vlan.equals("None")) {
+            return VlanId.vlanId("None");
+        } else {
+            try {
+                VlanId newVlan = VlanId.vlanId(vlan);
+                return newVlan;
+            } catch (IllegalArgumentException e) {
+                throw new IllegalArgumentException(INVALID_VLAN);
+            }
+        }
+    }
+
+    /**
+     *
+     * @param mode RAW or TAGGED
+     * @return the L2Mode if input is correct
+     * @throws  IllegalArgumentException if not supported mode
+     */
+    public L2Mode parseMode(String mode) {
+
+        if (!mode.equals("RAW") && !mode.equals("TAGGED")) {
+            throw  new IllegalArgumentException(INVALID_L2_MODE);
+        }
+
+        return L2Mode.valueOf(mode);
+    }
+
+    /**
+     *
+     * @param label the mpls label of the pseudowire
+     * @return the MplsLabel
+     * @throws IllegalArgumentException if label is invalid
+     */
+    public MplsLabel parsePWLabel(String label) {
+
+        try {
+            MplsLabel pwLabel = MplsLabel.mplsLabel(label);
+            return pwLabel;
+        } catch (Exception e) {
+            throw new IllegalArgumentException(INVALID_PW_LABEL);
+        }
+    }
+
+    /**
      * Returns pw description of given pseudo wire id.
      *
      * @param tunnelId pseudo wire key
@@ -107,7 +548,7 @@
         if (!hasFields((ObjectNode) pwDescription,
                       SRC_CP, SRC_INNER_TAG, SRC_OUTER_TAG,
                       DST_CP, DST_INNER_TAG, DST_OUTER_TAG,
-                      MODE, ALL_VLAN, SD_TAG, PW_LABEL)) {
+                      MODE, SD_TAG, PW_LABEL)) {
             throw new IllegalArgumentException(MISSING_PARAMS);
         }
         String tempString;
@@ -119,28 +560,25 @@
         ConnectPoint dstCp = ConnectPoint.deviceConnectPoint(tempString);
 
         tempString = pwDescription.get(SRC_INNER_TAG).asText();
-        VlanId srcInnerTag = VlanId.vlanId(tempString);
+        VlanId srcInnerTag = parseVlan(tempString);
 
         tempString = pwDescription.get(SRC_OUTER_TAG).asText();
-        VlanId srcOuterTag = VlanId.vlanId(tempString);
+        VlanId srcOuterTag = parseVlan(tempString);
 
         tempString = pwDescription.get(DST_INNER_TAG).asText();
-        VlanId dstInnerTag = VlanId.vlanId(tempString);
+        VlanId dstInnerTag = parseVlan(tempString);
 
         tempString = pwDescription.get(DST_OUTER_TAG).asText();
-        VlanId dstOuterTag = VlanId.vlanId(tempString);
+        VlanId dstOuterTag = parseVlan(tempString);
 
         tempString = pwDescription.get(MODE).asText();
-
-        L2Mode l2Mode = L2Mode.valueOf(tempString);
-
-        boolean allVlan = pwDescription.get(ALL_VLAN).asBoolean();
+        L2Mode l2Mode = parseMode(tempString);
 
         tempString = pwDescription.get(SD_TAG).asText();
-        VlanId sdTag = VlanId.vlanId(tempString);
+        VlanId sdTag = parseVlan(tempString);
 
         tempString = pwDescription.get(PW_LABEL).asText();
-        MplsLabel pwLabel = MplsLabel.mplsLabel(tempString);
+        MplsLabel pwLabel = parsePWLabel(tempString);
 
         DefaultL2Tunnel l2Tunnel = new DefaultL2Tunnel(
                 l2Mode,
@@ -156,11 +594,76 @@
                 srcOuterTag,
                 dstCp,
                 dstInnerTag,
-                dstOuterTag,
-                allVlan
+                dstOuterTag
         );
 
         return new DefaultL2TunnelDescription(l2Tunnel, l2TunnelPolicy);
     }
 
+    /**
+     * Removes a pseudowire from the configuration tree.
+     * @param pwId Pseudowire id
+     * @return null if pwId did not exist, or the object representing the
+     * udpated configuration tree
+     */
+    public ObjectNode removePseudowire(String pwId) {
+
+        JsonNode value = object.remove(pwId);
+        if (value == null) {
+            return (ObjectNode) value;
+        } else {
+            return object;
+        }
+    }
+
+    /**
+     * Adds a pseudowire to the configuration tree of pwwas. It also checks
+     * if the configuration is valid, if not return null and does not add the node,
+     * if yes return the new configuration. Caller will propagate update events.
+     *
+     * If the pseudowire already exists in the configuration it gets updated.
+     *
+     * @param tunnelId Id of tunnel
+     * @param pwLabel PW label of tunnel
+     * @param cP1 Connection point 1
+     * @param cP1InnerVlan Inner vlan of cp1
+     * @param cP1OuterVlan Outer vlan of cp2
+     * @param cP2 Connection point 2
+     * @param cP2InnerVlan Inner vlan of cp2
+     * @param cP2OuterVlan Outer vlan of cp2
+     * @param mode Mode for the pw
+     * @param sdTag Service delimiting tag for the pw
+     * @return The ObjectNode config if configuration is valid with the new pseudowire
+     * or null.
+     */
+    public ObjectNode addPseudowire(String tunnelId, String pwLabel, String cP1,
+                                    String cP1InnerVlan, String cP1OuterVlan, String cP2,
+                                    String cP2InnerVlan, String cP2OuterVlan,
+                                    String mode, String sdTag) {
+
+
+        ObjectNode newPw = new ObjectNode(JsonNodeFactory.instance);
+
+        // add fields for pseudowire
+        newPw.put(SRC_CP, cP1);
+        newPw.put(DST_CP, cP2);
+        newPw.put(PW_LABEL, pwLabel);
+        newPw.put(SRC_INNER_TAG, cP1InnerVlan);
+        newPw.put(SRC_OUTER_TAG, cP1OuterVlan);
+        newPw.put(DST_INNER_TAG, cP2InnerVlan);
+        newPw.put(DST_OUTER_TAG, cP2OuterVlan);
+        newPw.put(SD_TAG, sdTag);
+        newPw.put(MODE, mode);
+
+        object.set(tunnelId, newPw);
+        try {
+            isValid();
+        } catch (IllegalArgumentException e) {
+            log.info("Pseudowire could not be created : {}", e);
+            object.remove(tunnelId);
+            return null;
+        }
+
+        return object;
+    }
 }
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
index 848e2ca..71f5c15 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/grouphandler/DefaultGroupHandler.java
@@ -910,6 +910,7 @@
                                                       index));
                     foundSingleNeighbor = true;
                 }
+
                 for (PortNumber sp : neighborPorts) {
                     TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment
                             .builder();
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java
index 8855a21..bddc191 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2Tunnel.java
@@ -20,7 +20,10 @@
 import com.google.common.base.MoreObjects;
 import org.onlab.packet.MplsLabel;
 import org.onlab.packet.VlanId;
+import org.onosproject.net.Link;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 
 import static com.google.common.base.Preconditions.checkArgument;
@@ -52,21 +55,19 @@
      */
     private MplsLabel interCoLabel;
 
+    private List<Link> pathUsed;
+
     /**
      * Creates a inter-co l2 tunnel using the
      * supplied parameters.
      *
-     * @param mode the tunnel mode
-     * @param sdtag the service delimiting tag
-     * @param tunnelId the tunnel id
-     * @param pwLabel the pseudo wire label
+     * @param mode         the tunnel mode
+     * @param sdtag        the service delimiting tag
+     * @param tunnelId     the tunnel id
+     * @param pwLabel      the pseudo wire label
      * @param interCoLabel the inter central office label
      */
-    public DefaultL2Tunnel(L2Mode mode,
-                           VlanId sdtag,
-                           long tunnelId,
-                           MplsLabel pwLabel,
-                           MplsLabel interCoLabel) {
+    public DefaultL2Tunnel(L2Mode mode, VlanId sdtag, long tunnelId, MplsLabel pwLabel, MplsLabel interCoLabel) {
         checkNotNull(mode);
         checkArgument(tunnelId > 0);
         checkNotNull(pwLabel);
@@ -80,24 +81,36 @@
     }
 
     /**
-     * Creates a intra-co l2 tunnel using the
-     * supplied parameters.
+     * Creates a l2Tunnel from a given tunnel.
      *
-     * @param mode the tunnel mode
-     * @param sdtag the service delimiting tag
-     * @param tunnelId the tunnel id
-     * @param pwLabel the pseudo wire label
+     * @param l2Tunnel to replicate
      */
-    public DefaultL2Tunnel(L2Mode mode,
-                           VlanId sdtag,
-                           long tunnelId,
-                           MplsLabel pwLabel) {
-        this(mode, sdtag, tunnelId, pwLabel, MplsLabel.mplsLabel(MplsLabel.MAX_MPLS));
+    public DefaultL2Tunnel(DefaultL2Tunnel l2Tunnel) {
+
+        this.pwMode = l2Tunnel.pwMode();
+        this.sdTag = l2Tunnel.sdTag();
+        this.tunnelId = l2Tunnel.tunnelId();
+        this.pwLabel = l2Tunnel.pwLabel();
+        this.interCoLabel = l2Tunnel.interCoLabel();
+        this.pathUsed = l2Tunnel.pathUsed();
     }
 
     /**
-     * Creates an empty l2 tunnel.
+     * Creates a intra-co l2 tunnel using the
+     * supplied parameters.
      *
+     * @param mode     the tunnel mode
+     * @param sdtag    the service delimiting tag
+     * @param tunnelId the tunnel id
+     * @param pwLabel  the pseudo wire label
+     */
+    public DefaultL2Tunnel(L2Mode mode, VlanId sdtag, long tunnelId, MplsLabel pwLabel) {
+        this(mode, sdtag, tunnelId, pwLabel, MplsLabel.mplsLabel(MplsLabel.MAX_MPLS));
+    }
+
+
+    /**
+     * Creates an empty l2 tunnel.
      **/
     public DefaultL2Tunnel() {
         this.pwMode = null;
@@ -145,6 +158,24 @@
     }
 
     /**
+     * Set the path for the pseudowire.
+     *
+     * @param path The path to set
+     */
+    public void setPath(List<Link> path) {
+        pathUsed = new ArrayList<>(path);
+    }
+
+    /**
+     * Returns the used path of the pseudowire.
+     *
+     * @return pathUsed
+     */
+    public List<Link> pathUsed() {
+        return pathUsed;
+    }
+
+    /**
      * Returns the inter-co label.
      *
      * @return the mpls inter-co label
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java
index 6e797d2..ac52f3e 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelPolicy.java
@@ -57,10 +57,6 @@
      * cP2 outer vlan tag.
      */
     private VlanId cP2OuterTag;
-    /**
-     * Boolean value to indicate if the pseudo wire is port based.
-     */
-    private boolean allVlan;
 
     /**
      * Creates a default l2 tunnel policy using
@@ -73,12 +69,10 @@
      * @param cP2 the second connect point
      * @param cP2InnerTag the cP2 inner tag
      * @param cP2OuterTag the cP2 outer tag
-     * @param allVlan if the tunnel is port based or not
      */
     public DefaultL2TunnelPolicy(long tunnelId,
                                  ConnectPoint cP1, VlanId cP1InnerTag, VlanId cP1OuterTag,
-                                 ConnectPoint cP2, VlanId cP2InnerTag, VlanId cP2OuterTag,
-                                 boolean allVlan) {
+                                 ConnectPoint cP2, VlanId cP2InnerTag, VlanId cP2OuterTag) {
         this.cP1 = checkNotNull(cP1);
         this.cP2 = checkNotNull(cP2);
         this.tunnelId = tunnelId;
@@ -86,7 +80,21 @@
         this.cP1OuterTag = cP1OuterTag;
         this.cP2InnerTag = cP2InnerTag;
         this.cP2OuterTag = cP2OuterTag;
-        this.allVlan = allVlan;
+    }
+
+    /**
+     * Creates a default l2 policy given the provided policy.
+     * @param policy L2policy to replicate
+     */
+    public DefaultL2TunnelPolicy(DefaultL2TunnelPolicy policy) {
+
+        this.cP1 = policy.cP1;
+        this.cP2 = policy.cP2;
+        this.tunnelId = policy.tunnelId;
+        this.cP1InnerTag = policy.cP1InnerTag;
+        this.cP1OuterTag = policy.cP1OuterTag;
+        this.cP2InnerTag = policy.cP2InnerTag;
+        this.cP2OuterTag = policy.cP2OuterTag;
     }
 
     /**
@@ -144,16 +152,6 @@
     }
 
     /**
-     * Return all vlan value.
-     *
-     * @return true, if the pw is port based. False if the traffic is sliced
-     *         through the inner and outer tags
-     */
-    public boolean isAllVlan() {
-        return allVlan;
-    }
-
-    /**
      * Returns the tunnel ID of the policy.
      *
      * @return Tunnel ID
@@ -170,8 +168,7 @@
                             cP1InnerTag,
                             cP1OuterTag,
                             cP2InnerTag,
-                            cP2OuterTag,
-                            allVlan
+                            cP2OuterTag
         );
     }
 
@@ -189,8 +186,7 @@
                     this.cP1InnerTag.equals(that.cP1InnerTag) &&
                     this.cP1OuterTag.equals(that.cP1OuterTag) &&
                     this.cP2InnerTag.equals(that.cP2InnerTag) &&
-                    this.cP2OuterTag.equals(that.cP2OuterTag) &&
-                    this.allVlan == that.allVlan) {
+                    this.cP2OuterTag.equals(that.cP2OuterTag)) {
                 return true;
             }
         }
@@ -208,7 +204,6 @@
                 .add("cP1OuterTag", cP1OuterTag())
                 .add("cP2InnerTag", cP2InnerTag())
                 .add("cP2OuterTag", cP2OuterTag())
-                .add("allVlan", isAllVlan())
                 .toString();
     }
 
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
index 4c7e3d2..8b334ea 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
@@ -25,6 +25,7 @@
 import org.onlab.packet.VlanId;
 import org.onlab.util.KryoNamespace;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.DisjointPath;
 import org.onosproject.net.Link;
@@ -52,6 +53,7 @@
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.ConsistentMap;
 import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.Versioned;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -60,9 +62,7 @@
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
-import static com.google.common.base.Preconditions.checkState;
 import static org.onosproject.net.flowobjective.ForwardingObjective.Flag.VERSATILE;
-import static org.onosproject.segmentrouting.pwaas.L2Mode.TAGGED;
 import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Pipeline.INITIATION;
 import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Pipeline.TERMINATION;
 import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Result.*;
@@ -75,11 +75,6 @@
 public class L2TunnelHandler {
 
     private static final Logger log = LoggerFactory.getLogger(L2TunnelHandler.class);
-    /**
-     * Error message for invalid paths.
-     */
-    private static final String WRONG_TOPOLOGY = "Path in leaf-spine topology" +
-            " should always be two hops: ";
 
     private final SegmentRoutingManager srManager;
     /**
@@ -90,16 +85,17 @@
      * To store the next objectives related to the termination.
      */
     private final ConsistentMap<String, NextObjective> l2TerminationNextObjStore;
+
     /**
-     * TODO a proper store is necessary to handle the policies, collisions and recovery.
-     * We should have a proper store for the policies and the tunnels. For several reasons:
-     * 1) We should avoid the overlapping of different policies;
-     * 2) We should avoid the overlapping of different tunnels;
-     * 3) We should have a proper mechanism for the protection;
-     * The most important one is 3). At least for 3.0 EA0 was not possible
-     * to remove the bucket, so we need a mapping between policies and tunnel
-     * in order to proper update the fwd objective for the recovery of a fault.
+     * To store policies.
      */
+    private final ConsistentMap<String, DefaultL2TunnelPolicy> l2PolicyStore;
+
+    /**
+     * To store tunnels.
+     */
+    private final ConsistentMap<String, DefaultL2Tunnel> l2TunnelStore;
+
     private final KryoNamespace.Builder l2TunnelKryo;
 
     /**
@@ -111,19 +107,105 @@
     public L2TunnelHandler(SegmentRoutingManager segmentRoutingManager) {
         srManager = segmentRoutingManager;
         l2TunnelKryo = new KryoNamespace.Builder()
-                .register(KryoNamespaces.API);
+                .register(KryoNamespaces.API)
+                .register(DefaultL2Tunnel.class,
+                          DefaultL2TunnelPolicy.class,
+                          L2Mode.class,
+                          MplsLabel.class,
+                          VlanId.class,
+                          ConnectPoint.class);
 
-        l2InitiationNextObjStore = srManager.storageService
-                .<String, NextObjective>consistentMapBuilder()
-                .withName("onos-l2initiation-nextobj-store")
-                .withSerializer(Serializer.using(l2TunnelKryo.build()))
-                .build();
+        l2InitiationNextObjStore = srManager.
+                storageService.
+                <String, NextObjective>consistentMapBuilder().
+                withName("onos-l2initiation-nextobj-store").
+                withSerializer(Serializer.using(l2TunnelKryo.build())).
+                build();
 
-        l2TerminationNextObjStore = srManager.storageService
-                .<String, NextObjective>consistentMapBuilder()
+        l2TerminationNextObjStore = srManager.storageService.
+                <String, NextObjective>consistentMapBuilder()
                 .withName("onos-l2termination-nextobj-store")
                 .withSerializer(Serializer.using(l2TunnelKryo.build()))
                 .build();
+
+        l2PolicyStore = srManager.storageService
+                .<String, DefaultL2TunnelPolicy>consistentMapBuilder()
+                .withName("onos-l2-policy-store")
+                .withSerializer(Serializer.using(l2TunnelKryo.build()))
+                .build();
+
+        l2TunnelStore = srManager.storageService
+                .<String, DefaultL2Tunnel>consistentMapBuilder()
+                .withName("onos-l2-tunnel-store")
+                .withSerializer(Serializer.using(l2TunnelKryo.build()))
+                .build();
+    }
+
+    /**
+     * Returns all L2 Policies.
+     *
+     * @return List of policies
+     */
+    public List<DefaultL2TunnelPolicy> getL2Policies() {
+
+        return l2PolicyStore
+                .values()
+                .stream()
+                .map(Versioned::value)
+                .map(DefaultL2TunnelPolicy::new)
+                .collect(Collectors.toList());
+
+    }
+
+    /**
+     * Returns all L2 Tunnels.
+     *
+     * @return List of tunnels.
+     */
+    public List<DefaultL2Tunnel> getL2Tunnels() {
+
+        return l2TunnelStore
+                .values()
+                .stream()
+                .map(Versioned::value)
+                .map(DefaultL2Tunnel::new)
+                .collect(Collectors.toList());
+
+    }
+
+    /**
+     * Processes a link removal. Finds affected pseudowires and rewires them.
+     * TODO: Make it also take into account failures of links that are used for pw
+     * traffic in the spine.
+     * @param link The link that failed
+     */
+    public void processLinkDown(Link link) {
+
+        List<DefaultL2Tunnel> tunnels = getL2Tunnels();
+        List<DefaultL2TunnelPolicy> policies = getL2Policies();
+
+        // determine affected pseudowires and update them at once
+        Set<DefaultL2TunnelDescription> pwToUpdate = tunnels
+                .stream()
+                .filter(tun -> tun.pathUsed().contains(link))
+                .map(l2Tunnel -> {
+                        DefaultL2TunnelPolicy policy = null;
+                        for (DefaultL2TunnelPolicy l2Policy : policies) {
+                            if (l2Policy.tunnelId() == l2Tunnel.tunnelId()) {
+                                policy = l2Policy;
+                                break;
+                            }
+                        }
+
+                        return new DefaultL2TunnelDescription(l2Tunnel, policy);
+                })
+                .collect(Collectors.toSet());
+
+
+        log.info("Pseudowires affected by link failure : {}, rerouting them...", pwToUpdate);
+
+        // update all pseudowires
+        pwToUpdate.forEach(tun -> updatePw(tun, tun));
     }
 
     /**
@@ -132,93 +214,209 @@
      * @param event network config add event
      */
     public void processPwaasConfigAdded(NetworkConfigEvent event) {
-        log.info("Processing Pwaas CONFIG_ADDED");
+
+        log.info("Network event : Pseudowire configuration added!");
         PwaasConfig config = (PwaasConfig) event.config().get();
-        Set<DefaultL2TunnelDescription> pwToAdd = config.getPwIds()
+
+        // gather pseudowires
+        Set<DefaultL2TunnelDescription> pwToAdd = config
+                .getPwIds()
                 .stream()
                 .map(config::getPwDescription)
                 .collect(Collectors.toSet());
-        // We deploy all the pseudo wire deployed
+
+        // deploy pseudowires
         deploy(pwToAdd);
     }
 
     /**
+     * Returns the new vlan id for an ingress point of a
+     * pseudowire. For double tagged, it is the outer,
+     * For single tagged it is the single tag, and for
+     * inner it is None.
+     *
+     * @param ingressOuter vlanid of ingress outer
+     * @param ingressInner vlanid of ingress inner
+     * @param egressOuter  vlanid of egress outer
+     * @param egressInner  vlanid of egress inner
+     * @return returns the vlan id which will be installed at vlan table 1.
+     */
+    public VlanId determineEgressVlan(VlanId ingressOuter, VlanId ingressInner,
+                                      VlanId egressOuter, VlanId egressInner) {
+
+        // validity of vlan combinations was checked at verifyPseudowire
+        if (!(ingressOuter.equals(VlanId.NONE))) {
+            return egressOuter;
+        } else if (!(ingressInner.equals(VlanId.NONE))) {
+            return egressInner;
+        } else {
+            return VlanId.vlanId("None");
+        }
+    }
+
+    /**
+     * Adds a single pseudowire. This method can be called from cli commands
+     * without configration updates, thus it does not check for mastership
+     * of the ingress pseudowire device.
+     *
+     * @param pw The pseudowire
+     * @return
+     */
+    private Result deployPseudowire(DefaultL2TunnelDescription pw) {
+
+        Result result;
+        long l2TunnelId;
+
+        l2TunnelId = pw.l2Tunnel().tunnelId();
+
+        // The tunnel id cannot be 0.
+        if (l2TunnelId == 0) {
+            log.warn("Tunnel id id must be > 0");
+            return Result.ADDITION_ERROR;
+        }
+
+        // get path here, need to use the same for fwd and rev direction
+        List<Link> path = getPath(pw.l2TunnelPolicy().cP1(),
+                                  pw.l2TunnelPolicy().cP2());
+        if (path == null) {
+            log.info("Deploying process : No path between the connection points for pseudowire {}", l2TunnelId);
+            return WRONG_PARAMETERS;
+        }
+
+        pw.l2Tunnel().setPath(path);
+
+        // next hops for next objectives
+        Link fwdNextHop = path.get(0);
+        Link revNextHop = reverseLink(path.get(1));
+
+        log.info("Deploying process : Establishing forward direction for pseudowire {}", l2TunnelId);
+
+        // We establish the tunnel.
+        // result.nextId will be used in fwd
+        result = deployPseudoWireInit(pw.l2Tunnel(),
+                                      pw.l2TunnelPolicy().cP1(),
+                                      pw.l2TunnelPolicy().cP2(),
+                                      FWD,
+                                      fwdNextHop);
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire initiation for CP1");
+            return Result.ADDITION_ERROR;
+        }
+
+        VlanId egressVlan = determineEgressVlan(pw.l2TunnelPolicy().cP1OuterTag(),
+                                                pw.l2TunnelPolicy().cP1InnerTag(),
+                                                pw.l2TunnelPolicy().cP2OuterTag(),
+                                                pw.l2TunnelPolicy().cP2InnerTag());
+
+        // We create the policy.
+        result = deployPolicy(l2TunnelId,
+                              pw.l2TunnelPolicy().cP1(),
+                              pw.l2TunnelPolicy().cP1InnerTag(),
+                              pw.l2TunnelPolicy().cP1OuterTag(),
+                              egressVlan,
+                              result.nextId);
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire policy for CP1");
+            return Result.ADDITION_ERROR;
+        }
+
+        // We terminate the tunnel
+        result = deployPseudoWireTerm(pw.l2Tunnel(),
+                                       pw.l2TunnelPolicy().cP2(),
+                                       pw.l2TunnelPolicy().cP2OuterTag(),
+                                       FWD);
+
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire termination for CP1");
+            return Result.ADDITION_ERROR;
+
+        }
+
+        log.info("Deploying process : Establishing reverse direction for pseudowire {}", l2TunnelId);
+
+        // We establish the reverse tunnel.
+        result = deployPseudoWireInit(pw.l2Tunnel(),
+                                       pw.l2TunnelPolicy().cP2(),
+                                       pw.l2TunnelPolicy().cP1(),
+                                       REV,
+                                       revNextHop);
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire initiation for CP2");
+            return Result.ADDITION_ERROR;
+        }
+
+        egressVlan = determineEgressVlan(pw.l2TunnelPolicy().cP2OuterTag(),
+                                          pw.l2TunnelPolicy().cP2InnerTag(),
+                                          pw.l2TunnelPolicy().cP1OuterTag(),
+                                          pw.l2TunnelPolicy().cP1InnerTag());
+        result = deployPolicy(l2TunnelId,
+                               pw.l2TunnelPolicy().cP2(),
+                               pw.l2TunnelPolicy().cP2InnerTag(),
+                               pw.l2TunnelPolicy().cP2OuterTag(),
+                               egressVlan,
+                               result.nextId);
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying policy for CP2");
+            return Result.ADDITION_ERROR;
+        }
+
+        result = deployPseudoWireTerm(pw.l2Tunnel(),
+                                       pw.l2TunnelPolicy().cP1(),
+                                       pw.l2TunnelPolicy().cP1OuterTag(),
+                                       REV);
+
+        if (result != SUCCESS) {
+            log.info("Deploying process : Error in deploying pseudowire termination for CP2");
+            return Result.ADDITION_ERROR;
+        }
+
+        log.info("Deploying process : Updating relevant information for pseudowire {}", l2TunnelId);
+
+        // Populate stores
+        l2TunnelStore.put(Long.toString(l2TunnelId), pw.l2Tunnel());
+        l2PolicyStore.put(Long.toString(l2TunnelId), pw.l2TunnelPolicy());
+
+        return Result.SUCCESS;
+    }
+
+    /**
      * To deploy a number of pseudo wires.
+     * <p>
+     * Called ONLY when configuration changes, thus the check
+     * for the mastership of the device.
+     * <p>
+     * Only the master of CP1 will deploy this pseudowire.
      *
      * @param pwToAdd the set of pseudo wires to add
      */
     private void deploy(Set<DefaultL2TunnelDescription> pwToAdd) {
+
         Result result;
-        long l2TunnelId;
+
         for (DefaultL2TunnelDescription currentL2Tunnel : pwToAdd) {
-            l2TunnelId = currentL2Tunnel.l2Tunnel().tunnelId();
-            // The tunnel id cannot be 0.
-            if (l2TunnelId == 0) {
-                log.warn("Tunnel id id must be > 0");
+
+            // only the master of CP1 will program this pseudowire
+            if (!srManager.isMasterOf(currentL2Tunnel.l2TunnelPolicy().cP1())) {
                 continue;
             }
-            // We do a sanity check of the pseudo wire.
-            result = verifyPseudoWire(currentL2Tunnel);
-            if (result != SUCCESS) {
-                continue;
+
+            log.info("Deploying pseudowire {}", currentL2Tunnel.l2Tunnel().tunnelId());
+
+            result = deployPseudowire(currentL2Tunnel);
+            switch (result) {
+                case WRONG_PARAMETERS:
+                    log.warn("Could not deploy pseudowire {}, wrong parameters!",
+                             currentL2Tunnel.l2Tunnel().tunnelId());
+                    break;
+                case ADDITION_ERROR:
+                    log.warn("Could not deploy pseudowire {}, error in populating rules!",
+                             currentL2Tunnel.l2Tunnel().tunnelId());
+                    break;
+                default:
+                    log.info("Pseudowire with {} succesfully deployed!",
+                             currentL2Tunnel.l2Tunnel().tunnelId());
+                    break;
             }
-            // We establish the tunnel.
-            result = deployPseudoWireInit(
-                    currentL2Tunnel.l2Tunnel(),
-                    currentL2Tunnel.l2TunnelPolicy().cP1(),
-                    currentL2Tunnel.l2TunnelPolicy().cP2(),
-                    FWD
-            );
-            if (result != SUCCESS) {
-                continue;
-            }
-            // We create the policy.
-            result = deployPolicy(
-                    l2TunnelId,
-                    currentL2Tunnel.l2TunnelPolicy().cP1(),
-                    currentL2Tunnel.l2TunnelPolicy().cP1InnerTag(),
-                    currentL2Tunnel.l2TunnelPolicy().cP1OuterTag(),
-                    result.nextId
-            );
-            if (result != SUCCESS) {
-                continue;
-            }
-            // We terminate the tunnel
-            result = deployPseudoWireTerm(
-                    currentL2Tunnel.l2Tunnel(),
-                    currentL2Tunnel.l2TunnelPolicy().cP2(),
-                    currentL2Tunnel.l2TunnelPolicy().cP2OuterTag(),
-                    FWD
-            );
-            if (result != SUCCESS) {
-                continue;
-            }
-            // We establish the reverse tunnel.
-            result = deployPseudoWireInit(
-                    currentL2Tunnel.l2Tunnel(),
-                    currentL2Tunnel.l2TunnelPolicy().cP2(),
-                    currentL2Tunnel.l2TunnelPolicy().cP1(),
-                    REV
-            );
-            if (result != SUCCESS) {
-                continue;
-            }
-            result = deployPolicy(
-                    l2TunnelId,
-                    currentL2Tunnel.l2TunnelPolicy().cP2(),
-                    currentL2Tunnel.l2TunnelPolicy().cP2InnerTag(),
-                    currentL2Tunnel.l2TunnelPolicy().cP2OuterTag(),
-                    result.nextId
-            );
-            if (result != SUCCESS) {
-                continue;
-            }
-            deployPseudoWireTerm(
-                    currentL2Tunnel.l2Tunnel(),
-                    currentL2Tunnel.l2TunnelPolicy().cP1(),
-                    currentL2Tunnel.l2TunnelPolicy().cP1OuterTag(),
-                    REV
-            );
         }
     }
 
@@ -228,46 +426,75 @@
      * @param event network config updated event
      */
     public void processPwaasConfigUpdated(NetworkConfigEvent event) {
-        log.info("Processing Pwaas CONFIG_UPDATED");
+
+        log.info("Pseudowire configuration updated.");
+
         // We retrieve the old pseudo wires.
         PwaasConfig prevConfig = (PwaasConfig) event.prevConfig().get();
         Set<Long> prevPws = prevConfig.getPwIds();
+
         // We retrieve the new pseudo wires.
         PwaasConfig config = (PwaasConfig) event.config().get();
         Set<Long> newPws = config.getPwIds();
+
         // We compute the pseudo wires to update.
         Set<Long> updPws = newPws.stream()
-                .filter(tunnelId -> prevPws.contains(tunnelId) &&
-                !config.getPwDescription(tunnelId).equals(prevConfig.getPwDescription(tunnelId)))
+                .filter(tunnelId -> prevPws.contains(tunnelId)
+                        && !config.getPwDescription(tunnelId).equals(prevConfig.getPwDescription(tunnelId)))
                 .collect(Collectors.toSet());
+
         // The pseudo wires to remove.
-        Set<DefaultL2TunnelDescription> pwToRemove = prevPws.stream()
-                .filter(tunnelId -> !newPws.contains(tunnelId))
+        Set<Long> rmvPWs = prevPws.stream()
+                .filter(tunnelId -> !newPws.contains(tunnelId)).collect(Collectors.toSet());
+
+        Set<DefaultL2TunnelDescription> pwToRemove = rmvPWs.stream()
                 .map(prevConfig::getPwDescription)
                 .collect(Collectors.toSet());
         tearDown(pwToRemove);
+
         // The pseudo wires to add.
-        Set<DefaultL2TunnelDescription> pwToAdd = newPws.stream()
+        Set<Long> addedPWs = newPws.stream()
                 .filter(tunnelId -> !prevPws.contains(tunnelId))
+                .collect(Collectors.toSet());
+        Set<DefaultL2TunnelDescription> pwToAdd = addedPWs.stream()
                 .map(config::getPwDescription)
                 .collect(Collectors.toSet());
         deploy(pwToAdd);
+
+
         // The pseudo wires to update.
-        updPws.forEach(tunnelId -> updatePw(
-                prevConfig.getPwDescription(tunnelId),
-                config.getPwDescription(tunnelId))
-        );
+        updPws.forEach(tunnelId -> updatePw(prevConfig.getPwDescription(tunnelId),
+                                            config.getPwDescription(tunnelId)));
+
+        log.info("Pseudowires removed : {}, Pseudowires updated : {}, Pseudowires added : {}", rmvPWs,
+                 updPws, addedPWs);
     }
 
     /**
      * Helper function to update a pw.
+     * <p>
+     * Called upon configuration changes that update existing pseudowires and
+     * when links fail. Checking of mastership for CP1 is mandatory because it is
+     * called in multiple instances for both cases.
+     * <p>
+     * Meant to call asynchronously for various events, thus this call can not block and need
+     * to perform asynchronous operations.
+     * <p>
+     * For this reason error checking is omitted.
      *
      * @param oldPw the pseudo wire to remove
-     * @param newPw the pseudo wirte to add
+     * @param newPw the pseudo wire to add
      */
-    private void updatePw(DefaultL2TunnelDescription oldPw,
-                          DefaultL2TunnelDescription newPw) {
+    public void updatePw(DefaultL2TunnelDescription oldPw, DefaultL2TunnelDescription newPw) {
         long tunnelId = oldPw.l2Tunnel().tunnelId();
+
+        // only the master of CP1 will update this pseudowire
+        if (!srManager.isMasterOf(oldPw.l2TunnelPolicy().cP1())) {
+            return;
+        }
+
+        log.info("Updating pseudowire {}", oldPw.l2Tunnel().tunnelId());
+
         // The async tasks to orchestrate the next and
         // forwarding update.
         CompletableFuture<ObjectiveError> fwdInitNextFuture = new CompletableFuture<>();
@@ -277,136 +504,165 @@
         CompletableFuture<ObjectiveError> fwdPwFuture = new CompletableFuture<>();
         CompletableFuture<ObjectiveError> revPwFuture = new CompletableFuture<>();
 
-
-        Result result = verifyPseudoWire(newPw);
-        if (result != SUCCESS) {
-            return;
-        }
         // First we remove both policy.
         log.debug("Start deleting fwd policy for {}", tunnelId);
-        deletePolicy(
-                tunnelId,
-                oldPw.l2TunnelPolicy().cP1(),
-                oldPw.l2TunnelPolicy().cP1InnerTag(),
-                oldPw.l2TunnelPolicy().cP1OuterTag(),
-                fwdInitNextFuture,
-                FWD
-        );
-        log.debug("Start deleting rev policy for {}", tunnelId);
-        deletePolicy(
-                tunnelId,
-                oldPw.l2TunnelPolicy().cP2(),
-                oldPw.l2TunnelPolicy().cP2InnerTag(),
-                oldPw.l2TunnelPolicy().cP2OuterTag(),
-                revInitNextFuture,
-                REV
-        );
+
+        // first delete all information from our stores
+        // we can not do it asynchronously
+        l2PolicyStore.remove(Long.toString(tunnelId));
+        l2TunnelStore.remove(Long.toString(tunnelId));
+
+        VlanId egressVlan = determineEgressVlan(oldPw.l2TunnelPolicy().cP1OuterTag(),
+                                                 oldPw.l2TunnelPolicy().cP1InnerTag(),
+                                                 oldPw.l2TunnelPolicy().cP2OuterTag(),
+                                                 oldPw.l2TunnelPolicy().cP2InnerTag());
+        deletePolicy(tunnelId,
+                      oldPw.l2TunnelPolicy().cP1(),
+                      oldPw.l2TunnelPolicy().cP1InnerTag(),
+                      oldPw.l2TunnelPolicy().cP1OuterTag(),
+                      egressVlan,
+                      fwdInitNextFuture,
+                      FWD);
+
+        log.debug("Update process : Start deleting rev policy for {}", tunnelId);
+
+        egressVlan = determineEgressVlan(oldPw.l2TunnelPolicy().cP2OuterTag(),
+                                          oldPw.l2TunnelPolicy().cP2InnerTag(),
+                                          oldPw.l2TunnelPolicy().cP1OuterTag(),
+                                          oldPw.l2TunnelPolicy().cP1InnerTag());
+        deletePolicy(tunnelId,
+                      oldPw.l2TunnelPolicy().cP2(),
+                      oldPw.l2TunnelPolicy().cP2InnerTag(),
+                      oldPw.l2TunnelPolicy().cP2OuterTag(),
+                      egressVlan, revInitNextFuture,
+                      REV);
+
         // Finally we remove both the tunnels.
         fwdInitNextFuture.thenAcceptAsync(status -> {
             if (status == null) {
-                log.debug("Fwd policy removed. Now remove fwd {} for {}", INITIATION, tunnelId);
-                tearDownPseudoWireInit(
-                        tunnelId,
-                        oldPw.l2TunnelPolicy().cP1(),
-                        fwdTermNextFuture,
-                        FWD
-                );
+                log.debug("Update process : Fwd policy removed. " +
+                                  "Now remove fwd {} for {}", INITIATION, tunnelId);
+                tearDownPseudoWireInit(tunnelId,
+                                        oldPw.l2TunnelPolicy().cP1(),
+                                        fwdTermNextFuture,
+                                        FWD);
             }
         });
         revInitNextFuture.thenAcceptAsync(status -> {
-           if (status == null) {
-               log.debug("Rev policy removed. Now remove rev {} for {}", INITIATION, tunnelId);
-               tearDownPseudoWireInit(
-                       tunnelId,
-                       oldPw.l2TunnelPolicy().cP2(),
-                       revTermNextFuture,
-                       REV
-               );
-
-           }
+            if (status == null) {
+                log.debug("Update process : Rev policy removed. " +
+                                  "Now remove rev {} for {}", INITIATION, tunnelId);
+                tearDownPseudoWireInit(tunnelId,
+                                        oldPw.l2TunnelPolicy().cP2(),
+                                        revTermNextFuture,
+                                        REV);
+            }
         });
         fwdTermNextFuture.thenAcceptAsync(status -> {
             if (status == null) {
-                log.debug("Fwd {} removed. Now remove fwd {} for {}", INITIATION, TERMINATION, tunnelId);
-                tearDownPseudoWireTerm(
-                        oldPw.l2Tunnel(),
-                        oldPw.l2TunnelPolicy().cP2(),
-                        fwdPwFuture,
-                        FWD
-                );
+                log.debug("Update process : Fwd {} removed. " +
+                                  "Now remove fwd {} for {}", INITIATION, TERMINATION, tunnelId);
+                tearDownPseudoWireTerm(oldPw.l2Tunnel(),
+                                        oldPw.l2TunnelPolicy().cP2(),
+                                        fwdPwFuture,
+                                        FWD);
             }
         });
         revTermNextFuture.thenAcceptAsync(status -> {
             if (status == null) {
-                log.debug("Rev {} removed. Now remove rev {} for {}", INITIATION, TERMINATION, tunnelId);
-                tearDownPseudoWireTerm(
-                        oldPw.l2Tunnel(),
-                        oldPw.l2TunnelPolicy().cP1(),
-                        revPwFuture,
-                        REV
-                );
+                log.debug("Update process : Rev {} removed. " +
+                                  "Now remove rev {} for {}", INITIATION, TERMINATION, tunnelId);
+                tearDownPseudoWireTerm(oldPw.l2Tunnel(),
+                                        oldPw.l2TunnelPolicy().cP1(),
+                                        revPwFuture,
+                                        REV);
             }
         });
-        // At the end we install the new pw.
+
+        // get path here, need to use the same for fwd and rev direction
+        List<Link> path = getPath(newPw.l2TunnelPolicy().cP1(),
+                                   newPw.l2TunnelPolicy().cP2());
+        if (path == null) {
+            log.info("Deploying process : " +
+                             "No path between the connection points for pseudowire {}", newPw.l2Tunnel().tunnelId());
+            return;
+        }
+
+        newPw.l2Tunnel().setPath(path);
+        // next hops for next objectives
+        Link fwdNextHop = path.get(0);
+        Link revNextHop = reverseLink(path.get(1));
+
+        // At the end we install the updated PW.
         fwdPwFuture.thenAcceptAsync(status -> {
             if (status == null) {
-                log.debug("Deploying new fwd pw for {}", tunnelId);
-                Result lamdaResult = deployPseudoWireInit(
-                        newPw.l2Tunnel(),
-                        newPw.l2TunnelPolicy().cP1(),
-                        newPw.l2TunnelPolicy().cP2(),
-                        FWD
-                );
+
+                // Upgrade stores and book keeping information, need to move this here
+                // cause this call is asynchronous.
+                l2PolicyStore.put(Long.toString(tunnelId), newPw.l2TunnelPolicy());
+                l2TunnelStore.put(Long.toString(tunnelId), newPw.l2Tunnel());
+
+                log.debug("Update process : Deploying new fwd pw for {}", tunnelId);
+                Result lamdaResult = deployPseudoWireInit(newPw.l2Tunnel(),
+                                                           newPw.l2TunnelPolicy().cP1(),
+                                                           newPw.l2TunnelPolicy().cP2(),
+                                                           FWD,
+                                                           fwdNextHop);
                 if (lamdaResult != SUCCESS) {
                     return;
                 }
-                lamdaResult = deployPolicy(
-                        tunnelId,
-                        newPw.l2TunnelPolicy().cP1(),
-                        newPw.l2TunnelPolicy().cP1InnerTag(),
-                        newPw.l2TunnelPolicy().cP1OuterTag(),
-                        lamdaResult.nextId
-                );
+
+                VlanId egressVlanId = determineEgressVlan(newPw.l2TunnelPolicy().cP1OuterTag(),
+                                                           newPw.l2TunnelPolicy().cP1InnerTag(),
+                                                           newPw.l2TunnelPolicy().cP2OuterTag(),
+                                                           newPw.l2TunnelPolicy().cP2InnerTag());
+
+                lamdaResult = deployPolicy(tunnelId,
+                                            newPw.l2TunnelPolicy().cP1(),
+                                            newPw.l2TunnelPolicy().cP1InnerTag(),
+                                            newPw.l2TunnelPolicy().cP1OuterTag(),
+                                            egressVlanId,
+                                            lamdaResult.nextId);
                 if (lamdaResult != SUCCESS) {
                     return;
                 }
-                deployPseudoWireTerm(
-                        newPw.l2Tunnel(),
-                        newPw.l2TunnelPolicy().cP2(),
-                        newPw.l2TunnelPolicy().cP2OuterTag(),
-                        FWD
-                );
+                deployPseudoWireTerm(newPw.l2Tunnel(),
+                                      newPw.l2TunnelPolicy().cP2(),
+                                      newPw.l2TunnelPolicy().cP2OuterTag(),
+                                      FWD);
 
             }
         });
+
         revPwFuture.thenAcceptAsync(status -> {
             if (status == null) {
-                log.debug("Deploying new rev pw for {}", tunnelId);
-                Result lamdaResult = deployPseudoWireInit(
-                        newPw.l2Tunnel(),
-                        newPw.l2TunnelPolicy().cP2(),
-                        newPw.l2TunnelPolicy().cP1(),
-                        REV
-                );
+                log.debug("Update process : Deploying new rev pw for {}", tunnelId);
+                Result lamdaResult = deployPseudoWireInit(newPw.l2Tunnel(),
+                                                           newPw.l2TunnelPolicy().cP2(),
+                                                           newPw.l2TunnelPolicy().cP1(),
+                                                           REV,
+                                                           revNextHop);
                 if (lamdaResult != SUCCESS) {
                     return;
                 }
-                lamdaResult = deployPolicy(
-                        tunnelId,
-                        newPw.l2TunnelPolicy().cP2(),
-                        newPw.l2TunnelPolicy().cP2InnerTag(),
-                        newPw.l2TunnelPolicy().cP2OuterTag(),
-                        lamdaResult.nextId
-                );
+
+                VlanId egressVlanId = determineEgressVlan(newPw.l2TunnelPolicy().cP2OuterTag(),
+                                                           newPw.l2TunnelPolicy().cP2InnerTag(),
+                                                           newPw.l2TunnelPolicy().cP1OuterTag(),
+                                                           newPw.l2TunnelPolicy().cP1InnerTag());
+                lamdaResult = deployPolicy(tunnelId,
+                                            newPw.l2TunnelPolicy().cP2(),
+                                            newPw.l2TunnelPolicy().cP2InnerTag(),
+                                            newPw.l2TunnelPolicy().cP2OuterTag(),
+                                            egressVlanId,
+                                            lamdaResult.nextId);
                 if (lamdaResult != SUCCESS) {
                     return;
                 }
-                deployPseudoWireTerm(
-                        newPw.l2Tunnel(),
-                        newPw.l2TunnelPolicy().cP1(),
-                        newPw.l2TunnelPolicy().cP1OuterTag(),
-                        REV
-                );
+                deployPseudoWireTerm(newPw.l2Tunnel(),
+                                      newPw.l2TunnelPolicy().cP1(),
+                                      newPw.l2TunnelPolicy().cP1OuterTag(),
+                                      REV);
             }
         });
     }
@@ -417,110 +673,165 @@
      * @param event network config removed event
      */
     public void processPwaasConfigRemoved(NetworkConfigEvent event) {
-        log.info("Processing Pwaas CONFIG_REMOVED");
+
+        log.info("Network event : Pseudowire configuration removed!");
         PwaasConfig config = (PwaasConfig) event.prevConfig().get();
-        Set<DefaultL2TunnelDescription> pwToRemove = config.getPwIds()
+
+        Set<DefaultL2TunnelDescription> pwToRemove = config
+                .getPwIds()
                 .stream()
                 .map(config::getPwDescription)
                 .collect(Collectors.toSet());
+
         // We teardown all the pseudo wire deployed
         tearDown(pwToRemove);
     }
 
     /**
-     * Helper function to handle the pw removal.
+     * Helper function for removing a single pseudowire.
+     * <p>
+     * No mastership of CP1 is checked, because it can be called from
+     * the CLI for removal of pseudowires.
      *
-     * @param pwToRemove the pseudo wires to remove
+     * @param l2TunnelId the id of the pseudowire to tear down
+     * @return Returns SUCCESS if no error is obeserved or an appropriate
+     * error on a failure
      */
-    private void tearDown(Set<DefaultL2TunnelDescription> pwToRemove) {
-        Result result;
-        long l2TunnelId;
-        // We remove all the pw in the configuration file.
-        for (DefaultL2TunnelDescription currentL2Tunnel : pwToRemove) {
-            l2TunnelId = currentL2Tunnel.l2Tunnel().tunnelId();
-            if (l2TunnelId == 0) {
-                log.warn("Tunnel id cannot be 0");
-                continue;
-            }
-            result = verifyPseudoWire(currentL2Tunnel);
-            if (result != SUCCESS) {
-                continue;
-            }
-            // First all we have to delete the policy.
-            deletePolicy(
-                    l2TunnelId,
-                    currentL2Tunnel.l2TunnelPolicy().cP1(),
-                    currentL2Tunnel.l2TunnelPolicy().cP1InnerTag(),
-                    currentL2Tunnel.l2TunnelPolicy().cP1OuterTag(),
-                    null,
-                    FWD
-            );
-            // Finally we will tear down the pseudo wire.
-            tearDownPseudoWireInit(
-                    l2TunnelId,
-                    currentL2Tunnel.l2TunnelPolicy().cP1(),
-                    null,
-                    FWD
-            );
-            tearDownPseudoWireTerm(
-                    currentL2Tunnel.l2Tunnel(),
-                    currentL2Tunnel.l2TunnelPolicy().cP2(),
-                    null,
-                    FWD
-            );
-            // We do the same operations on the reverse side.
-            deletePolicy(
-                    l2TunnelId,
-                    currentL2Tunnel.l2TunnelPolicy().cP2(),
-                    currentL2Tunnel.l2TunnelPolicy().cP2InnerTag(),
-                    currentL2Tunnel.l2TunnelPolicy().cP2OuterTag(),
-                    null,
-                    REV
-            );
-            tearDownPseudoWireInit(
-                    l2TunnelId,
-                    currentL2Tunnel.l2TunnelPolicy().cP2(),
-                    null,
-                    REV
-            );
-            tearDownPseudoWireTerm(
-                    currentL2Tunnel.l2Tunnel(),
-                    currentL2Tunnel.l2TunnelPolicy().cP1(),
-                    null,
-                    REV
-            );
+    public Result tearDownPseudowire(long l2TunnelId) {
+
+        CompletableFuture<ObjectiveError> fwdInitNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> fwdTermNextFuture = new CompletableFuture<>();
+
+        CompletableFuture<ObjectiveError> revInitNextFuture = new CompletableFuture<>();
+        CompletableFuture<ObjectiveError> revTermNextFuture = new CompletableFuture<>();
+
+        if (l2TunnelId == 0) {
+            log.warn("Removal process : Tunnel id cannot be 0");
+            return Result.WRONG_PARAMETERS;
         }
 
+        // check existence of tunnels/policy in the store, if one is missing abort!
+        Versioned<DefaultL2Tunnel> l2TunnelVersioned = l2TunnelStore.get(Long.toString(l2TunnelId));
+        Versioned<DefaultL2TunnelPolicy> l2TunnelPolicyVersioned = l2PolicyStore.get(Long.toString(l2TunnelId));
+        if ((l2TunnelVersioned == null) || (l2TunnelPolicyVersioned == null)) {
+            log.warn("Removal process : Policy and/or tunnel missing for tunnel id {}", l2TunnelId);
+            return Result.REMOVAL_ERROR;
+        }
+
+        DefaultL2TunnelDescription pwToRemove = new DefaultL2TunnelDescription(l2TunnelVersioned.value(),
+                                                                               l2TunnelPolicyVersioned.value());
+
+        // remove the tunnels and the policies from the store
+        l2PolicyStore.remove(Long.toString(l2TunnelId));
+        l2TunnelStore.remove(Long.toString(l2TunnelId));
+
+        log.info("Removal process : Tearing down forward direction of pseudowire {}", l2TunnelId);
+
+        VlanId egressVlan = determineEgressVlan(pwToRemove.l2TunnelPolicy().cP1OuterTag(),
+                                                 pwToRemove.l2TunnelPolicy().cP1InnerTag(),
+                                                 pwToRemove.l2TunnelPolicy().cP2OuterTag(),
+                                                 pwToRemove.l2TunnelPolicy().cP2InnerTag());
+        deletePolicy(l2TunnelId,
+                      pwToRemove.l2TunnelPolicy().cP1(),
+                      pwToRemove.l2TunnelPolicy().cP1InnerTag(),
+                      pwToRemove.l2TunnelPolicy().cP1OuterTag(),
+                      egressVlan,
+                      fwdInitNextFuture,
+                      FWD);
+
+        fwdInitNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                // Finally we will tear down the pseudo wire.
+                tearDownPseudoWireInit(l2TunnelId,
+                                        pwToRemove.l2TunnelPolicy().cP1(),
+                                        fwdTermNextFuture,
+                                        FWD);
+            }
+        });
+
+        fwdTermNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                tearDownPseudoWireTerm(pwToRemove.l2Tunnel(),
+                                        pwToRemove.l2TunnelPolicy().cP2(),
+                                        null,
+                                        FWD);
+            }
+        });
+
+        log.info("Removal process : Tearing down reverse direction of pseudowire {}", l2TunnelId);
+
+        egressVlan = determineEgressVlan(pwToRemove.l2TunnelPolicy().cP2OuterTag(),
+                                          pwToRemove.l2TunnelPolicy().cP2InnerTag(),
+                                          pwToRemove.l2TunnelPolicy().cP1OuterTag(),
+                                          pwToRemove.l2TunnelPolicy().cP1InnerTag());
+
+        // We do the same operations on the reverse side.
+        deletePolicy(l2TunnelId,
+                      pwToRemove.l2TunnelPolicy().cP2(),
+                      pwToRemove.l2TunnelPolicy().cP2InnerTag(),
+                      pwToRemove.l2TunnelPolicy().cP2OuterTag(),
+                      egressVlan,
+                      revInitNextFuture,
+                      REV);
+
+        revInitNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                tearDownPseudoWireInit(l2TunnelId,
+                                        pwToRemove.l2TunnelPolicy().cP2(),
+                                        revTermNextFuture,
+                                        REV);
+            }
+        });
+
+        revTermNextFuture.thenAcceptAsync(status -> {
+            if (status == null) {
+                tearDownPseudoWireTerm(pwToRemove.l2Tunnel(),
+                                        pwToRemove.l2TunnelPolicy().cP1(),
+                                        null,
+                                        REV);
+            }
+        });
+
+        return Result.SUCCESS;
     }
 
     /**
-     * Helper method to verify the integrity of the pseudo wire.
+     * Helper function to handle the pw removal.
+     * <p>
+     * This method checks for the mastership of the device because it is
+     * used only from network configuration updates, thus we only want
+     * one instance only to program each pseudowire.
      *
-     * @param l2TunnelDescription the pseudo wire description
-     * @return the result of the check
+     * @param pwToRemove the pseudo wires to remove
      */
-    private Result verifyPseudoWire(DefaultL2TunnelDescription l2TunnelDescription) {
-        Result result;
-        DefaultL2Tunnel l2Tunnel = l2TunnelDescription.l2Tunnel();
-        DefaultL2TunnelPolicy l2TunnelPolicy = l2TunnelDescription.l2TunnelPolicy();
-        result = verifyTunnel(l2Tunnel);
-        if (result != SUCCESS) {
-            log.warn("Tunnel {}: did not pass the validation", l2Tunnel.tunnelId());
-            return result;
-        }
-        result = verifyPolicy(
-                l2TunnelPolicy.isAllVlan(),
-                l2TunnelPolicy.cP1InnerTag(),
-                l2TunnelPolicy.cP1OuterTag(),
-                l2TunnelPolicy.cP2InnerTag(),
-                l2TunnelPolicy.cP2OuterTag()
-        );
-        if (result != SUCCESS) {
-            log.warn("Policy for tunnel {}: did not pass the validation", l2Tunnel.tunnelId());
-            return result;
-        }
+    public void tearDown(Set<DefaultL2TunnelDescription> pwToRemove) {
 
-        return SUCCESS;
+        Result result;
+
+        // We remove all the pw in the configuration file.
+        for (DefaultL2TunnelDescription currentL2Tunnel : pwToRemove) {
+
+            // only the master of CP1 will program this pseudowire
+            if (!srManager.isMasterOf(currentL2Tunnel.l2TunnelPolicy().cP1())) {
+                continue;
+            }
+
+            log.info("Removing pseudowire {}", currentL2Tunnel.l2Tunnel().tunnelId());
+
+            result = tearDownPseudowire(currentL2Tunnel.l2Tunnel().tunnelId());
+            switch (result) {
+                case WRONG_PARAMETERS:
+                    log.warn("Error in supplied parameters for the pseudowire removal with tunnel id {}!",
+                             currentL2Tunnel.l2Tunnel().tunnelId());
+                    break;
+                case REMOVAL_ERROR:
+                    log.warn("Error in pseudowire removal with tunnel id {}!", currentL2Tunnel.l2Tunnel().tunnelId());
+                    break;
+                default:
+                    log.warn("Pseudowire with tunnel id {} was removed successfully",
+                             currentL2Tunnel.l2Tunnel().tunnelId());
+            }
+        }
     }
 
     /**
@@ -528,54 +839,48 @@
      * create the filtering and forwarding objectives related
      * to the initiation and termination.
      *
-     * @param tunnelId the tunnel id
-     * @param ingress the ingress point
+     * @param tunnelId     the tunnel id
+     * @param ingress      the ingress point
      * @param ingressInner the ingress inner tag
      * @param ingressOuter the ingress outer tag
-     * @param nextId the next objective id
+     * @param nextId       the next objective id
+     * @param egressVlan   Vlan-id to set, depends on ingress vlan
+     *                     combinations. For example, if pw is double tagged
+     *                     then this is the value of the outer vlan, if single
+     *                     tagged then it is the new value of the single tag.
+     *                     Should be None for untagged traffic.
      * @return the result of the operation
      */
-    private Result deployPolicy(long tunnelId,
-                                ConnectPoint ingress,
-                                VlanId ingressInner,
-                                VlanId ingressOuter,
-                                int nextId) {
-        if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
-            log.info("Abort creation of policy for tunnel {}: I am not the master", tunnelId);
-            return SUCCESS;
-        }
+    private Result deployPolicy(long tunnelId, ConnectPoint ingress, VlanId ingressInner,
+                                VlanId ingressOuter, VlanId egressVlan, int nextId) {
+
         List<Objective> objectives = Lists.newArrayList();
         // We create the forwarding objective for supporting
         // the l2 tunnel.
-        ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(
-                tunnelId,
-                ingress.port(),
-                nextId
-        );
+        ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(tunnelId, ingress.port(), nextId);
         // We create and add objective context.
-        ObjectiveContext context = new DefaultObjectiveContext(
-                (objective)
-                        -> log.debug("FwdObj for tunnel {} populated", tunnelId),
-                (objective, error)
-                        -> log.warn("Failed to populate fwdrObj for tunnel {}", tunnelId, error));
+        ObjectiveContext context = new DefaultObjectiveContext((objective) ->
+                                                                log.debug("FwdObj for tunnel {} populated", tunnelId),
+                                                               (objective, error) ->
+                                                                log.warn("Failed to populate fwdrObj " +
+                                                                                 "for tunnel {}", tunnelId, error));
         objectives.add(fwdBuilder.add(context));
+
         // We create the filtering objective to define the
         // permit traffic in the switch
-        FilteringObjective.Builder filtBuilder = createFiltObjective(
-                ingress.port(),
-                ingressInner,
-                ingressOuter
-        );
+        FilteringObjective.Builder filtBuilder = createFiltObjective(ingress.port(), ingressInner, ingressOuter);
+
         // We add the metadata.
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
-                .setTunnelId(tunnelId);
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+                .builder()
+                .setTunnelId(tunnelId)
+                .setVlanId(egressVlan);
         filtBuilder.withMeta(treatment.build());
+
         // We create and add objective context.
-        context = new DefaultObjectiveContext(
-                (objective)
-                        -> log.debug("FilterObj for tunnel {} populated", tunnelId),
-                (objective, error)
-                        -> log.warn("Failed to populate filterObj for tunnel {}", tunnelId, error));
+        context = new DefaultObjectiveContext((objective) -> log.debug("FilterObj for tunnel {} populated", tunnelId),
+                                              (objective, error) -> log.warn("Failed to populate filterObj for " +
+                                                                                     "tunnel {}", tunnelId, error));
         objectives.add(filtBuilder.add(context));
 
         for (Objective objective : objectives) {
@@ -591,73 +896,32 @@
     }
 
     /**
-     * Helper method to verify if the policy is whether or not
-     * supported.
-     *
-     * @param isAllVlan all vlan mode
-     * @param ingressInner the ingress inner tag
-     * @param ingressOuter the ingress outer tag
-     * @param egressInner the egress inner tag
-     * @param egressOuter the egress outer tag
-     * @return the result of verification
-     */
-    private Result verifyPolicy(boolean isAllVlan,
-                                VlanId ingressInner,
-                                VlanId ingressOuter,
-                                VlanId egressInner,
-                                VlanId egressOuter) {
-        // AllVlan mode is not supported yet.
-        if (isAllVlan) {
-            log.warn("AllVlan not supported yet");
-            return UNSUPPORTED;
-        }
-        // The vlan tags for cP1 and cP2 have to be different from
-        // vlan none.
-        if (ingressInner.equals(VlanId.NONE) ||
-                ingressOuter.equals(VlanId.NONE) ||
-                egressInner.equals(VlanId.NONE) ||
-                egressOuter.equals(VlanId.NONE)) {
-            log.warn("The vlan tags for the connect point have to be" +
-                             "different from vlan none");
-            return WRONG_PARAMETERS;
-        }
-        return SUCCESS;
-    }
-
-    /**
      * Handles the tunnel establishment which consists in
      * create the next objectives related to the initiation.
      *
-     * @param l2Tunnel the tunnel to deploy
-     * @param ingress the ingress connect point
-     * @param egress the egress connect point
+     * @param l2Tunnel  the tunnel to deploy
+     * @param ingress   the ingress connect point
+     * @param egress    the egress connect point
      * @param direction the direction of the pw
      * @return the result of the operation
      */
-    private Result deployPseudoWireInit(DefaultL2Tunnel l2Tunnel,
-                                        ConnectPoint ingress,
-                                        ConnectPoint egress,
-                                        Direction direction) {
-        if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
-            log.info("Abort initiation of tunnel {}: I am not the master", l2Tunnel.tunnelId());
-            return SUCCESS;
-        }
-        // We need at least a path between ingress and egress.
-        Link nextHop = getNextHop(ingress, egress);
+    private Result deployPseudoWireInit(DefaultL2Tunnel l2Tunnel, ConnectPoint ingress,
+                                        ConnectPoint egress, Direction direction, Link nextHop) {
+
         if (nextHop == null) {
-            log.warn("No path between ingress and egress");
+            log.warn("No path between ingress and egress cps for tunnel {}", l2Tunnel.tunnelId());
             return WRONG_PARAMETERS;
         }
+
         // We create the next objective without the metadata
         // context and id. We check if it already exists in the
         // store. If not we store as it is in the store.
-        NextObjective.Builder nextObjectiveBuilder = createNextObjective(
-                INITIATION,
-                nextHop.src(),
-                nextHop.dst(),
-                l2Tunnel,
-                egress.deviceId()
-        );
+        NextObjective.Builder nextObjectiveBuilder = createNextObjective(INITIATION,
+                                                                         nextHop.src(),
+                                                                         nextHop.dst(),
+                                                                         l2Tunnel,
+                                                                         egress.deviceId());
+
         if (nextObjectiveBuilder == null) {
             return INTERNAL_ERROR;
         }
@@ -676,19 +940,18 @@
         nextObjectiveBuilder.withId(nextId);
         String key = generateKey(l2Tunnel.tunnelId(), direction);
         l2InitiationNextObjStore.put(key, nextObjectiveBuilder.add());
-        ObjectiveContext context = new DefaultObjectiveContext(
-                (objective)
-                        -> log.debug("Initiation l2 tunnel rule for {} populated",
-                                     l2Tunnel.tunnelId()),
-                (objective, error)
-                        -> log.warn("Failed to populate Initiation l2 tunnel rule for {}: {}",
-                                    l2Tunnel.tunnelId(), error));
+        ObjectiveContext context = new DefaultObjectiveContext((objective) ->
+                                                                 log.debug("Initiation l2 tunnel rule " +
+                                                                                   "for {} populated",
+                                                                           l2Tunnel.tunnelId()),
+                                                               (objective, error) ->
+                                                                       log.warn("Failed to populate Initiation " +
+                                                                                        "l2 tunnel rule for {}: {}",
+                                                                                l2Tunnel.tunnelId(), error));
         NextObjective nextObjective = nextObjectiveBuilder.add(context);
         srManager.flowObjectiveService.next(ingress.deviceId(), nextObjective);
         log.debug("Initiation next objective for {} not found. Creating new NextObj with id={}",
-                  l2Tunnel.tunnelId(),
-                  nextObjective.id()
-        );
+                  l2Tunnel.tunnelId(), nextObjective.id());
         Result result = SUCCESS;
         result.nextId = nextObjective.id();
         return result;
@@ -698,30 +961,18 @@
      * Handles the tunnel termination, which consists in the creation
      * of a forwarding objective and a next objective.
      *
-     * @param l2Tunnel the tunnel to terminate
-     * @param egress the egress point
+     * @param l2Tunnel   the tunnel to terminate
+     * @param egress     the egress point
      * @param egressVlan the expected vlan at egress
-     * @param direction the direction
+     * @param direction  the direction
      * @return the result of the operation
      */
-    private Result deployPseudoWireTerm(DefaultL2Tunnel l2Tunnel,
-                                        ConnectPoint egress,
-                                        VlanId egressVlan,
-                                        Direction direction) {
+    private Result deployPseudoWireTerm(DefaultL2Tunnel l2Tunnel, ConnectPoint egress,
+                                        VlanId egressVlan, Direction direction) {
+
         // We create the group relative to the termination.
-        // It's fine to abort the termination if we are
-        // not the master.
-        if (!srManager.mastershipService.isLocalMaster(egress.deviceId())) {
-            log.info("Abort termination of tunnel {}: I am not the master", l2Tunnel.tunnelId());
-            return SUCCESS;
-        }
-        NextObjective.Builder nextObjectiveBuilder = createNextObjective(
-                TERMINATION,
-                egress,
-                null,
-                null,
-                egress.deviceId()
-        );
+        NextObjective.Builder nextObjectiveBuilder = createNextObjective(TERMINATION, egress, null,
+                                                                         null, egress.deviceId());
         if (nextObjectiveBuilder == null) {
             return INTERNAL_ERROR;
         }
@@ -738,74 +989,47 @@
         nextObjectiveBuilder.withId(nextId);
         String key = generateKey(l2Tunnel.tunnelId(), direction);
         l2TerminationNextObjStore.put(key, nextObjectiveBuilder.add());
-        ObjectiveContext context = new DefaultObjectiveContext(
-                (objective)
-                        -> log.debug("Termination l2 tunnel rule for {} populated",
-                                     l2Tunnel.tunnelId()),
-                (objective, error)
-                        -> log.warn("Failed to populate termination l2 tunnel rule for {}: {}",
-                                    l2Tunnel.tunnelId(), error));
+        ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("Termination l2 tunnel rule " +
+                                                                                        "for {} populated",
+                                                                                        l2Tunnel.tunnelId()),
+                                                               (objective, error) -> log.warn("Failed to populate " +
+                                                                                              "termination l2 tunnel " +
+                                                                                              "rule for {}: {}",
+                                                                                              l2Tunnel.tunnelId(),
+                                                                                              error));
         NextObjective nextObjective = nextObjectiveBuilder.add(context);
         srManager.flowObjectiveService.next(egress.deviceId(), nextObjective);
         log.debug("Termination next objective for {} not found. Creating new NextObj with id={}",
-                  l2Tunnel.tunnelId(),
-                  nextObjective.id()
-        );
+                  l2Tunnel.tunnelId(), nextObjective.id());
+
         // We create the flow relative to the termination.
-        ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(
-                l2Tunnel.pwLabel(),
-                l2Tunnel.tunnelId(),
-                egress.port(),
-                nextObjective.id()
-        );
-        context = new DefaultObjectiveContext(
-                (objective)
-                        -> log.debug("FwdObj for tunnel termination {} populated",
-                                     l2Tunnel.tunnelId()),
-                (objective, error)
-                        -> log.warn("Failed to populate fwdrObj for tunnel termination {}",
-                                    l2Tunnel.tunnelId(), error));
+        ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(l2Tunnel.pwLabel(), l2Tunnel.tunnelId(),
+                                                                        egress.port(), nextObjective.id());
+        context = new DefaultObjectiveContext((objective) -> log.debug("FwdObj for tunnel termination {} populated",
+                                                                       l2Tunnel.tunnelId()),
+                                              (objective, error) -> log.warn("Failed to populate fwdrObj" +
+                                                                             " for tunnel termination {}",
+                                                                             l2Tunnel.tunnelId(), error));
         srManager.flowObjectiveService.forward(egress.deviceId(), fwdBuilder.add(context));
-        log.debug("Creating new FwdObj for termination NextObj with id={} for tunnel {}", nextId, l2Tunnel.tunnelId());
+        log.debug("Creating new FwdObj for termination NextObj with id={} for tunnel {}",
+                  nextId, l2Tunnel.tunnelId());
         return SUCCESS;
 
     }
 
     /**
-     * Helper method to verify if the tunnel is whether or not
-     * supported.
-     *
-     * @param l2Tunnel the tunnel to verify
-     * @return the result of the verification
-     */
-    private Result verifyTunnel(DefaultL2Tunnel l2Tunnel) {
-        // Service delimiting tag not supported yet.
-        if (!l2Tunnel.sdTag().equals(VlanId.NONE)) {
-            log.warn("Service delimiting tag not supported yet");
-            return UNSUPPORTED;
-        }
-        // Tag mode not supported yet.
-        if (l2Tunnel.pwMode() == TAGGED) {
-            log.warn("Tagged mode not supported yet");
-            return UNSUPPORTED;
-        }
-        // Raw mode without service delimiting tag
-        // is the only mode supported for now.
-        return SUCCESS;
-    }
-
-    /**
      * Creates the filtering objective according to a given policy.
      *
-     * @param inPort the in port
+     * @param inPort   the in port
      * @param innerTag the inner vlan tag
      * @param outerTag the outer vlan tag
      * @return the filtering objective
      */
-    private FilteringObjective.Builder createFiltObjective(PortNumber inPort,
-                                                           VlanId innerTag,
-                                                           VlanId outerTag) {
-        return DefaultFilteringObjective.builder()
+    private FilteringObjective.Builder createFiltObjective(PortNumber inPort, VlanId innerTag, VlanId outerTag) {
+
+        log.info("Creating filtering objective for vlans {} / {}", outerTag, innerTag);
+        return DefaultFilteringObjective
+                .builder()
                 .withKey(Criteria.matchInPort(inPort))
                 .addCondition(Criteria.matchInnerVlanId(innerTag))
                 .addCondition(Criteria.matchVlanId(outerTag))
@@ -817,20 +1041,17 @@
     /**
      * Creates the forwarding objective for the termination.
      *
-     * @param pwLabel the pseudo wire label
-     * @param tunnelId the tunnel id
+     * @param pwLabel    the pseudo wire label
+     * @param tunnelId   the tunnel id
      * @param egressPort the egress port
-     * @param nextId the next step
+     * @param nextId     the next step
      * @return the forwarding objective to support the termination
      */
-    private ForwardingObjective.Builder createTermFwdObjective(MplsLabel pwLabel,
-                                                               long tunnelId,
-                                                               PortNumber egressPort,
-                                                               int nextId) {
-        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector
-                .builder();
-        TrafficTreatment.Builder trafficTreatment = DefaultTrafficTreatment
-                .builder();
+    private ForwardingObjective.Builder createTermFwdObjective(MplsLabel pwLabel, long tunnelId,
+                                                               PortNumber egressPort, int nextId) {
+
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder trafficTreatment = DefaultTrafficTreatment.builder();
         // The flow has to match on the pw label and bos
         trafficSelector.matchEthType(Ethernet.MPLS_UNICAST);
         trafficSelector.matchMplsLabel(pwLabel);
@@ -843,7 +1064,8 @@
         trafficTreatment.setTunnelId(tunnelId);
         trafficTreatment.setOutput(egressPort);
 
-        return DefaultForwardingObjective.builder()
+        return DefaultForwardingObjective
+                .builder()
                 .fromApp(srManager.appId())
                 .makePermanent()
                 .nextStep(nextId)
@@ -857,21 +1079,21 @@
      * Creates the forwarding objective for the initiation.
      *
      * @param tunnelId the tunnel id
-     * @param inPort the input port
-     * @param nextId the next step
+     * @param inPort   the input port
+     * @param nextId   the next step
      * @return the forwarding objective to support the initiation.
      */
-    private ForwardingObjective.Builder createInitFwdObjective(long tunnelId,
-                                                               PortNumber inPort,
-                                                               int nextId) {
-        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector
-                .builder();
+    private ForwardingObjective.Builder createInitFwdObjective(long tunnelId, PortNumber inPort, int nextId) {
+
+        TrafficSelector.Builder trafficSelector = DefaultTrafficSelector.builder();
+
         // The flow has to match on the mpls logical
         // port and the tunnel id.
         trafficSelector.matchTunnelId(tunnelId);
         trafficSelector.matchInPort(inPort);
 
-        return DefaultForwardingObjective.builder()
+        return DefaultForwardingObjective
+                .builder()
                 .fromApp(srManager.appId())
                 .makePermanent()
                 .nextStep(nextId)
@@ -888,16 +1110,14 @@
      * the same next objective for different tunnels.
      *
      * @param pipeline the pipeline to support
-     * @param srcCp the source port
-     * @param dstCp the destination port
+     * @param srcCp    the source port
+     * @param dstCp    the destination port
      * @param l2Tunnel the tunnel to support
      * @param egressId the egress device id
      * @return the next objective to support the pipeline
      */
-    private NextObjective.Builder createNextObjective(Pipeline pipeline,
-                                                      ConnectPoint srcCp,
-                                                      ConnectPoint dstCp,
-                                                      DefaultL2Tunnel l2Tunnel,
+    private NextObjective.Builder createNextObjective(Pipeline pipeline, ConnectPoint srcCp,
+                                                      ConnectPoint dstCp,  DefaultL2Tunnel l2Tunnel,
                                                       DeviceId egressId) {
         NextObjective.Builder nextObjBuilder;
         TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
@@ -924,16 +1144,17 @@
                 treatmentBuilder.copyTtlOut();
             }
             // We retrieve the sr label from the config
+            // specific for pseudowire traffic
             // using the egress leaf device id.
             MplsLabel srLabel;
             try {
-                 srLabel = MplsLabel.mplsLabel(
-                         srManager.deviceConfiguration().getIPv4SegmentId(egressId)
-                 );
+                srLabel = MplsLabel.mplsLabel(srManager.deviceConfiguration().getPWRoutingLabel(egressId));
+
             } catch (DeviceConfigNotFoundException e) {
-                log.warn("Sr label not configured");
+                log.warn("Sr label for pw traffic not configured");
                 return null;
             }
+
             treatmentBuilder.pushMpls();
             treatmentBuilder.setMpls(srLabel);
             treatmentBuilder.setMplsBos(false);
@@ -941,9 +1162,7 @@
             // We have to rewrite the src and dst mac address.
             MacAddress ingressMac;
             try {
-                ingressMac = srManager
-                        .deviceConfiguration()
-                        .getDeviceMac(srcCp.deviceId());
+                ingressMac = srManager.deviceConfiguration().getDeviceMac(srcCp.deviceId());
             } catch (DeviceConfigNotFoundException e) {
                 log.warn("Was not able to find the ingress mac");
                 return null;
@@ -951,9 +1170,7 @@
             treatmentBuilder.setEthSrc(ingressMac);
             MacAddress neighborMac;
             try {
-                neighborMac = srManager
-                        .deviceConfiguration()
-                        .getDeviceMac(dstCp.deviceId());
+                neighborMac = srManager.deviceConfiguration().getDeviceMac(dstCp.deviceId());
             } catch (DeviceConfigNotFoundException e) {
                 log.warn("Was not able to find the neighbor mac");
                 return null;
@@ -973,54 +1190,64 @@
     }
 
     /**
-     * Returns the next hop.
+     * Reverses a link.
      *
-     * @param srcCp the ingress connect point
-     * @param dstCp the egress connect point
-     * @return the next hop
+     * @param link
+     * @return The reversed link
      */
-    private Link getNextHop(ConnectPoint srcCp, ConnectPoint dstCp) {
-        // We retrieve a set of disjoint paths.
-        Set<DisjointPath> paths = srManager.pathService.getDisjointPaths(
-                srcCp.elementId(),
-                dstCp.elementId()
-        );
-        // We randmly pick a path.
+    private Link reverseLink(Link link) {
+
+        DefaultLink.Builder linkBuilder = DefaultLink.builder();
+
+        linkBuilder.src(link.dst());
+        linkBuilder.dst(link.src());
+        linkBuilder.type(link.type());
+        linkBuilder.providerId(link.providerId());
+
+        return linkBuilder.build();
+    }
+
+    /**
+     * Returns the path betwwen two connect points.
+     *
+     * @param srcCp
+     * @param dstCp
+     * @return The path
+     */
+    private List<Link> getPath(ConnectPoint srcCp, ConnectPoint dstCp) {
+
+        /* We retrieve a set of disjoint paths.
+        * We perform that in case of a link failure, what happens
+        * if the PathService gets the link notification AFTER us and
+        * has not updated the paths?
+        */
+        Set<DisjointPath> paths = srManager
+                .pathService
+                .getDisjointPaths(srcCp.elementId(), dstCp.elementId());
+
+        // We randomly pick a path.
         if (paths.isEmpty()) {
             return null;
         }
         int size = paths.size();
         int index = RandomUtils.nextInt(0, size);
-        // We verify if the path is ok and there is not
-        // a misconfiguration.
-        List<Link> links = Iterables.get(paths, index).links();
-        checkState(links.size() == 2, WRONG_TOPOLOGY, links);
-        return links.get(0);
+
+        return Iterables.get(paths, index).links();
     }
 
     /**
      * Deletes a given policy using the parameter supplied.
      *
-     * @param tunnelId the tunnel id
-     * @param ingress the ingress point
+     * @param tunnelId     the tunnel id
+     * @param ingress      the ingress point
      * @param ingressInner the ingress inner vlan id
      * @param ingressOuter the ingress outer vlan id
-     * @param future to perform the async operation
-     * @param direction the direction: forward or reverse
+     * @param future       to perform the async operation
+     * @param direction    the direction: forward or reverse
      */
-    private void deletePolicy(long tunnelId,
-                              ConnectPoint ingress,
-                              VlanId ingressInner,
-                              VlanId ingressOuter,
-                              CompletableFuture<ObjectiveError> future,
-                              Direction direction) {
-        if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
-            log.info("Abort delete of policy for tunnel {}: I am not the master", tunnelId);
-            if (future != null) {
-                future.complete(null);
-            }
-            return;
-        }
+    private void deletePolicy(long tunnelId, ConnectPoint ingress, VlanId ingressInner, VlanId ingressOuter,
+                              VlanId egressVlan, CompletableFuture<ObjectiveError> future, Direction direction) {
+
         String key = generateKey(tunnelId, direction);
         if (!l2InitiationNextObjStore.containsKey(key)) {
             log.warn("Abort delete of policy for tunnel {}: next does not exist in the store", tunnelId);
@@ -1033,11 +1260,7 @@
         int nextId = nextObjective.id();
         List<Objective> objectives = Lists.newArrayList();
         // We create the forwarding objective.
-        ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(
-                tunnelId,
-                ingress.port(),
-                nextId
-        );
+        ForwardingObjective.Builder fwdBuilder = createInitFwdObjective(tunnelId, ingress.port(), nextId);
         ObjectiveContext context = new ObjectiveContext() {
             @Override
             public void onSuccess(Objective objective) {
@@ -1058,19 +1281,16 @@
         objectives.add(fwdBuilder.remove(context));
         // We create the filtering objective to define the
         // permit traffic in the switch
-        FilteringObjective.Builder filtBuilder = createFiltObjective(
-                ingress.port(),
-                ingressInner,
-                ingressOuter
-        );
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder()
-                .setTunnelId(tunnelId);
+        FilteringObjective.Builder filtBuilder = createFiltObjective(ingress.port(), ingressInner, ingressOuter);
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment
+                .builder()
+                .setTunnelId(tunnelId)
+                .setVlanId(egressVlan);
         filtBuilder.withMeta(treatment.build());
-        context = new DefaultObjectiveContext(
-                (objective)
-                        -> log.debug("FilterObj for policy {} revoked", tunnelId),
-                (objective, error)
-                        -> log.warn("Failed to revoke filterObj for policy {}", tunnelId, error));
+        context = new DefaultObjectiveContext((objective) -> log.debug("FilterObj for policy {} revoked", tunnelId),
+                                              (objective, error) ->
+                                                      log.warn("Failed to revoke filterObj for policy {}",
+                                                               tunnelId, error));
         objectives.add(filtBuilder.remove(context));
 
         for (Objective objective : objectives) {
@@ -1086,22 +1306,14 @@
      * Deletes the pseudo wire initiation.
      *
      * @param l2TunnelId the tunnel id
-     * @param ingress the ingress connect point
-     * @param future to perform an async operation
-     * @param direction the direction: reverse of forward
+     * @param ingress    the ingress connect point
+     * @param future     to perform an async operation
+     * @param direction  the direction: reverse of forward
      */
-    private void tearDownPseudoWireInit(long l2TunnelId,
-                                        ConnectPoint ingress,
-                                        CompletableFuture<ObjectiveError> future,
-                                        Direction direction) {
+    private void tearDownPseudoWireInit(long l2TunnelId, ConnectPoint ingress,
+                                        CompletableFuture<ObjectiveError> future, Direction direction) {
+
         String key = generateKey(l2TunnelId, direction);
-        if (!srManager.mastershipService.isLocalMaster(ingress.deviceId())) {
-            log.info("Abort delete of {} for {}: I am not the master", INITIATION, key);
-            if (future != null) {
-                future.complete(null);
-            }
-            return;
-        }
         if (!l2InitiationNextObjStore.containsKey(key)) {
             log.info("Abort delete of {} for {}: next does not exist in the store", INITIATION, key);
             if (future != null) {
@@ -1110,6 +1322,10 @@
             return;
         }
         NextObjective nextObjective = l2InitiationNextObjStore.get(key).value();
+        // un-comment in case you want to delete groups used by the pw
+        // however, this will break the update of pseudowires cause the L2 interface group can
+        // not be deleted (it is referenced by other groups)
+        /*
         ObjectiveContext context = new ObjectiveContext() {
             @Override
             public void onSuccess(Objective objective) {
@@ -1127,34 +1343,27 @@
                 }
             }
         };
-        srManager.flowObjectiveService
-                .next(ingress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
+        srManager.flowObjectiveService.next(ingress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
+        */
+
+        future.complete(null);
         l2InitiationNextObjStore.remove(key);
     }
 
     /**
      * Deletes the pseudo wire termination.
      *
-     * @param l2Tunnel the tunnel
-     * @param egress the egress connect point
-     * @param future the async task
+     * @param l2Tunnel  the tunnel
+     * @param egress    the egress connect point
+     * @param future    the async task
      * @param direction the direction of the tunnel
      */
     private void tearDownPseudoWireTerm(DefaultL2Tunnel l2Tunnel,
                                         ConnectPoint egress,
                                         CompletableFuture<ObjectiveError> future,
                                         Direction direction) {
-        /*
-         * We verify the mastership for the termination.
-         */
+
         String key = generateKey(l2Tunnel.tunnelId(), direction);
-        if (!srManager.mastershipService.isLocalMaster(egress.deviceId())) {
-            log.info("Abort delete of {} for {}: I am not the master", TERMINATION, key);
-            if (future != null) {
-                future.complete(null);
-            }
-            return;
-        }
         if (!l2TerminationNextObjStore.containsKey(key)) {
             log.info("Abort delete of {} for {}: next does not exist in the store", TERMINATION, key);
             if (future != null) {
@@ -1163,20 +1372,24 @@
             return;
         }
         NextObjective nextObjective = l2TerminationNextObjStore.get(key).value();
-        ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(
-                l2Tunnel.pwLabel(),
-                l2Tunnel.tunnelId(),
-                egress.port(),
-                nextObjective.id()
-        );
-        ObjectiveContext context = new DefaultObjectiveContext(
-                (objective)
-                        -> log.debug("FwdObj for {} {} removed", TERMINATION, l2Tunnel.tunnelId()),
-                (objective, error)
-                        -> log.warn("Failed to remove fwdObj for {} {}", TERMINATION, l2Tunnel.tunnelId(),
-                                    error));
+        ForwardingObjective.Builder fwdBuilder = createTermFwdObjective(l2Tunnel.pwLabel(),
+                                                                        l2Tunnel.tunnelId(),
+                                                                        egress.port(),
+                                                                        nextObjective.id());
+        ObjectiveContext context = new DefaultObjectiveContext((objective) -> log.debug("FwdObj for {} {} removed",
+                                                                                        TERMINATION,
+                                                                                        l2Tunnel.tunnelId()),
+                                                               (objective, error) ->
+                                                                       log.warn("Failed to remove fwdObj for {} {}",
+                                                                                TERMINATION,
+                                                                                l2Tunnel.tunnelId(),
+                                                                                error));
         srManager.flowObjectiveService.forward(egress.deviceId(), fwdBuilder.remove(context));
 
+        // un-comment in case you want to delete groups used by the pw
+        // however, this will break the update of pseudowires cause the L2 interface group can
+        // not be deleted (it is referenced by other groups)
+        /*
         context = new ObjectiveContext() {
             @Override
             public void onSuccess(Objective objective) {
@@ -1194,15 +1407,17 @@
                 }
             }
         };
-        srManager.flowObjectiveService
-                .next(egress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
+        srManager.flowObjectiveService.next(egress.deviceId(), (NextObjective) nextObjective.copy().remove(context));
+        */
+
+        future.complete(null);
         l2TerminationNextObjStore.remove(key);
     }
 
     /**
      * Utilities to generate pw key.
      *
-     * @param tunnelId the tunnel id
+     * @param tunnelId  the tunnel id
      * @param direction the direction of the pw
      * @return the key of the store
      */
@@ -1217,38 +1432,46 @@
         /**
          * The initiation pipeline.
          */
-        INITIATION,
-        /**
+        INITIATION, /**
          * The termination pipeline.
          */
         TERMINATION
     }
 
     /**
-     * Enum helper to carry the outcomes of an operation.
+     * Enum helper to carry results of various operations.
      */
     public enum Result {
         /**
-         * Happy ending scenario it has been created.
+         * Happy ending scenario.
          */
-        SUCCESS(0, "It has been Created"),
+        SUCCESS(0, "No error occurred"),
+
         /**
          * We have problems with the supplied parameters.
          */
         WRONG_PARAMETERS(1, "Wrong parameters"),
-        /**
-         * It already exists.
-         */
-        ID_EXISTS(2, "The id already exists"),
+
         /**
          * We have an internal error during the deployment
-         * phase.
+         * or removal phase.
          */
         INTERNAL_ERROR(3, "Internal error"),
+
         /**
-         * The operation is not supported.
+         *
          */
-        UNSUPPORTED(4, "Unsupported");
+        REMOVAL_ERROR(5, "Can not remove pseudowire from network configuration"),
+
+        /**
+         *
+         */
+        ADDITION_ERROR(6, "Can not add pseudowire in network configuration"),
+
+        /**
+         *
+         */
+        CONFIG_NOT_FOUND(7, "Can not find configuration class for pseudowires");
 
         private final int code;
         private final String description;
@@ -1276,8 +1499,7 @@
         /**
          * The forward direction of the pseudo wire.
          */
-        FWD,
-        /**
+        FWD, /**
          * The reverse direction of the pseudo wire.
          */
         REV
