diff --git a/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index d951b53..b9912ac 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -15,8 +15,6 @@
  */
 package org.onosproject.segmentrouting;
 
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
@@ -94,7 +92,6 @@
 import org.onosproject.routeservice.RouteService;
 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
 import org.onosproject.segmentrouting.config.DeviceConfiguration;
-import org.onosproject.segmentrouting.config.PwaasConfig;
 import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
 import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
 import org.onosproject.segmentrouting.config.XConnectConfig;
@@ -104,9 +101,13 @@
 import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
 import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelHandler;
 import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
+
 import org.onosproject.segmentrouting.pwaas.L2Tunnel;
 import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
 import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
+
 import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
 import org.onosproject.segmentrouting.storekey.McastStoreKey;
 import org.onosproject.segmentrouting.storekey.PortNextObjectiveStoreKey;
@@ -142,6 +143,7 @@
 import static org.onlab.util.Tools.groupedThreads;
 import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_REGISTERED;
 import static org.onosproject.net.config.NetworkConfigEvent.Type.CONFIG_UNREGISTERED;
+import static org.onosproject.segmentrouting.pwaas.PwaasUtil.configurationValidity;
 
 /**
  * Segment routing manager.
@@ -234,7 +236,7 @@
     private RouteHandler routeHandler = null;
     LinkHandler linkHandler = null;
     private SegmentRoutingNeighbourDispatcher neighbourHandler = null;
-    private L2TunnelHandler l2TunnelHandler = null;
+    private DefaultL2TunnelHandler l2TunnelHandler = null;
     private InternalEventHandler eventHandler = new InternalEventHandler();
     private final InternalHostListener hostListener = new InternalHostListener();
     private final InternalConfigListener cfgListener = new InternalConfigListener(this);
@@ -314,16 +316,6 @@
                 }
             };
 
-    private final ConfigFactory<ApplicationId, PwaasConfig> pwaasConfigFactory =
-            new ConfigFactory<ApplicationId, PwaasConfig>(
-                    SubjectFactories.APP_SUBJECT_FACTORY,
-                    PwaasConfig.class, "pwaas") {
-                @Override
-                public PwaasConfig createConfig() {
-                    return new PwaasConfig();
-                }
-            };
-
     private static final Object THREAD_SCHED_LOCK = new Object();
     private static int numOfEventsQueued = 0;
     private static int numOfEventsExecuted = 0;
@@ -430,7 +422,6 @@
         cfgService.registerConfigFactory(appConfigFactory);
         cfgService.registerConfigFactory(xConnectConfigFactory);
         cfgService.registerConfigFactory(mcastConfigFactory);
-        cfgService.registerConfigFactory(pwaasConfigFactory);
         log.info("Configuring network before adding listeners");
         cfgListener.configureNetwork();
 
@@ -474,7 +465,6 @@
         cfgService.unregisterConfigFactory(appConfigFactory);
         cfgService.unregisterConfigFactory(xConnectConfigFactory);
         cfgService.unregisterConfigFactory(mcastConfigFactory);
-        cfgService.unregisterConfigFactory(pwaasConfigFactory);
         compCfgService.unregisterProperties(getClass(), false);
 
         hostService.removeListener(hostListener);
@@ -567,55 +557,90 @@
     }
 
     @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) {
-        // Try to inject an empty Pwaas config if it is not found for the first time
-        PwaasConfig config = cfgService.getConfig(appId(), PwaasConfig.class);
-        if (config == null) {
-            log.debug("Pwaas config not found. Try to create an empty one.");
-            cfgService.applyConfig(appId(), PwaasConfig.class, new ObjectMapper().createObjectNode());
-            config = cfgService.getConfig(appId(), PwaasConfig.class);
+    public L2TunnelHandler.Result addPseudowire(L2TunnelDescription l2TunnelDescription) {
+
+        List<L2Tunnel> tunnels = getL2Tunnels();
+        List<L2TunnelPolicy> policies = getL2Policies();
+
+        // combine polices and tunnels to pseudowires
+        List<L2TunnelDescription> pseudowires = tunnels.stream()
+                .map(l2Tunnel -> {
+                    L2TunnelPolicy policy = null;
+                    for (L2TunnelPolicy l2Policy : policies) {
+                        if (l2Policy.tunnelId() == l2Tunnel.tunnelId()) {
+                            policy = l2Policy;
+                            break;
+                        }
+                    }
+
+                    return new DefaultL2TunnelDescription(l2Tunnel, policy);
+                })
+                .collect(Collectors.toList());
+
+
+        // creating a new list with the new pseudowire
+        Set<L2TunnelDescription> newPseudowires = new HashSet<>(pseudowires);
+
+        // corner case where we try to add the exact same pseudowire
+        if (newPseudowires.contains(l2TunnelDescription)) {
+            log.info("Pseudowire with {} already exists!", l2TunnelDescription);
+            return L2TunnelHandler.Result.SUCCESS;
         }
 
-        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!");
+        // add the new pseudowire to the Set
+        newPseudowires.add(l2TunnelDescription);
+
+        // validate the new set of pseudowires
+        boolean res = configurationValidity(newPseudowires);
+        if (res) {
+
+            // deploy a set with ONLY the new pseudowire
+            newPseudowires = new HashSet<>();
+            newPseudowires.add(l2TunnelDescription);
+            l2TunnelHandler.deploy(newPseudowires);
+
+            log.info("Pseudowire with {} deployment started, check log for any errors in this process!",
+                     l2TunnelDescription.l2Tunnel().tunnelId());
+            return L2TunnelHandler.Result.SUCCESS;
+        } else {
+
+            log.error("Pseudowire with {} can not be added!", l2TunnelDescription.l2Tunnel().tunnelId());
             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) {
+    public L2TunnelHandler.Result removePseudowire(Integer 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;
-        }
+        List<L2Tunnel> tunnels = getL2Tunnels();
+        List<L2TunnelPolicy> policies = getL2Policies();
 
-        ObjectNode object = config.removePseudowire(pwId);
-        if (object == null) {
-            log.warn("Could not delete pseudowire from configuration!");
+        // get the pseudowire, if it exists
+        List<L2TunnelDescription> pseudowires = tunnels.stream().map(l2Tunnel -> {
+            L2TunnelPolicy policy = null;
+            for (L2TunnelPolicy l2Policy : policies) {
+                if (l2Policy.tunnelId() == l2Tunnel.tunnelId()) {
+                    policy = l2Policy;
+                    break;
+                }
+            }
+
+            return new DefaultL2TunnelDescription(l2Tunnel, policy);
+        }).filter(l2desc ->
+            l2desc.l2Tunnel().tunnelId() == pwId
+        ).collect(Collectors.toList());
+
+        if (pseudowires.size() == 0) {
+            log.error("Pseudowire with id {} does not exist", pwId);
             return L2TunnelHandler.Result.REMOVAL_ERROR;
+        } else {
+
+            l2TunnelHandler.tearDown(new HashSet<>(pseudowires));
+
+            log.info("Removal of pseudowire with {} started, check log for any errors in this process!",
+                     pwId);
+            return L2TunnelHandler.Result.SUCCESS;
         }
-
-        // 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
@@ -1411,21 +1436,6 @@
                     default:
                         break;
                 }
-            } else if (event.configClass().equals(PwaasConfig.class)) {
-                checkState(l2TunnelHandler != null, "DefaultL2TunnelHandler is not initialized");
-                switch (event.type()) {
-                    case CONFIG_ADDED:
-                        l2TunnelHandler.processPwaasConfigAdded(event);
-                        break;
-                    case CONFIG_UPDATED:
-                        l2TunnelHandler.processPwaasConfigUpdated(event);
-                        break;
-                    case CONFIG_REMOVED:
-                        l2TunnelHandler.processPwaasConfigRemoved(event);
-                        break;
-                    default:
-                        break;
-                }
             }
         }
 
@@ -1440,8 +1450,7 @@
             if (!event.configClass().equals(SegmentRoutingDeviceConfig.class) &&
                     !event.configClass().equals(SegmentRoutingAppConfig.class) &&
                     !event.configClass().equals(InterfaceConfig.class) &&
-                    !event.configClass().equals(XConnectConfig.class) &&
-                    !event.configClass().equals(PwaasConfig.class)) {
+                    !event.configClass().equals(XConnectConfig.class)) {
                 log.debug("Ignore event {} due to class mismatch", event);
                 return false;
             }
diff --git a/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java b/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
index 6f115e4..fa7b7d6 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingService.java
@@ -25,6 +25,7 @@
 import org.onosproject.segmentrouting.pwaas.L2Tunnel;
 import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
 import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
 import org.onosproject.segmentrouting.storekey.DestinationSetNextObjectiveStoreKey;
 
 import com.google.common.collect.ImmutableMap;
@@ -101,33 +102,20 @@
     List<L2TunnelPolicy> getL2Policies();
 
     /**
-     * Removes pw. Essentially updates configuration for PwaasConfig
-     * and sends event for removal. The rest are handled by DefaultL2TunnelHandler
+     * Removes pseudowire. Used ONLY by the REST api.
      *
-     * @param pwId The pseudowire id
+     * @param pwId The id of the pseudowire.
      * @return SUCCESS if operation successful or a descriptive error otherwise.
      */
-    L2TunnelHandler.Result removePseudowire(String pwId);
+    L2TunnelHandler.Result removePseudowire(Integer 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
+     * @param tunnel The pseudowire tunnel.
      * @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);
+    L2TunnelHandler.Result addPseudowire(L2TunnelDescription tunnel);
 
     /**
      * Creates a policy.
diff --git a/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java b/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
index d916823..ab80aff 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireAddCommand.java
@@ -19,8 +19,17 @@
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
+import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
+import org.onosproject.segmentrouting.pwaas.L2Tunnel;
+import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
 import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
+import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
+
+import static org.onosproject.segmentrouting.pwaas.PwaasUtil.*;
 
 
 /**
@@ -86,16 +95,36 @@
         SegmentRoutingService srService =
                 AbstractShellCommand.get(SegmentRoutingService.class);
 
-        L2TunnelHandler.Result res = srService.addPseudowire(pwId, pwLabel,
-                                                             cP1, cP1InnerVlan, cP1OuterVlan,
-                                                             cP2, cP2InnerVlan, cP2OuterVlan,
-                                                             mode, sDTag);
+        L2Tunnel tun;
+        L2TunnelPolicy policy;
+
+        try {
+            tun = new DefaultL2Tunnel(parseMode(mode), parseVlan(sDTag), parsePwId(pwId), parsePWLabel(pwLabel));
+        } catch (Exception e) {
+            print("Exception while parsing L2Tunnel : {}", e);
+            return;
+        }
+
+        try {
+            policy = new DefaultL2TunnelPolicy(parsePwId(pwId),
+                                               ConnectPoint.deviceConnectPoint(cP1), parseVlan(cP1InnerVlan),
+                                               parseVlan(cP1OuterVlan), ConnectPoint.deviceConnectPoint(cP2),
+                                               parseVlan(cP2InnerVlan), parseVlan(cP2OuterVlan));
+
+        } catch (Exception e) {
+            print("Exception while parsing L2TunnelPolicy : {}", e);
+            return;
+        }
+
+        L2TunnelDescription pw = new DefaultL2TunnelDescription(tun, policy);
+        L2TunnelHandler.Result res = srService.addPseudowire(pw);
+
         switch (res) {
             case ADDITION_ERROR:
-                print("Pseudowire could not be added, error in configuration, please check logs for more details!");
+                print("Pseudowire could not be added, please check logs for more details!");
                 break;
-            case CONFIG_NOT_FOUND:
-                print("Configuration for pwaas was not found! Initialize the configuration first through netcfg.");
+            case SUCCESS:
+                print("Pseudowire was added succesfully!");
                 break;
             default:
                 break;
diff --git a/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java b/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
index 098bbf9..0f027b2 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/cli/PseudowireRemoveCommand.java
@@ -23,6 +23,8 @@
 import org.onosproject.segmentrouting.SegmentRoutingService;
 import org.onosproject.segmentrouting.pwaas.L2TunnelHandler;
 
+import static org.onosproject.segmentrouting.pwaas.PwaasUtil.parsePwId;
+
 
 /**
  * Command to remove a pseudowire.
@@ -44,8 +46,15 @@
 
         // remove the pseudowire
         SegmentRoutingManager mngr = (SegmentRoutingManager) srService;
-        L2TunnelHandler.Result res = mngr.removePseudowire(pwId);
+        int pwIntId;
+        try {
+            pwIntId = parsePwId(pwId);
+        } catch (Exception e) {
+            print("Exception while parsing pseudowire id : {}", e);
+            return;
+        }
 
+        L2TunnelHandler.Result res = mngr.removePseudowire(pwIntId);
         switch (res) {
             case REMOVAL_ERROR:
                 error("Error in deletion, pseudowire not found!");
diff --git a/app/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java b/app/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java
deleted file mode 100644
index 31cad7e..0000000
--- a/app/src/main/java/org/onosproject/segmentrouting/config/PwaasConfig.java
+++ /dev/null
@@ -1,671 +0,0 @@
-/*
- * Copyright 2016-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.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.L2Tunnel;
-import org.onosproject.segmentrouting.pwaas.L2TunnelDescription;
-import org.onosproject.segmentrouting.pwaas.L2TunnelPolicy;
-import org.onosproject.segmentrouting.pwaas.DefaultL2Tunnel;
-import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelDescription;
-import org.onosproject.segmentrouting.pwaas.DefaultL2TunnelPolicy;
-import org.onosproject.segmentrouting.pwaas.L2Mode;
-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);
-
-    private static final String SRC_CP = "cP1";
-    private static final String DST_CP = "cP2";
-    private static final String SRC_OUTER_TAG = "cP1OuterTag";
-    private static final String DST_OUTER_TAG = "cP2OuterTag";
-    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 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.
-     */
-    private static final String MISSING_PARAMS = "Missing parameters in pseudo wire description";
-
-    /**
-     * Error message for invalid l2 mode.
-     */
-    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<L2TunnelDescription> pseudowires;
-        try {
-            pseudowires = getPwIds().stream()
-                    .map(this::getPwDescription)
-                    .collect(Collectors.toSet());
-
-            // check semantics now and return
-            return configurationValidity(pseudowires);
-
-        } catch (IllegalArgumentException e) {
-            log.warn("{}", e.getMessage());
-            return false;
-        }
-    }
-
-    /**
-     * 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(L2Tunnel 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) && !ingressInner.equals(VlanId.NONE)) &&
-                (egressOuter.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE)))
-                || ((ingressOuter.equals(VlanId.NONE) && ingressInner.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))
-           || (egressOuter.equals(VlanId.NONE) &&
-                !egressInner.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(L2Tunnel tunnel,
-                                      L2TunnelPolicy 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(L2TunnelDescription l2TunnelDescription,
-                                  Set<MplsLabel> labelSet,
-                                  Map<ConnectPoint, Set<VlanId>> vlanset,
-                                  Set<Long> tunnelSet) {
-
-        L2Tunnel l2Tunnel = l2TunnelDescription.l2Tunnel();
-        L2TunnelPolicy 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<L2TunnelDescription> 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 (L2TunnelDescription pw : pseudowires) {
-            verifyPseudoWire(pw, labelsUsed, vlanIds, tunIds);
-        }
-
-        return true;
-    }
-
-    /**
-     * Returns all pseudo wire keys.
-     *
-     * @return all keys (tunnels id)
-     * @throws IllegalArgumentException if wrong format
-     */
-    public Set<Long> getPwIds() {
-        ImmutableSet.Builder<Long> builder = ImmutableSet.builder();
-        object.fields().forEachRemaining(entry -> {
-            Long tunnelId = Long.parseLong(entry.getKey());
-            builder.add(tunnelId);
-        });
-        return builder.build();
-    }
-
-    /**
-     * 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
-     * @return set of l2 tunnel descriptions
-     * @throws IllegalArgumentException if wrong format
-     */
-    public L2TunnelDescription getPwDescription(Long tunnelId) {
-        JsonNode pwDescription = object.get(tunnelId.toString());
-        if (!hasFields((ObjectNode) pwDescription,
-                      SRC_CP, SRC_INNER_TAG, SRC_OUTER_TAG,
-                      DST_CP, DST_INNER_TAG, DST_OUTER_TAG,
-                      MODE, SD_TAG, PW_LABEL)) {
-            throw new IllegalArgumentException(MISSING_PARAMS);
-        }
-        String tempString;
-
-        tempString = pwDescription.get(SRC_CP).asText();
-        ConnectPoint srcCp = ConnectPoint.deviceConnectPoint(tempString);
-
-        tempString = pwDescription.get(DST_CP).asText();
-        ConnectPoint dstCp = ConnectPoint.deviceConnectPoint(tempString);
-
-        tempString = pwDescription.get(SRC_INNER_TAG).asText();
-        VlanId srcInnerTag = parseVlan(tempString);
-
-        tempString = pwDescription.get(SRC_OUTER_TAG).asText();
-        VlanId srcOuterTag = parseVlan(tempString);
-
-        tempString = pwDescription.get(DST_INNER_TAG).asText();
-        VlanId dstInnerTag = parseVlan(tempString);
-
-        tempString = pwDescription.get(DST_OUTER_TAG).asText();
-        VlanId dstOuterTag = parseVlan(tempString);
-
-        tempString = pwDescription.get(MODE).asText();
-        L2Mode l2Mode = parseMode(tempString);
-
-        tempString = pwDescription.get(SD_TAG).asText();
-        VlanId sdTag = parseVlan(tempString);
-
-        tempString = pwDescription.get(PW_LABEL).asText();
-        MplsLabel pwLabel = parsePWLabel(tempString);
-
-        L2Tunnel l2Tunnel = new DefaultL2Tunnel(
-                l2Mode,
-                sdTag,
-                tunnelId,
-                pwLabel
-        );
-
-        L2TunnelPolicy l2TunnelPolicy = new DefaultL2TunnelPolicy(
-                tunnelId,
-                srcCp,
-                srcInnerTag,
-                srcOuterTag,
-                dstCp,
-                dstInnerTag,
-                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);
-
-        if (!isValid()) {
-            log.info("Pseudowire could not be created : {}");
-            object.remove(tunnelId);
-            return null;
-        }
-
-        return object;
-    }
-}
diff --git a/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java b/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
index 2dc9de2..4b3272d 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/pwaas/DefaultL2TunnelHandler.java
@@ -30,7 +30,6 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.config.NetworkConfigEvent;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
@@ -49,7 +48,6 @@
 import org.onosproject.segmentrouting.SegmentRoutingManager;
 import org.onosproject.segmentrouting.SegmentRoutingService;
 import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
-import org.onosproject.segmentrouting.config.PwaasConfig;
 import org.onosproject.store.serializers.KryoNamespaces;
 import org.onosproject.store.service.ConsistentMap;
 import org.onosproject.store.service.DistributedSet;
@@ -64,7 +62,6 @@
 import java.util.concurrent.CompletableFuture;
 import java.util.stream.Collectors;
 
-import static com.google.common.base.Preconditions.checkArgument;
 import static org.onosproject.net.flowobjective.ForwardingObjective.Flag.VERSATILE;
 import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Pipeline.INITIATION;
 import static org.onosproject.segmentrouting.pwaas.L2TunnelHandler.Pipeline.TERMINATION;
@@ -168,28 +165,14 @@
     }
 
     /**
-     * Deploys any pre-existing pseudowires in the configuration.
      * Used by manager only in initialization.
      */
     @Override
     public void init() {
-
-        PwaasConfig config = srManager.cfgService.getConfig(srManager.appId(), PwaasConfig.class);
-        if (config == null) {
-            return;
-        }
-
-        log.info("Deploying existing pseudowires");
-
-        // gather pseudowires
-        Set<L2TunnelDescription> pwToAdd = config
-                .getPwIds()
-                .stream()
-                .map(config::getPwDescription)
-                .collect(Collectors.toSet());
-
-        // deploy pseudowires
-        deploy(pwToAdd);
+        // Since we have no pseudowires in netcfg there
+        // is nothing to do in initialization.
+        // I leave it here because potentially we might need to
+        // use it in the future.
     }
 
     /**
@@ -254,25 +237,6 @@
         pwToUpdate.forEach(tun -> updatePw(tun, tun));
     }
 
-    @Override
-    public void processPwaasConfigAdded(NetworkConfigEvent event) {
-        checkArgument(event.config().isPresent(),
-                "Config is not presented in PwaasConfigAdded event {}", event);
-
-        log.info("Network event : Pseudowire configuration added!");
-        PwaasConfig config = (PwaasConfig) event.config().get();
-
-        // gather pseudowires
-        Set<L2TunnelDescription> pwToAdd = config
-                .getPwIds()
-                .stream()
-                .map(config::getPwDescription)
-                .collect(Collectors.toSet());
-
-        // deploy pseudowires
-        deploy(pwToAdd);
-    }
-
     /**
      * Returns the new vlan id for an ingress point of a
      * pseudowire. For double tagged, it is the outer,
@@ -334,10 +298,7 @@
     }
 
     /**
-     * Adds a single pseudowire from leaf to a leaf.
-     * This method can be called from cli commands
-     * without configuration updates, thus it does not check for mastership
-     * of the ingress pseudowire device.
+     * Adds a single pseudowire.
      *
      * @param pw The pseudowire
      * @param spinePw True if pseudowire is from leaf to spine
@@ -490,15 +451,10 @@
 
     /**
      * 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<L2TunnelDescription> pwToAdd) {
+    public void deploy(Set<L2TunnelDescription> pwToAdd) {
 
         Result result;
 
@@ -507,11 +463,6 @@
             ConnectPoint cp2 = currentL2Tunnel.l2TunnelPolicy().cP2();
             long tunnelId = currentL2Tunnel.l2TunnelPolicy().tunnelId();
 
-            // only the master of CP1 will program this pseudowire
-            if (!srManager.isMasterOf(cp1)) {
-                log.debug("Not the master of {}. Ignore pseudo wire deployment id={}", cp1, tunnelId);
-                continue;
-            }
 
             try {
                 // differentiate between leaf-leaf pseudowires and leaf-spine
@@ -550,57 +501,6 @@
         }
     }
 
-
-    @Override
-    public void processPwaasConfigUpdated(NetworkConfigEvent event) {
-        checkArgument(event.config().isPresent(),
-                "Config is not presented in PwaasConfigUpdated event {}", event);
-        checkArgument(event.prevConfig().isPresent(),
-                "PrevConfig is not presented in PwaasConfigUpdated event {}", event);
-
-        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)))
-                .collect(Collectors.toSet());
-
-        // The pseudo wires to remove.
-        Set<Long> rmvPWs = prevPws.stream()
-                .filter(tunnelId -> !newPws.contains(tunnelId)).collect(Collectors.toSet());
-
-        Set<L2TunnelDescription> pwToRemove = rmvPWs.stream()
-                .map(prevConfig::getPwDescription)
-                .collect(Collectors.toSet());
-        tearDown(pwToRemove);
-
-        // The pseudo wires to add.
-        Set<Long> addedPWs = newPws.stream()
-                .filter(tunnelId -> !prevPws.contains(tunnelId))
-                .collect(Collectors.toSet());
-        Set<L2TunnelDescription> 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)));
-
-        log.info("Pseudowires removed : {}, Pseudowires updated : {}, Pseudowires added : {}", rmvPWs,
-                 updPws, addedPWs);
-    }
-
     /**
      * Helper function to update a pw.
      * <p>
@@ -621,11 +521,6 @@
         ConnectPoint oldCp1 = oldPw.l2TunnelPolicy().cP1();
         long tunnelId = oldPw.l2Tunnel().tunnelId();
 
-        // only the master of CP1 will update this pseudowire
-        if (!srManager.isMasterOf(oldPw.l2TunnelPolicy().cP1())) {
-            log.debug("Not the master of {}. Ignore pseudo wire update id={}", oldCp1, tunnelId);
-            return;
-        }
         // only determine if the new pseudowire is leaf-spine, because
         // removal process is the same for both leaf-leaf and leaf-spine pws
         boolean newPwSpine;
@@ -815,24 +710,6 @@
         });
     }
 
-    @Override
-    public void processPwaasConfigRemoved(NetworkConfigEvent event) {
-        checkArgument(event.prevConfig().isPresent(),
-                "PrevConfig is not presented in PwaasConfigRemoved event {}", event);
-
-        log.info("Network event : Pseudowire configuration removed!");
-        PwaasConfig config = (PwaasConfig) event.prevConfig().get();
-
-        Set<L2TunnelDescription> pwToRemove = config
-                .getPwIds()
-                .stream()
-                .map(config::getPwDescription)
-                .collect(Collectors.toSet());
-
-        // We teardown all the pseudo wire deployed
-        tearDown(pwToRemove);
-    }
-
     /**
      * Helper function for removing a single pseudowire.
      * <p>
@@ -957,12 +834,6 @@
             ConnectPoint cp2 = currentL2Tunnel.l2TunnelPolicy().cP2();
             long tunnelId = currentL2Tunnel.l2TunnelPolicy().tunnelId();
 
-            // only the master of CP1 will program this pseudowire
-            if (!srManager.isMasterOf(cp1)) {
-                log.debug("Not the master of {}. Ignore pseudo wire removal id={}", cp1, tunnelId);
-                continue;
-            }
-
             // no need to differentiate here between leaf-leaf and leaf-spine, because
             // the only change is in the groups, which we do not remove either way
             log.info("Removing pseudowire {}", tunnelId);
diff --git a/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java b/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
index 044ad41..5fce137 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/pwaas/L2TunnelHandler.java
@@ -17,7 +17,6 @@
 package org.onosproject.segmentrouting.pwaas;
 
 import org.onosproject.net.Link;
-import org.onosproject.net.config.NetworkConfigEvent;
 
 import java.util.List;
 import java.util.Set;
@@ -48,27 +47,6 @@
     void processLinkDown(Link link);
 
     /**
-     * Processes Pwaas Config added event.
-     *
-     * @param event network config add event
-     */
-    void processPwaasConfigAdded(NetworkConfigEvent event);
-
-    /**
-     * Processes PWaaS Config updated event.
-     *
-     * @param event network config updated event
-     */
-    void processPwaasConfigUpdated(NetworkConfigEvent event);
-
-    /**
-     * Processes Pwaas Config removed event.
-     *
-     * @param event network config removed event
-     */
-    void processPwaasConfigRemoved(NetworkConfigEvent event);
-
-    /**
      * Helper function to handle the pw removal.
      * <p>
      * This method should for the mastership of the device because it is
diff --git a/app/src/main/java/org/onosproject/segmentrouting/pwaas/PwaasUtil.java b/app/src/main/java/org/onosproject/segmentrouting/pwaas/PwaasUtil.java
new file mode 100644
index 0000000..fa2807e
--- /dev/null
+++ b/app/src/main/java/org/onosproject/segmentrouting/pwaas/PwaasUtil.java
@@ -0,0 +1,478 @@
+/*
+ * Copyright 2015-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting.pwaas;
+
+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.net.ConnectPoint;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.intf.InterfaceService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class with static methods that help
+ * parse pseudowire related information and also
+ * verify that a pseudowire combination is valid.
+ */
+public final class PwaasUtil {
+
+    private static final Logger log = LoggerFactory.getLogger(PwaasUtil.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public static DeviceService deviceService = AbstractShellCommand.get(DeviceService.class);;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    public static InterfaceService intfService = AbstractShellCommand.get(InterfaceService.class);
+
+    private PwaasUtil() {
+        return;
+    }
+
+    /**
+     * 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 null if error
+     */
+    public static 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) {
+                return null;
+            }
+        }
+    }
+
+    /**
+     *
+     * @param mode RAW or TAGGED
+     * @return the L2Mode if input is correct
+     */
+    public static L2Mode parseMode(String mode) {
+
+        if (!mode.equals("RAW") && !mode.equals("TAGGED")) {
+            return null;
+        }
+
+        return L2Mode.valueOf(mode);
+    }
+
+    /**
+     *
+     * @param label the mpls label of the pseudowire
+     * @return the MplsLabel
+     * @throws IllegalArgumentException if label is invalid
+     */
+    public static MplsLabel parsePWLabel(String label) {
+
+        try {
+            MplsLabel pwLabel = MplsLabel.mplsLabel(label);
+            return pwLabel;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+    /**
+     * Parses a string as a pseudowire id - which is an integer.
+     *
+     * @param id The id of pw in string form
+     * @return The id of pw as an Integer or null if it failed the conversion.
+     */
+    public static Integer parsePwId(String id) {
+        try {
+            return Integer.parseInt(id);
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+
+    /**
+     * Helper method to verify if the tunnel is whether or not
+     * supported.
+     *
+     * @param l2Tunnel the tunnel to verify
+     */
+    private static void verifyTunnel(L2Tunnel 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
+     */
+    private static 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) && !ingressInner.equals(VlanId.NONE)) &&
+                (egressOuter.equals(VlanId.NONE) && egressInner.equals(VlanId.NONE)))
+                || ((ingressOuter.equals(VlanId.NONE) && ingressInner.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))
+                || (egressOuter.equals(VlanId.NONE) &&
+                !egressInner.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 static void verifyGlobalValidity(L2Tunnel tunnel,
+                                      L2TunnelPolicy 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 " +
+                                                                                                " 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
+     */
+    private static void verifyPseudoWire(L2TunnelDescription l2TunnelDescription,
+                                  Set<MplsLabel> labelSet,
+                                  Map<ConnectPoint, Set<VlanId>> vlanset,
+                                  Set<Long> tunnelSet) {
+
+        L2Tunnel l2Tunnel = l2TunnelDescription.l2Tunnel();
+        L2TunnelPolicy 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);
+
+    }
+
+    public static boolean configurationValidity(Set<L2TunnelDescription> 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<>();
+
+        // TODO : I know we should not use exceptions for flow control,
+        // however this code was originally implemented in the configuration
+        // addition where the exceptions were propagated and the configuration was
+        // deemed not valid. I plan in the future to refactor the parts that
+        // check the pseudowire validity.
+        //
+        // Ideally we would like to return a String which could also return to
+        // the user issuing the rest request for adding the pseudowire.
+        try {
+
+            // 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 (L2TunnelDescription pw : pseudowires) {
+                verifyPseudoWire(pw, labelsUsed, vlanIds, tunIds);
+            }
+        } catch (Exception e) {
+
+            log.error("Caught exception while validating pseudowire : {}", e.getMessage());
+            return false;
+        }
+
+        // return true
+        return true;
+    }
+
+}
