diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentCompilationException.java b/core/api/src/main/java/org/onosproject/net/intent/IntentCompilationException.java
new file mode 100644
index 0000000..bca5739
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentCompilationException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2014-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.net.intent;
+
+/**
+ * An exception thrown when a intent compilation fails.
+ */
+public class IntentCompilationException extends IntentException {
+
+    private static final long serialVersionUID = 2439094479018639853L;
+
+    public IntentCompilationException() {
+        super();
+    }
+
+    public IntentCompilationException(String message) {
+        super(message);
+    }
+
+    public IntentCompilationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
similarity index 90%
rename from core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java
rename to core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
index 9da412e..f5f884b 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MockResourceService.java
+++ b/core/api/src/test/java/org/onosproject/net/resource/MockResourceService.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.onosproject.net.intent.impl.compiler;
+package org.onosproject.net.resource;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
@@ -22,16 +22,6 @@
 import org.onlab.packet.VlanId;
 import org.onlab.util.Tools;
 import org.onosproject.net.TributarySlot;
-import org.onosproject.net.resource.ContinuousResourceId;
-import org.onosproject.net.resource.DiscreteResource;
-import org.onosproject.net.resource.DiscreteResourceId;
-import org.onosproject.net.resource.ResourceAllocation;
-import org.onosproject.net.resource.ResourceConsumer;
-import org.onosproject.net.resource.ResourceId;
-import org.onosproject.net.resource.ResourceListener;
-import org.onosproject.net.resource.Resource;
-import org.onosproject.net.resource.ResourceService;
-import org.onosproject.net.resource.Resources;
 
 import java.util.Collection;
 import java.util.HashMap;
@@ -43,7 +33,7 @@
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
-class MockResourceService implements ResourceService {
+public class MockResourceService implements ResourceService {
 
     private final Map<Resource, ResourceConsumer> assignment = new HashMap<>();
 
diff --git a/core/net/BUCK b/core/net/BUCK
index 25db0df..73bbe7d 100644
--- a/core/net/BUCK
+++ b/core/net/BUCK
@@ -4,8 +4,6 @@
     '//utils/rest:onlab-rest',
     '//incubator/net:onos-incubator-net',
     '//incubator/store:onos-incubator-store',
-    # TODO Remove after decoupling optical
-    '//apps/optical-model:onos-apps-optical-model',
 ]
 
 TEST_DEPS = [
diff --git a/core/net/pom.xml b/core/net/pom.xml
index 32b4ab5..1d3650b 100644
--- a/core/net/pom.xml
+++ b/core/net/pom.xml
@@ -104,14 +104,6 @@
             <artifactId>onos-incubator-api</artifactId>
         </dependency>
 
-        <!-- TODO Remove after decoupling optical -->
-        <!-- - OpticalCompilers x4 -->
-        <dependency>
-            <groupId>org.onosproject</groupId>
-            <artifactId>onos-optical-model</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
         <dependency>
             <groupId>org.apache.karaf.features</groupId>
             <artifactId>org.apache.karaf.features.core</artifactId>
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCompilationException.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCompilationException.java
index d5d1bce..0fdface 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCompilationException.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentCompilationException.java
@@ -19,7 +19,10 @@
 
 /**
  * An exception thrown when a intent compilation fails.
+ *
+ * @deprecated in in Hummingbird (1.6.0) use {@link org.onosproject.net.intent.IntentCompilationException} instead.
  */
+@Deprecated
 public class IntentCompilationException extends IntentException {
     private static final long serialVersionUID = 235237603018210810L;
 
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/ResourceHelper.java b/core/net/src/main/java/org/onosproject/net/intent/impl/ResourceHelper.java
deleted file mode 100644
index 525d09e..0000000
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/ResourceHelper.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2016 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onosproject.net.intent.impl;
-
-import com.google.common.annotations.Beta;
-import org.onosproject.net.intent.IntentId;
-import org.onosproject.net.resource.ResourceConsumerId;
-
-import java.util.Optional;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * Helper class for ResourceService related processes.
- */
-@Beta
-public final class ResourceHelper {
-
-    // To avoid instantiation
-    private ResourceHelper() {
-    }
-
-    /**
-     * Creates IntentId object from given consumer ID.
-     *
-     * @param consumerId ConsumerId object
-     * @return Created IntentId object.  null if failed to create or given consumer is not instance of IntentId.
-     */
-    public static Optional<IntentId> getIntentId(ResourceConsumerId consumerId) {
-        checkNotNull(consumerId);
-
-        if (!consumerId.isClassOf(IntentId.class)) {
-            return Optional.empty();
-        }
-
-        return Optional.of(IntentId.valueOf(consumerId.value()));
-    }
-
-}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
index 9fd7b12..5dda4ee 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentCompiler.java
@@ -52,9 +52,9 @@
 import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
 import org.onosproject.net.intent.FlowRuleIntent;
 import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompilationException;
 import org.onosproject.net.intent.IntentCompiler;
 import org.onosproject.net.intent.LinkCollectionIntent;
-import org.onosproject.net.intent.impl.IntentCompilationException;
 
 import java.util.ArrayList;
 import java.util.Collections;
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
deleted file mode 100644
index b598b73..0000000
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompiler.java
+++ /dev/null
@@ -1,584 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.net.intent.impl.compiler;
-
-import com.google.common.base.Strings;
-
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Modified;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.util.Tools;
-import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.AnnotationKeys;
-import org.onosproject.net.CltSignalType;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.OduSignalId;
-import org.onosproject.net.OduSignalType;
-import org.onosproject.net.OduSignalUtils;
-import org.onosproject.net.Port;
-import org.onosproject.net.TributarySlot;
-import org.onosproject.net.behaviour.TributarySlotQuery;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.driver.Driver;
-import org.onosproject.net.driver.DriverService;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.intent.FlowRuleIntent;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentCompiler;
-import org.onosproject.net.intent.IntentExtensionService;
-import org.onosproject.net.intent.IntentId;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.intent.OpticalCircuitIntent;
-import org.onosproject.net.intent.OpticalConnectivityIntent;
-import org.onosproject.net.intent.impl.IntentCompilationException;
-import org.onosproject.net.optical.OchPort;
-import org.onosproject.net.optical.OduCltPort;
-import org.onosproject.net.intent.IntentSetMultimap;
-import org.onosproject.net.intent.impl.ResourceHelper;
-import org.onosproject.net.resource.ResourceAllocation;
-import org.onosproject.net.resource.Resource;
-import org.onosproject.net.resource.ResourceService;
-import org.onosproject.net.resource.Resources;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.onosproject.net.optical.device.OpticalDeviceServiceView.opticalView;
-
-/**
- * An intent compiler for {@link org.onosproject.net.intent.OpticalCircuitIntent}.
- */
-@Component(immediate = true)
-public class OpticalCircuitIntentCompiler implements IntentCompiler<OpticalCircuitIntent> {
-
-    private static final Logger log = LoggerFactory.getLogger(OpticalCircuitIntentCompiler.class);
-
-    private static final int DEFAULT_MAX_CAPACITY = 10;
-
-    @Property(name = "maxCapacity", intValue = DEFAULT_MAX_CAPACITY,
-            label = "Maximum utilization of an optical connection.")
-
-    private int maxCapacity = DEFAULT_MAX_CAPACITY;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ComponentConfigService cfgService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected IntentExtensionService intentManager;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ResourceService resourceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected IntentSetMultimap intentSetMultimap;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected IntentService intentService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DriverService driverService;
-
-    private ApplicationId appId;
-
-    @Modified
-    public void modified(ComponentContext context) {
-        if (context == null) {
-            return;
-        }
-
-        Dictionary properties = context.getProperties();
-
-        //TODO for reduction check if the new capacity is smaller than the size of the current mapping
-        String propertyString = Tools.get(properties, "maxCapacity");
-
-        //Ignore if propertyString is empty or null
-        if (!Strings.isNullOrEmpty(propertyString)) {
-            try {
-                int temp = Integer.parseInt(propertyString);
-                //Ensure value is non-negative but allow zero as a way to shutdown the link
-                if (temp >= 0) {
-                    maxCapacity = temp;
-                }
-            } catch (NumberFormatException e) {
-                //Malformed arguments lead to no change of value (user should be notified of error)
-              log.error("The value '{}' for maxCapacity was not parsable as an integer.", propertyString, e);
-            }
-        } else {
-            //Notify of empty value but do not return (other properties will also go in this function)
-            log.error("The value for maxCapacity was set to an empty value.");
-        }
-
-    }
-
-    @Activate
-    public void activate(ComponentContext context) {
-        deviceService = opticalView(deviceService);
-        appId = coreService.registerApplication("org.onosproject.net.intent");
-        intentManager.registerCompiler(OpticalCircuitIntent.class, this);
-        cfgService.registerProperties(getClass());
-        modified(context);
-    }
-
-    @Deactivate
-    public void deactivate() {
-        intentManager.unregisterCompiler(OpticalCircuitIntent.class);
-        cfgService.unregisterProperties(getClass(), false);
-    }
-
-    @Override
-    public List<Intent> compile(OpticalCircuitIntent intent, List<Intent> installable) {
-        // Check if ports are OduClt ports
-        ConnectPoint src = intent.getSrc();
-        ConnectPoint dst = intent.getDst();
-        Port srcPort = deviceService.getPort(src.deviceId(), src.port());
-        Port dstPort = deviceService.getPort(dst.deviceId(), dst.port());
-        checkArgument(srcPort instanceof OduCltPort);
-        checkArgument(dstPort instanceof OduCltPort);
-
-        log.debug("Compiling optical circuit intent between {} and {}", src, dst);
-
-        // Release of intent resources here is only a temporary solution for handling the
-        // case of recompiling due to intent restoration (when intent state is FAILED).
-        // TODO: try to release intent resources in IntentManager.
-        resourceService.release(intent.id());
-
-        // Check OduClt ports availability
-        Resource srcPortResource = Resources.discrete(src.deviceId(), src.port()).resource();
-        Resource dstPortResource = Resources.discrete(dst.deviceId(), dst.port()).resource();
-        // If ports are not available, compilation fails
-        if (!Stream.of(srcPortResource, dstPortResource).allMatch(resourceService::isAvailable)) {
-            throw new IntentCompilationException("Ports for the intent are not available. Intent: " + intent);
-        }
-        List<Resource> ports = ImmutableList.of(srcPortResource, dstPortResource);
-
-        // Check if both devices support multiplexing (usage of TributarySlots)
-        boolean multiplexingSupported = isMultiplexingSupported(intent.getSrc())
-                && isMultiplexingSupported(intent.getDst());
-
-        OpticalConnectivityIntent connIntent = findOpticalConnectivityIntent(intent.getSrc(), intent.getDst(),
-                intent.getSignalType(), multiplexingSupported);
-
-        if (connIntent != null && !multiplexingSupported) {
-            return compile(intent, src, dst, Optional.of(connIntent), ports, false);
-        }
-
-        // Create optical connectivity intent if needed - no optical intent or not enough slots available
-        if (connIntent == null) {
-            return compile(intent, src, dst, Optional.empty(), ports, multiplexingSupported);
-        }
-
-        List<Resource> slots = availableSlotResources(connIntent.getSrc(), connIntent.getDst(),
-                intent.getSignalType());
-        if (slots.isEmpty()) {
-            return compile(intent, src, dst, Optional.empty(), ports, true);
-        }
-
-        return compile(intent, src, dst, Optional.of(connIntent), ImmutableList.<Resource>builder()
-                .addAll(ports).addAll(slots).build(), false);
-
-    }
-
-    private List<Intent> compile(OpticalCircuitIntent intent, ConnectPoint src, ConnectPoint dst,
-                                 Optional<OpticalConnectivityIntent> existingConnectivity,
-                                 List<Resource> resources, boolean supportsMultiplexing) {
-        OpticalConnectivityIntent connectivityIntent;
-        List<Resource> required;
-        if (existingConnectivity.isPresent()) {
-            connectivityIntent = existingConnectivity.get();
-            required = resources;
-        } else {
-            // Find OCh ports with available resources
-            Pair<OchPort, OchPort> ochPorts = findPorts(intent.getSrc(), intent.getDst(), intent.getSignalType());
-
-            if (ochPorts == null) {
-                throw new IntentCompilationException("Unable to find suitable OCH ports for intent " + intent);
-            }
-
-            ConnectPoint srcCP = new ConnectPoint(src.elementId(), ochPorts.getLeft().number());
-            ConnectPoint dstCP = new ConnectPoint(dst.elementId(), ochPorts.getRight().number());
-
-            // Create optical connectivity intent
-            connectivityIntent = OpticalConnectivityIntent.builder()
-                    .appId(appId)
-                    .src(srcCP)
-                    .dst(dstCP)
-                    .signalType(ochPorts.getLeft().signalType())
-                    .bidirectional(intent.isBidirectional())
-                    .build();
-
-            if (!supportsMultiplexing) {
-                required = resources;
-            } else {
-                List<Resource> slots = availableSlotResources(srcCP, dstCP, intent.getSignalType());
-                if (slots.isEmpty()) {
-                    throw new IntentCompilationException("Unable to find Tributary Slots for intent " + intent);
-                }
-                required = ImmutableList.<Resource>builder().addAll(resources).addAll(slots).build();
-            }
-        }
-
-        if (resourceService.allocate(intent.id(), required).isEmpty()) {
-            throw new IntentCompilationException("Unable to allocate resources for intent " + intent
-                    + ": resources=" + required);
-        }
-
-        intentService.submit(connectivityIntent);
-
-        // Save circuit to connectivity intent mapping
-        intentSetMultimap.allocateMapping(connectivityIntent.id(), intent.id());
-
-        FlowRuleIntent circuitIntent = createFlowRule(intent, connectivityIntent, required.stream().
-                flatMap(x -> Tools.stream(x.valueAs(TributarySlot.class)))
-                .collect(Collectors.toSet()));
-        return ImmutableList.of(circuitIntent);
-    }
-
-    private List<Resource> availableSlotResources(ConnectPoint src, ConnectPoint dst, CltSignalType signalType) {
-        OduSignalType oduSignalType = OduSignalUtils.mappingCltSignalTypeToOduSignalType(signalType);
-        int requestedTsNum = oduSignalType.tributarySlots();
-        Set<TributarySlot> commonTributarySlots = findCommonTributarySlotsOnCps(src, dst);
-        if (commonTributarySlots.isEmpty()) {
-            return Collections.emptyList();
-        }
-        if (commonTributarySlots.size() < requestedTsNum) {
-            return Collections.emptyList();
-        }
-
-        Set<TributarySlot> tributarySlots = commonTributarySlots.stream()
-                .limit(requestedTsNum)
-                .collect(Collectors.toSet());
-
-        final List<ConnectPoint> portsList = ImmutableList.of(src, dst);
-        List<Resource> tributarySlotResources = portsList.stream()
-                .flatMap(cp -> tributarySlots
-                        .stream()
-                        .map(ts-> Resources.discrete(cp.deviceId(), cp.port()).resource().child(ts)))
-                .collect(Collectors.toList());
-
-        if (!tributarySlotResources.stream().allMatch(resourceService::isAvailable)) {
-            log.debug("Resource allocation for {} on {} and {} failed (resource request: {})",
-                    signalType, src, dst, tributarySlotResources);
-            return Collections.emptyList();
-        }
-        return tributarySlotResources;
-    }
-
-    private FlowRuleIntent createFlowRule(OpticalCircuitIntent higherIntent,
-                                          OpticalConnectivityIntent lowerIntent, Set<TributarySlot> slots) {
-        // Create optical circuit intent
-        List<FlowRule> rules = new LinkedList<>();
-        // at the source: ODUCLT port mapping to OCH port
-        rules.add(connectPorts(higherIntent.getSrc(), lowerIntent.getSrc(), higherIntent.priority(), slots));
-        // at the destination: OCH port mapping to ODUCLT port
-        rules.add(connectPorts(lowerIntent.getDst(), higherIntent.getDst(), higherIntent.priority(), slots));
-
-        // Create flow rules for reverse path
-        if (higherIntent.isBidirectional()) {
-           // at the destination: OCH port mapping to ODUCLT port
-            rules.add(connectPorts(lowerIntent.getSrc(), higherIntent.getSrc(), higherIntent.priority(), slots));
-            // at the source: ODUCLT port mapping to OCH port
-            rules.add(connectPorts(higherIntent.getDst(), lowerIntent.getDst(), higherIntent.priority(), slots));
-        }
-
-        return new FlowRuleIntent(appId, rules, higherIntent.resources());
-    }
-
-    /**
-     * Returns existing and available optical connectivity intent that matches the given circuit intent.
-     *
-     * @param src source connect point of optical circuit intent
-     * @param dst destination connect point of optical circuit intent
-     * @param signalType signal type of optical circuit intent
-     * @param multiplexingSupported indicates whether ODU multiplexing is supported
-     * @return existing optical connectivity intent, null otherwise.
-     */
-    private OpticalConnectivityIntent findOpticalConnectivityIntent(ConnectPoint src,
-                                                                    ConnectPoint dst,
-                                                                    CltSignalType signalType,
-                                                                    boolean multiplexingSupported) {
-
-        OduSignalType oduSignalType = OduSignalUtils.mappingCltSignalTypeToOduSignalType(signalType);
-
-        return Tools.stream(intentService.getIntents())
-                .filter(x -> x instanceof OpticalConnectivityIntent)
-                .map(x -> (OpticalConnectivityIntent) x)
-                .filter(x -> src.deviceId().equals(x.getSrc().deviceId()))
-                .filter(x -> dst.deviceId().equals(x.getDst().deviceId()))
-                .filter(x -> isAllowed(src, x.getSrc()))
-                .filter(x -> isAllowed(dst, x.getDst()))
-                .filter(x -> isAvailable(x.id()))
-                .filter(x -> !multiplexingSupported ||
-                        isAvailableTributarySlots(x.getSrc(), x.getDst(), oduSignalType.tributarySlots()))
-                .findFirst()
-                .orElse(null);
-    }
-
-    private boolean isAllowed(ConnectPoint circuitCp, ConnectPoint connectivityCp) {
-        ConnectPoint staticPort = staticPort(circuitCp);
-        return staticPort == null || staticPort.equals(connectivityCp);
-    }
-
-    /**
-     * Checks if current allocations on given resource can satisfy request.
-     * If the resource is null, return true.
-     *
-     * @param resource the resource on which to map the intent
-     * @return true if the resource can accept the request, false otherwise
-     */
-    private boolean isAvailable(IntentId resource) {
-        if (resource == null) {
-            return true;
-        }
-
-        Set<IntentId> mapping = intentSetMultimap.getMapping(resource);
-
-        if (mapping == null) {
-            return true;
-        }
-
-        return mapping.size() < maxCapacity;
-    }
-
-    private boolean isAvailableTributarySlots(ConnectPoint src, ConnectPoint dst, int requestedTsNum) {
-        Set<TributarySlot> common = findCommonTributarySlotsOnCps(src, dst);
-        if (common.isEmpty()) {
-            log.debug("No available TributarySlots");
-            return false;
-        }
-        if (common.size() < requestedTsNum) {
-            log.debug("Not enough available TributarySlots={} < requestedTsNum={}", common.size(), requestedTsNum);
-            return false;
-        }
-        return true;
-    }
-
-    private ConnectPoint staticPort(ConnectPoint connectPoint) {
-        Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
-
-        String staticPort = port.annotations().value(AnnotationKeys.STATIC_PORT);
-
-        // FIXME: need a better way to match the port
-        if (staticPort != null) {
-            for (Port p : deviceService.getPorts(connectPoint.deviceId())) {
-                if (staticPort.equals(p.number().name())) {
-                    return new ConnectPoint(p.element().id(), p.number());
-                }
-            }
-        }
-
-        return null;
-    }
-
-    private Pair<OchPort, OchPort> findPorts(ConnectPoint src, ConnectPoint dst, CltSignalType signalType) {
-        // According to the OpticalCircuitIntent's signalType find OCH ports with available TributarySlots resources
-        switch (signalType) {
-            case CLT_1GBE:
-            case CLT_10GBE:
-                // First search for OCH ports with OduSignalType of ODU2. If not found - search for those with ODU4
-                return findPorts(src, dst, OduSignalType.ODU2)
-                        .orElse(findPorts(src, dst, OduSignalType.ODU4).orElse(null));
-            case CLT_100GBE:
-                return findPorts(src, dst, OduSignalType.ODU4).orElse(null);
-            case CLT_40GBE:
-            default:
-                return null;
-        }
-    }
-
-    private Optional<Pair<OchPort, OchPort>> findPorts(ConnectPoint src, ConnectPoint dst,
-                                                       OduSignalType ochPortSignalType) {
-        return findAvailableOchPort(src, ochPortSignalType)
-                .flatMap(srcOch ->
-                        findAvailableOchPort(dst, ochPortSignalType).map(dstOch -> Pair.of(srcOch, dstOch)));
-    }
-
-    private Optional<OchPort> findAvailableOchPort(ConnectPoint oduPort, OduSignalType ochPortSignalType) {
-        // First see if the port mappings are constrained
-        ConnectPoint ochCP = staticPort(oduPort);
-
-        if (ochCP != null) {
-            OchPort ochPort = (OchPort) deviceService.getPort(ochCP.deviceId(), ochCP.port());
-            Optional<IntentId> intentId =
-                    resourceService.getResourceAllocations(Resources.discrete(ochCP.deviceId(), ochCP.port()).id())
-                            .stream()
-                            .map(ResourceAllocation::consumerId)
-                            .map(ResourceHelper::getIntentId)
-                            .flatMap(Tools::stream)
-                            .findAny();
-
-            if (isAvailable(intentId.orElse(null))) {
-                return Optional.of(ochPort);
-            }
-            return Optional.empty();
-        }
-
-        // No port constraints, so find any port that works
-        List<Port> ports = deviceService.getPorts(oduPort.deviceId());
-
-        for (Port port : ports) {
-            if (!(port instanceof OchPort)) {
-                continue;
-            }
-            // This should be the first allocation on the OCH port
-            if (!resourceService.isAvailable(Resources.discrete(oduPort.deviceId(), port.number()).resource())) {
-                continue;
-            }
-            // OchPort is required to have the requested oduSignalType
-            if (((OchPort) port).signalType() != ochPortSignalType) {
-                continue;
-            }
-
-            Optional<IntentId> intentId =
-                    resourceService.getResourceAllocations(Resources.discrete(oduPort.deviceId(), port.number()).id())
-                            .stream()
-                            .map(ResourceAllocation::consumerId)
-                            .map(ResourceHelper::getIntentId)
-                            .flatMap(Tools::stream)
-                            .findAny();
-
-            if (isAvailable(intentId.orElse(null))) {
-                return Optional.of((OchPort) port);
-            }
-        }
-
-        return Optional.empty();
-    }
-
-    /**
-     * Builds flow rule for mapping between two ports.
-     *
-     * @param src source port
-     * @param dst destination port
-     * @param priority
-     * @param slots Set of TributarySlots
-     * @return flow rules
-     */
-    private FlowRule connectPorts(ConnectPoint src, ConnectPoint dst, int priority, Set<TributarySlot> slots) {
-        checkArgument(src.deviceId().equals(dst.deviceId()));
-
-        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
-        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-
-        selectorBuilder.matchInPort(src.port());
-        if (!slots.isEmpty()) {
-            Port srcPort = deviceService.getPort(src.deviceId(), src.port());
-            Port dstPort = deviceService.getPort(dst.deviceId(), dst.port());
-            OduSignalType oduCltPortOduSignalType;
-            OduSignalType ochPortOduSignalType;
-
-            if (srcPort instanceof OduCltPort) {
-                oduCltPortOduSignalType =
-                        OduSignalUtils.mappingCltSignalTypeToOduSignalType(((OduCltPort) srcPort).signalType());
-                ochPortOduSignalType = ((OchPort) dstPort).signalType();
-
-                selectorBuilder.add(Criteria.matchOduSignalType(oduCltPortOduSignalType));
-                // use Instruction of OduSignalId only in case of ODU Multiplexing
-                if (oduCltPortOduSignalType != ochPortOduSignalType) {
-                    OduSignalId oduSignalId = OduSignalUtils.buildOduSignalId(ochPortOduSignalType, slots);
-                    treatmentBuilder.add(Instructions.modL1OduSignalId(oduSignalId));
-                }
-            } else { // srcPort is OchPort
-                oduCltPortOduSignalType =
-                        OduSignalUtils.mappingCltSignalTypeToOduSignalType(((OduCltPort) dstPort).signalType());
-                ochPortOduSignalType = ((OchPort) srcPort).signalType();
-
-                selectorBuilder.add(Criteria.matchOduSignalType(oduCltPortOduSignalType));
-                // use Criteria of OduSignalId only in case of ODU Multiplexing
-                if (oduCltPortOduSignalType != ochPortOduSignalType) {
-                    OduSignalId oduSignalId = OduSignalUtils.buildOduSignalId(ochPortOduSignalType, slots);
-                    selectorBuilder.add(Criteria.matchOduSignalId(oduSignalId));
-                }
-            }
-        }
-        treatmentBuilder.setOutput(dst.port());
-
-        FlowRule flowRule = DefaultFlowRule.builder()
-                .forDevice(src.deviceId())
-                .withSelector(selectorBuilder.build())
-                .withTreatment(treatmentBuilder.build())
-                .withPriority(priority)
-                .fromApp(appId)
-                .makePermanent()
-                .build();
-
-        return flowRule;
-    }
-
-    private boolean isMultiplexingSupported(ConnectPoint cp) {
-        Driver driver = driverService.getDriver(cp.deviceId());
-        return driver != null
-                && driver.hasBehaviour(TributarySlotQuery.class)
-                && staticPort(cp) == null;
-    }
-
-    /**
-     * Finds the common TributarySlots available on the two connect points.
-     *
-     * @param src source connect point
-     * @param dst dest connect point
-     * @return set of common TributarySlots on both connect points
-     */
-    Set<TributarySlot> findCommonTributarySlotsOnCps(ConnectPoint src, ConnectPoint dst) {
-        Set<TributarySlot> forward = findTributarySlotsOnCp(src);
-        Set<TributarySlot> backward = findTributarySlotsOnCp(dst);
-        return Sets.intersection(forward, backward);
-    }
-
-    /**
-     * Finds the TributarySlots available on the connect point.
-     *
-     * @param cp connect point
-     * @return set of TributarySlots available on the connect point
-     */
-    Set<TributarySlot> findTributarySlotsOnCp(ConnectPoint cp) {
-        return resourceService.getAvailableResourceValues(
-                Resources.discrete(cp.deviceId(), cp.port()).id(),
-                TributarySlot.class);
-    }
-}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
deleted file mode 100644
index b1ca006..0000000
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.net.intent.impl.compiler;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.util.Frequency;
-import org.onosproject.net.AnnotationKeys;
-import org.onosproject.net.ChannelSpacing;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultOchSignalComparator;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Link;
-import org.onosproject.net.OchSignal;
-import org.onosproject.net.OchSignalType;
-import org.onosproject.net.Path;
-import org.onosproject.net.Port;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentCompiler;
-import org.onosproject.net.intent.IntentExtensionService;
-import org.onosproject.net.intent.OpticalConnectivityIntent;
-import org.onosproject.net.intent.OpticalPathIntent;
-import org.onosproject.net.intent.impl.IntentCompilationException;
-import org.onosproject.net.optical.OchPort;
-import org.onosproject.net.resource.ResourceAllocation;
-import org.onosproject.net.resource.Resource;
-import org.onosproject.net.resource.ResourceService;
-import org.onosproject.net.resource.Resources;
-import org.onosproject.net.topology.LinkWeight;
-import org.onosproject.net.topology.Topology;
-import org.onosproject.net.topology.TopologyService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.onosproject.net.optical.device.OpticalDeviceServiceView.opticalView;
-
-/**
- * An intent compiler for {@link org.onosproject.net.intent.OpticalConnectivityIntent}.
- */
-@Component(immediate = true)
-public class OpticalConnectivityIntentCompiler implements IntentCompiler<OpticalConnectivityIntent> {
-
-    protected static final Logger log = LoggerFactory.getLogger(OpticalConnectivityIntentCompiler.class);
-    // By default, allocate 50 GHz lambdas (4 slots of 12.5 GHz) for each intent.
-    private static final int SLOT_COUNT = 4;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected IntentExtensionService intentManager;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected TopologyService topologyService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ResourceService resourceService;
-
-    @Activate
-    public void activate() {
-        deviceService = opticalView(deviceService);
-        intentManager.registerCompiler(OpticalConnectivityIntent.class, this);
-    }
-
-    @Deactivate
-    public void deactivate() {
-        intentManager.unregisterCompiler(OpticalConnectivityIntent.class);
-    }
-
-    @Override
-    public List<Intent> compile(OpticalConnectivityIntent intent,
-                                List<Intent> installable) {
-        // Check if source and destination are optical OCh ports
-        ConnectPoint src = intent.getSrc();
-        ConnectPoint dst = intent.getDst();
-        Port srcPort = deviceService.getPort(src.deviceId(), src.port());
-        Port dstPort = deviceService.getPort(dst.deviceId(), dst.port());
-        checkArgument(srcPort instanceof OchPort);
-        checkArgument(dstPort instanceof OchPort);
-
-        log.debug("Compiling optical connectivity intent between {} and {}", src, dst);
-
-        // Release of intent resources here is only a temporary solution for handling the
-        // case of recompiling due to intent restoration (when intent state is FAILED).
-        // TODO: try to release intent resources in IntentManager.
-        resourceService.release(intent.id());
-
-        // Check OCh port availability
-        Resource srcPortResource = Resources.discrete(src.deviceId(), src.port()).resource();
-        Resource dstPortResource = Resources.discrete(dst.deviceId(), dst.port()).resource();
-        // If ports are not available, compilation fails
-        if (!Stream.of(srcPortResource, dstPortResource).allMatch(resourceService::isAvailable)) {
-            throw new IntentCompilationException("Ports for the intent are not available. Intent: " + intent);
-        }
-
-        List<Resource> resources = new ArrayList<>();
-        resources.add(srcPortResource);
-        resources.add(dstPortResource);
-
-        // Calculate available light paths
-        Set<Path> paths = getOpticalPaths(intent);
-
-        if (paths.isEmpty()) {
-            throw new IntentCompilationException("Unable to find suitable lightpath for intent " + intent);
-        }
-
-        // Static or dynamic lambda allocation
-        String staticLambda = srcPort.annotations().value(AnnotationKeys.STATIC_LAMBDA);
-        OchPort srcOchPort = (OchPort) srcPort;
-        OchPort dstOchPort = (OchPort) dstPort;
-
-        Path firstPath = paths.iterator().next();
-        // FIXME: need to actually reserve the lambda for static lambda's
-        // static lambda case: early return
-        if (staticLambda != null) {
-            allocateResources(intent, resources);
-
-            OchSignal lambda = new OchSignal(Frequency.ofHz(Long.parseLong(staticLambda)),
-                    srcOchPort.lambda().channelSpacing(),
-                    srcOchPort.lambda().slotGranularity());
-            return ImmutableList.of(createIntent(intent, firstPath, lambda));
-        }
-
-        // FIXME: also check destination OCh port
-        // non-tunable case: early return
-        if (!srcOchPort.isTunable() || !dstOchPort.isTunable()) {
-            allocateResources(intent, resources);
-
-            OchSignal lambda = srcOchPort.lambda();
-            return ImmutableList.of(createIntent(intent, firstPath, lambda));
-        }
-
-        // remaining cases
-        // Use first path that the required resources are available
-        Optional<Map.Entry<Path, List<OchSignal>>> found = paths.stream()
-                .map(path -> Maps.immutableEntry(path, findFirstAvailableOch(path)))
-                .filter(entry -> !entry.getValue().isEmpty())
-                .filter(entry -> convertToResources(entry.getKey().links(),
-                        entry.getValue()).stream().allMatch(resourceService::isAvailable))
-                .findFirst();
-
-        if (found.isPresent()) {
-            resources.addAll(convertToResources(found.get().getKey().links(), found.get().getValue()));
-
-            allocateResources(intent, resources);
-
-            OchSignal ochSignal = OchSignal.toFixedGrid(found.get().getValue(), ChannelSpacing.CHL_50GHZ);
-            return ImmutableList.of(createIntent(intent, found.get().getKey(), ochSignal));
-        } else {
-            throw new IntentCompilationException("Unable to find suitable lightpath for intent " + intent);
-        }
-    }
-
-    private Intent createIntent(OpticalConnectivityIntent parentIntent, Path path, OchSignal lambda) {
-        // Create installable optical path intent
-        // Only support fixed grid for now
-        OchSignalType signalType = OchSignalType.FIXED_GRID;
-
-        return OpticalPathIntent.builder()
-                .appId(parentIntent.appId())
-                .src(parentIntent.getSrc())
-                .dst(parentIntent.getDst())
-                // calling paths.iterator().next() is safe because of non-empty set
-                .path(path)
-                .lambda(lambda)
-                .signalType(signalType)
-                .bidirectional(parentIntent.isBidirectional())
-                .build();
-    }
-
-    private void allocateResources(Intent intent, List<Resource> resources) {
-        // reserve all of required resources
-        List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), resources);
-        if (allocations.isEmpty()) {
-            log.info("Resource allocation for {} failed (resource request: {})", intent, resources);
-            throw new IntentCompilationException("Unable to allocate resources: " + resources);
-        }
-    }
-
-    private List<OchSignal> findFirstAvailableOch(Path path) {
-        Set<OchSignal> lambdas = findCommonLambdasOverLinks(path.links());
-        if (lambdas.isEmpty()) {
-            return Collections.emptyList();
-        }
-
-        return findFirstLambda(lambdas, slotCount());
-    }
-
-    private List<Resource> convertToResources(List<Link> links, List<OchSignal> lambda) {
-        return links.stream()
-                .flatMap(x -> Stream.of(
-                        Resources.discrete(x.src().deviceId(), x.src().port()).resource(),
-                        Resources.discrete(x.dst().deviceId(), x.dst().port()).resource()
-                ))
-                .flatMap(x -> lambda.stream().map(x::child))
-                .collect(Collectors.toList());
-    }
-
-    /**
-     * Get the number of 12.5 GHz slots required for the path.
-     *
-     * For now this returns a constant value of 4 (i.e., fixed grid 50 GHz slot),
-     * but in the future can depend on optical reach, line rate, transponder port capabilities, etc.
-     *
-     * @return number of slots
-     */
-    private int slotCount() {
-        return SLOT_COUNT;
-    }
-
-    private Set<OchSignal> findCommonLambdasOverLinks(List<Link> links) {
-        return links.stream()
-                .flatMap(x -> Stream.of(
-                        Resources.discrete(x.src().deviceId(), x.src().port()).id(),
-                        Resources.discrete(x.dst().deviceId(), x.dst().port()).id()
-                ))
-                .map(x -> resourceService.getAvailableResourceValues(x, OchSignal.class))
-                .map(x -> (Set<OchSignal>) ImmutableSet.copyOf(x))
-                .reduce(Sets::intersection)
-                .orElse(Collections.emptySet());
-    }
-
-    /**
-     * Returns list of consecutive resources in given set of lambdas.
-     *
-     * @param lambdas list of lambdas
-     * @param count number of consecutive lambdas to return
-     * @return list of consecutive lambdas
-     */
-    private List<OchSignal> findFirstLambda(Set<OchSignal> lambdas, int count) {
-        // Sort available lambdas
-        List<OchSignal> lambdaList = new ArrayList<>(lambdas);
-        lambdaList.sort(new DefaultOchSignalComparator());
-
-        // Look ahead by count and ensure spacing multiplier is as expected (i.e., no gaps)
-        for (int i = 0; i < lambdaList.size() - count; i++) {
-            if (lambdaList.get(i).spacingMultiplier() + 2 * count ==
-                    lambdaList.get(i + count).spacingMultiplier()) {
-                return lambdaList.subList(i, i + count);
-            }
-        }
-
-        return Collections.emptyList();
-    }
-
-    private ConnectPoint staticPort(ConnectPoint connectPoint) {
-        Port port = deviceService.getPort(connectPoint.deviceId(), connectPoint.port());
-
-        String staticPort = port.annotations().value(AnnotationKeys.STATIC_PORT);
-
-        // FIXME: need a better way to match the port
-        if (staticPort != null) {
-            for (Port p : deviceService.getPorts(connectPoint.deviceId())) {
-                if (staticPort.equals(p.number().name())) {
-                    return new ConnectPoint(p.element().id(), p.number());
-                }
-            }
-        }
-
-        return null;
-    }
-
-    /**
-     * Calculates optical paths in WDM topology.
-     *
-     * @param intent optical connectivity intent
-     * @return set of paths in WDM topology
-     */
-    private Set<Path> getOpticalPaths(OpticalConnectivityIntent intent) {
-        // Route in WDM topology
-        Topology topology = topologyService.currentTopology();
-        LinkWeight weight = edge -> {
-            // Disregard inactive or non-optical links
-            if (edge.link().state() == Link.State.INACTIVE) {
-                return -1;
-            }
-            if (edge.link().type() != Link.Type.OPTICAL) {
-                return -1;
-            }
-            // Adhere to static port mappings
-            DeviceId srcDeviceId = edge.link().src().deviceId();
-            if (srcDeviceId.equals(intent.getSrc().deviceId())) {
-                ConnectPoint srcStaticPort = staticPort(intent.getSrc());
-                if (srcStaticPort != null) {
-                    return srcStaticPort.equals(edge.link().src()) ? 1 : -1;
-                }
-            }
-            DeviceId dstDeviceId = edge.link().dst().deviceId();
-            if (dstDeviceId.equals(intent.getDst().deviceId())) {
-                ConnectPoint dstStaticPort = staticPort(intent.getDst());
-                if (dstStaticPort != null) {
-                    return dstStaticPort.equals(edge.link().dst()) ? 1 : -1;
-                }
-            }
-
-            return 1;
-        };
-
-        ConnectPoint start = intent.getSrc();
-        ConnectPoint end = intent.getDst();
-        Set<Path> paths = topologyService.getPaths(topology, start.deviceId(),
-                end.deviceId(), weight);
-
-        return paths;
-    }
-}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalOduIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalOduIntentCompiler.java
deleted file mode 100644
index d89cf1e..0000000
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalOduIntentCompiler.java
+++ /dev/null
@@ -1,384 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.net.intent.impl.compiler;
-
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Link;
-import org.onosproject.net.LinkKey;
-import org.onosproject.net.OduSignalId;
-import org.onosproject.net.OduSignalType;
-import org.onosproject.net.OduSignalUtils;
-import org.onosproject.net.Path;
-import org.onosproject.net.Port;
-import org.onosproject.net.TributarySlot;
-import org.onosproject.net.device.DeviceService;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.intent.FlowRuleIntent;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentCompiler;
-import org.onosproject.net.intent.IntentExtensionService;
-import org.onosproject.net.intent.OpticalOduIntent;
-import org.onosproject.net.intent.impl.IntentCompilationException;
-import org.onosproject.net.optical.OduCltPort;
-import org.onosproject.net.optical.OtuPort;
-import org.onosproject.net.resource.Resource;
-import org.onosproject.net.resource.ResourceService;
-import org.onosproject.net.resource.ResourceAllocation;
-import org.onosproject.net.resource.Resources;
-import org.onosproject.net.topology.LinkWeight;
-import org.onosproject.net.topology.Topology;
-import org.onosproject.net.topology.TopologyService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.onosproject.net.LinkKey.linkKey;
-import static org.onosproject.net.optical.device.OpticalDeviceServiceView.opticalView;
-
-/**
- * An intent compiler for {@link org.onosproject.net.intent.OpticalOduIntent}.
- */
-@Component(immediate = true)
-public class OpticalOduIntentCompiler implements IntentCompiler<OpticalOduIntent> {
-
-    private static final Logger log = LoggerFactory.getLogger(OpticalOduIntentCompiler.class);
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected IntentExtensionService intentManager;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected TopologyService topologyService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected DeviceService deviceService;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected ResourceService resourceService;
-
-    private ApplicationId appId;
-
-    @Activate
-    public void activate() {
-        deviceService = opticalView(deviceService);
-        appId = coreService.registerApplication("org.onosproject.net.intent");
-        intentManager.registerCompiler(OpticalOduIntent.class, this);
-    }
-
-    @Deactivate
-    public void deactivate() {
-        intentManager.unregisterCompiler(OpticalOduIntent.class);
-    }
-
-    @Override
-    public List<Intent> compile(OpticalOduIntent intent, List<Intent> installable) {
-        // Check if ports are OduClt ports
-        ConnectPoint src = intent.getSrc();
-        ConnectPoint dst = intent.getDst();
-        Port srcPort = deviceService.getPort(src.deviceId(), src.port());
-        Port dstPort = deviceService.getPort(dst.deviceId(), dst.port());
-        checkArgument(srcPort instanceof OduCltPort);
-        checkArgument(dstPort instanceof OduCltPort);
-
-        log.debug("Compiling optical ODU intent between {} and {}", src, dst);
-
-        // Release of intent resources here is only a temporary solution for handling the
-        // case of recompiling due to intent restoration (when intent state is FAILED).
-        // TODO: try to release intent resources in IntentManager.
-        resourceService.release(intent.id());
-
-        // Check OduClt ports availability
-        Resource srcPortResource = Resources.discrete(src.deviceId(), src.port()).resource();
-        Resource dstPortResource = Resources.discrete(dst.deviceId(), dst.port()).resource();
-        // If ports are not available, compilation fails
-        if (!Stream.of(srcPortResource, dstPortResource).allMatch(resourceService::isAvailable)) {
-            throw new IntentCompilationException("Ports for the intent are not available. Intent: " + intent);
-        }
-        List<Resource> intentResources = new ArrayList<>();
-        intentResources.add(srcPortResource);
-        intentResources.add(dstPortResource);
-
-        // Calculate available light paths
-        Set<Path> paths = getOpticalPaths(intent);
-
-        if (paths.isEmpty()) {
-            throw new IntentCompilationException("Unable to find suitable lightpath for intent " + intent);
-        }
-
-        // Use first path that can be successfully reserved
-        for (Path path : paths) {
-
-            // Find available Tributary Slots on both directions of path
-            Map<LinkKey, Set<TributarySlot>> slotsMap = findAvailableTributarySlots(intent, path);
-            if (slotsMap.isEmpty()) {
-                continue;
-            }
-            List<Resource> tributarySlotResources = convertToResources(slotsMap);
-            if (!tributarySlotResources.stream().allMatch(resourceService::isAvailable)) {
-                continue;
-            }
-
-            intentResources.addAll(tributarySlotResources);
-
-            allocateResources(intent, intentResources);
-
-            List<FlowRule> rules = new LinkedList<>();
-
-            // Create rules for forward and reverse path
-            rules = createRules(intent, intent.getSrc(), intent.getDst(), path, slotsMap, false);
-            if (intent.isBidirectional()) {
-                rules.addAll(createRules(intent, intent.getDst(), intent.getSrc(), path, slotsMap, true));
-            }
-
-            return Collections.singletonList(new FlowRuleIntent(appId,
-                    rules, ImmutableSet.copyOf(path.links())));
-        }
-
-        throw new IntentCompilationException("Unable to find suitable lightpath for intent " + intent);
-    }
-
-    /**
-     * Find available TributarySlots across path.
-     *
-     * @param intent
-     * @param path path in OTU topology
-     * @return Map of Linkey and Set of available TributarySlots on its ports
-     */
-    private Map<LinkKey, Set<TributarySlot>> findAvailableTributarySlots(OpticalOduIntent intent, Path path) {
-        Set<LinkKey> linkRequest = Sets.newHashSetWithExpectedSize(path.links().size());
-        for (int i = 0; i < path.links().size(); i++) {
-            LinkKey link = linkKey(path.links().get(i));
-            linkRequest.add(link);
-        }
-
-        return findTributarySlots(intent, linkRequest);
-    }
-
-    private List<Resource> convertToResources(Map<LinkKey, Set<TributarySlot>> slotsMap) {
-       // Same TributarySlots are used for both directions
-        Set<Resource> resources = slotsMap.entrySet().stream()
-                .flatMap(x -> x.getValue()
-                        .stream()
-                        .flatMap(ts-> Stream.of(
-                                Resources.discrete(x.getKey().src().deviceId(), x.getKey().src().port())
-                                        .resource().child(ts),
-                                Resources.discrete(x.getKey().dst().deviceId(), x.getKey().dst().port())
-                                        .resource().child(ts))))
-                .collect(Collectors.toSet());
-        return (ImmutableList.copyOf(resources));
-    }
-
-    private void allocateResources(Intent intent, List<Resource> resources) {
-        // reserve all of required resources
-        List<ResourceAllocation> allocations = resourceService.allocate(intent.id(), resources);
-        if (allocations.isEmpty()) {
-            log.info("Resource allocation for {} failed (resource request: {})", intent, resources);
-            throw new IntentCompilationException("Unable to allocate resources: " + resources);
-        }
-    }
-
-    private Map<LinkKey, Set<TributarySlot>> findTributarySlots(OpticalOduIntent intent, Set<LinkKey> links) {
-        OduSignalType oduSignalType = OduSignalUtils.mappingCltSignalTypeToOduSignalType(intent.getSignalType());
-        int requestedTsNum = oduSignalType.tributarySlots();
-
-        Map<LinkKey, Set<TributarySlot>> slotsMap = new HashMap<>();
-        for (LinkKey link : links) {
-            Set<TributarySlot> common = findCommonTributarySlotsOnCps(link.src(), link.dst());
-            if (common.isEmpty() || (common.size() < requestedTsNum)) {
-                log.debug("Failed to find TributarySlots on link {} requestedTsNum={}", link, requestedTsNum);
-                return Collections.emptyMap(); // failed to find enough available TributarySlots on a link
-            }
-            slotsMap.put(link, common.stream()
-                                .limit(requestedTsNum)
-                                .collect(Collectors.toSet()));
-        }
-        return slotsMap;
-    }
-
-    /**
-     * Calculates optical paths in OTU topology.
-     *
-     * @param intent optical ODU intent
-     * @return set of paths in OTU topology
-     */
-    private Set<Path> getOpticalPaths(OpticalOduIntent intent) {
-        // Route in OTU topology
-        Topology topology = topologyService.currentTopology();
-
-        LinkWeight weight = edge -> {
-            // Disregard inactive or non-optical links
-            if (edge.link().state() == Link.State.INACTIVE) {
-                return -1;
-            }
-            if (edge.link().type() != Link.Type.OPTICAL) {
-                return -1;
-            }
-            // Find path with available TributarySlots resources
-            if (!isAvailableTributarySlots(intent, edge.link())) {
-                return -1;
-            }
-            return 1;
-        };
-
-        ConnectPoint start = intent.getSrc();
-        ConnectPoint end = intent.getDst();
-
-        return topologyService.getPaths(topology, start.deviceId(), end.deviceId(), weight);
-    }
-
-    private boolean isAvailableTributarySlots(OpticalOduIntent intent, Link link) {
-        OduSignalType oduSignalType = OduSignalUtils.mappingCltSignalTypeToOduSignalType(intent.getSignalType());
-        int requestedTsNum = oduSignalType.tributarySlots();
-
-        Set<TributarySlot> common = findCommonTributarySlotsOnCps(link.src(), link.dst());
-        if (common.isEmpty() || (common.size() < requestedTsNum)) {
-            log.debug("Not enough available TributarySlots on link {} requestedTsNum={}", link, requestedTsNum);
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Create rules for the forward (or the reverse) path of the intent.
-     *
-     * @param intent OpticalOduIntent intent
-     * @param path path found for intent
-     * @param slotsMap Map of LinkKey and TributarySlots resources
-     * @return list of flow rules
-     */
-    private List<FlowRule> createRules(OpticalOduIntent intent, ConnectPoint src, ConnectPoint dst,
-            Path path, Map<LinkKey, Set<TributarySlot>> slotsMap, boolean reverse) {
-        // Build the ingress OTN rule
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
-        selector.matchInPort(src.port());
-        OduSignalType oduCltPortOduSignalType =
-                OduSignalUtils.mappingCltSignalTypeToOduSignalType(intent.getSignalType());
-        selector.add(Criteria.matchOduSignalType(oduCltPortOduSignalType));
-
-        List<FlowRule> rules = new LinkedList<>();
-        ConnectPoint current = src;
-
-        List<Link> links = ((!reverse) ? path.links() : Lists.reverse(path.links()));
-
-        for (Link link : links) {
-            Set<TributarySlot> slots = slotsMap.get(linkKey(link));
-            OtuPort otuPort = (OtuPort) (deviceService.getPort(link.src().deviceId(), link.src().port()));
-            OduSignalType otuPortOduSignalType =
-                    OduSignalUtils.mappingOtuSignalTypeToOduSignalType(otuPort.signalType());
-
-            TrafficTreatment.Builder treat = DefaultTrafficTreatment.builder();
-            OduSignalId oduSignalId = null;
-            // use Instruction of OduSignalId only in case of ODU Multiplexing
-            if (oduCltPortOduSignalType != otuPortOduSignalType) {
-                oduSignalId = OduSignalUtils.buildOduSignalId(otuPortOduSignalType, slots);
-                treat.add(Instructions.modL1OduSignalId(oduSignalId));
-            }
-            ConnectPoint next = ((!reverse) ? link.src() : link.dst());
-            treat.setOutput(next.port());
-
-            FlowRule rule = createFlowRule(intent, current.deviceId(), selector.build(), treat.build());
-            rules.add(rule);
-
-            current = ((!reverse) ? link.dst() : link.src());
-            selector = DefaultTrafficSelector.builder();
-            selector.matchInPort(current.port());
-            selector.add(Criteria.matchOduSignalType(oduCltPortOduSignalType));
-            // use Criteria of OduSignalId only in case of ODU Multiplexing
-            if (oduCltPortOduSignalType != otuPortOduSignalType) {
-                selector.add(Criteria.matchOduSignalId(oduSignalId));
-            }
-        }
-
-        // Build the egress OTN rule
-        TrafficTreatment.Builder treatLast = DefaultTrafficTreatment.builder();
-        treatLast.setOutput(dst.port());
-
-        FlowRule rule = createFlowRule(intent, dst.deviceId(), selector.build(), treatLast.build());
-        rules.add(rule);
-
-        return rules;
-    }
-
-    private FlowRule createFlowRule(OpticalOduIntent intent, DeviceId deviceId,
-            TrafficSelector selector, TrafficTreatment treat) {
-        return DefaultFlowRule.builder()
-                .forDevice(deviceId)
-                .withSelector(selector)
-                .withTreatment(treat)
-                .withPriority(intent.priority())
-                .fromApp(appId)
-                .makePermanent()
-                .build();
-    }
-
-    /**
-     * Finds the common TributarySlots available on the two connect points.
-     *
-     * @param src source connect point
-     * @param dst dest connect point
-     * @return set of common TributarySlots on both connect points
-     */
-    Set<TributarySlot> findCommonTributarySlotsOnCps(ConnectPoint src, ConnectPoint dst) {
-        Set<TributarySlot> forward = findTributarySlotsOnCp(src);
-        Set<TributarySlot> backward = findTributarySlotsOnCp(dst);
-        return Sets.intersection(forward, backward);
-    }
-
-    /**
-     * Finds the TributarySlots available on the connect point.
-     *
-     * @param cp connect point
-     * @return set of TributarySlots available on the connect point
-     */
-    Set<TributarySlot> findTributarySlotsOnCp(ConnectPoint cp) {
-        return resourceService.getAvailableResourceValues(
-                Resources.discrete(cp.deviceId(), cp.port()).id(),
-                TributarySlot.class);
-    }
-}
\ No newline at end of file
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompiler.java
deleted file mode 100644
index afb6e1e..0000000
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompiler.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.net.intent.impl.compiler;
-
-import com.google.common.collect.Lists;
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Link;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.intent.FlowRuleIntent;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentCompiler;
-import org.onosproject.net.intent.IntentExtensionService;
-import org.onosproject.net.intent.OpticalPathIntent;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
-@Component(immediate = true)
-public class OpticalPathIntentCompiler implements IntentCompiler<OpticalPathIntent> {
-
-    private static final Logger log = LoggerFactory.getLogger(OpticalPathIntentCompiler.class);
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected IntentExtensionService intentManager;
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected CoreService coreService;
-
-    private ApplicationId appId;
-
-    @Activate
-    public void activate() {
-        appId = coreService.registerApplication("org.onosproject.net.intent");
-        intentManager.registerCompiler(OpticalPathIntent.class, this);
-    }
-
-    @Deactivate
-    public void deactivate() {
-        intentManager.unregisterCompiler(OpticalPathIntent.class);
-    }
-
-    @Override
-    public List<Intent> compile(OpticalPathIntent intent, List<Intent> installable) {
-        log.debug("Compiling optical path intent between {} and {}", intent.src(), intent.dst());
-
-        // Create rules for forward and reverse path
-        List<FlowRule> rules = createRules(intent);
-        if (intent.isBidirectional()) {
-            rules.addAll(createReverseRules(intent));
-        }
-
-        return Collections.singletonList(new FlowRuleIntent(appId, rules, intent.resources()));
-    }
-
-    /**
-     * Create rules for the forward path of the intent.
-     *
-     * @param intent the intent
-     * @return list of flow rules
-     */
-    private List<FlowRule> createRules(OpticalPathIntent intent) {
-        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
-        selectorBuilder.matchInPort(intent.src().port());
-
-        List<FlowRule> rules = new LinkedList<>();
-        ConnectPoint current = intent.src();
-
-        for (Link link : intent.path().links()) {
-            TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-            treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
-            treatmentBuilder.setOutput(link.src().port());
-
-            FlowRule rule = DefaultFlowRule.builder()
-                    .forDevice(current.deviceId())
-                    .withSelector(selectorBuilder.build())
-                    .withTreatment(treatmentBuilder.build())
-                    .withPriority(intent.priority())
-                    .fromApp(appId)
-                    .makePermanent()
-                    .build();
-
-            rules.add(rule);
-
-            current = link.dst();
-            selectorBuilder.matchInPort(link.dst().port());
-            selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
-            selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
-        }
-
-        // Build the egress ROADM rule
-        TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
-        treatmentLast.setOutput(intent.dst().port());
-
-        FlowRule rule = new DefaultFlowRule.Builder()
-                .forDevice(intent.dst().deviceId())
-                .withSelector(selectorBuilder.build())
-                .withTreatment(treatmentLast.build())
-                .withPriority(intent.priority())
-                .fromApp(appId)
-                .makePermanent()
-                .build();
-        rules.add(rule);
-
-        return rules;
-    }
-
-    /**
-     * Create rules for the reverse path of the intent.
-     *
-     * @param intent the intent
-     * @return list of flow rules
-     */
-    private List<FlowRule> createReverseRules(OpticalPathIntent intent) {
-        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
-        selectorBuilder.matchInPort(intent.dst().port());
-
-        List<FlowRule> rules = new LinkedList<>();
-        ConnectPoint current = intent.dst();
-
-        for (Link link : Lists.reverse(intent.path().links())) {
-            TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
-            treatmentBuilder.add(Instructions.modL0Lambda(intent.lambda()));
-            treatmentBuilder.setOutput(link.dst().port());
-
-            FlowRule rule = DefaultFlowRule.builder()
-                    .forDevice(current.deviceId())
-                    .withSelector(selectorBuilder.build())
-                    .withTreatment(treatmentBuilder.build())
-                    .withPriority(intent.priority())
-                    .fromApp(appId)
-                    .makePermanent()
-                    .build();
-
-            rules.add(rule);
-
-            current = link.src();
-            selectorBuilder.matchInPort(link.src().port());
-            selectorBuilder.add(Criteria.matchLambda(intent.lambda()));
-            selectorBuilder.add(Criteria.matchOchSignalType(intent.signalType()));
-        }
-
-        // Build the egress ROADM rule
-        TrafficTreatment.Builder treatmentLast = DefaultTrafficTreatment.builder();
-        treatmentLast.setOutput(intent.src().port());
-
-        FlowRule rule = new DefaultFlowRule.Builder()
-                .forDevice(intent.src().deviceId())
-                .withSelector(selectorBuilder.build())
-                .withTreatment(treatmentLast.build())
-                .withPriority(intent.priority())
-                .fromApp(appId)
-                .makePermanent()
-                .build();
-        rules.add(rule);
-
-        return rules;
-    }
-}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathCompiler.java
index 69faaae..b831fef 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/PathCompiler.java
@@ -37,9 +37,9 @@
 import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.intent.IntentCompilationException;
 import org.onosproject.net.intent.PathIntent;
 import org.onosproject.net.intent.constraint.EncapsulationConstraint;
-import org.onosproject.net.intent.impl.IntentCompilationException;
 import org.onosproject.net.resource.Resource;
 import org.onosproject.net.resource.ResourceAllocation;
 import org.onosproject.net.resource.ResourceService;
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompiler.java
index 1fdebe1..8c04c6a 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/VirtualNetworkIntentCompiler.java
@@ -34,10 +34,10 @@
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompilationException;
 import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.intent.Key;
 import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.net.intent.impl.IntentCompilationException;
 import org.onosproject.net.topology.TopologyService;
 import org.slf4j.Logger;
 
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java
index b1e6376..585d3a0 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java
@@ -35,6 +35,7 @@
 import org.onosproject.net.NetworkResource;
 import org.onosproject.net.intent.FlowRuleIntent;
 import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompilationException;
 import org.onosproject.net.intent.IntentCompiler;
 import org.onosproject.net.intent.IntentData;
 import org.onosproject.net.intent.IntentEvent;
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompilerTest.java
index 4bba232..939cab0 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/HostToHostIntentCompilerTest.java
@@ -30,6 +30,7 @@
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentTestsMocks;
 import org.onosproject.net.intent.PathIntent;
+import org.onosproject.net.resource.MockResourceService;
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.VlanId;
 
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompilerTest.java
index 1317edc..fa0a0df 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/MplsPathIntentCompilerTest.java
@@ -43,6 +43,7 @@
 import org.onosproject.net.intent.IntentExtensionService;
 import org.onosproject.net.intent.MockIdGenerator;
 import org.onosproject.net.intent.MplsPathIntent;
+import org.onosproject.net.resource.MockResourceService;
 
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompilerTest.java
deleted file mode 100644
index 1ec1192..0000000
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalCircuitIntentCompilerTest.java
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.net.intent.impl.compiler;
-
-import org.easymock.EasyMock;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.onlab.packet.ChassisId;
-import org.onosproject.TestApplicationId;
-import org.onosproject.cfg.ComponentConfigService;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.core.IdGenerator;
-import org.onosproject.net.AbstractProjectableModel;
-import org.onosproject.net.Annotations;
-import org.onosproject.net.ChannelSpacing;
-import org.onosproject.net.DefaultAnnotations;
-import org.onosproject.net.CltSignalType;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultDevice;
-import org.onosproject.net.DefaultPort;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.OchSignal;
-import org.onosproject.net.OduSignalId;
-import org.onosproject.net.OduSignalType;
-import org.onosproject.net.OduSignalUtils;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.TributarySlot;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.intent.FlowRuleIntent;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentExtensionService;
-import org.onosproject.net.intent.IntentId;
-import org.onosproject.net.intent.IntentServiceAdapter;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MockIdGenerator;
-import org.onosproject.net.intent.OpticalCircuitIntent;
-import org.onosproject.net.optical.OchPort;
-import org.onosproject.net.optical.OduCltPort;
-import org.onosproject.net.optical.impl.DefaultOchPort;
-import org.onosproject.net.optical.impl.DefaultOduCltPort;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.net.intent.IntentSetMultimap;
-import org.onosproject.net.behaviour.TributarySlotQuery;
-import org.onosproject.net.device.DeviceServiceAdapter;
-import org.onosproject.net.driver.Behaviour;
-import org.onosproject.net.driver.DefaultDriver;
-import org.onosproject.net.driver.Driver;
-import org.onosproject.net.driver.DriverHandler;
-import org.onosproject.net.driver.DriverService;
-import org.onosproject.net.driver.DriverServiceAdapter;
-import org.onosproject.net.driver.TestBehaviourImpl;
-import org.onosproject.net.driver.TestBehaviourTwoImpl;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static org.easymock.EasyMock.anyObject;
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.expectLastCall;
-import static org.easymock.EasyMock.replay;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.onosproject.net.AnnotationKeys.STATIC_PORT;
-import static org.onosproject.net.AnnotationKeys.PORT_NAME;
-import static org.onosproject.net.Device.Type.ROADM;
-import static org.onosproject.net.DeviceId.deviceId;
-import static org.onosproject.net.NetTestTools.APP_ID;
-
-public class OpticalCircuitIntentCompilerTest {
-
-    private static final String DEV1 = "of:1";
-    private static final String DEV2 = "of:2";
-
-    static final Key KEY1 = Key.of(5L, APP_ID);
-
-    private static final String STATIC_TRUE = "true";
-    private static final String PNAME = "p2";
-
-    private CoreService coreService;
-    private IntentExtensionService intentExtensionService;
-    private final IdGenerator idGenerator = new MockIdGenerator();
-    private OpticalCircuitIntentCompiler sut;
-
-    private final ApplicationId appId = new TestApplicationId("test");
-    private static Device device1 = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), ROADM,
-            "m", "h", "s", "n", new ChassisId(0L));
-    private static Device device2 = new DefaultDevice(ProviderId.NONE, deviceId(DEV2), ROADM,
-            "m", "h", "s", "n", new ChassisId(1L));
-
-    private static Annotations annotations1 = DefaultAnnotations.builder().set(STATIC_PORT, STATIC_TRUE).build();
-    private static Annotations annotations2 = DefaultAnnotations.builder().set(PORT_NAME, PNAME).build();
-
-    // OduClt ports with signalType=1GBE
-    private static final OduCltPort D1P1 =
-            new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(1), true, annotations1),
-                                  CltSignalType.CLT_1GBE);
-    private static final OduCltPort D2P1 =
-            new DefaultOduCltPort(new DefaultPort(device2, PortNumber.portNumber(1), true, annotations1),
-                                  CltSignalType.CLT_1GBE);
-
-    // Och ports with signalType=ODU2
-    private static final OchPort D1P2 =
-            new DefaultOchPort(new DefaultPort(device1, PortNumber.portNumber(2), true, annotations2),
-                               OduSignalType.ODU2,
-                    true, OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 1));
-    private static final OchPort D2P2 =
-            new DefaultOchPort(new DefaultPort(device2, PortNumber.portNumber(2), true, annotations2),
-                               OduSignalType.ODU2,
-                    true, OchSignal.newDwdmSlot(ChannelSpacing.CHL_50GHZ, 1));
-
-    // OduClt ports with signalType=10GBE
-    private static final OduCltPort D1P3 =
-            new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(3), true, annotations1),
-                                  CltSignalType.CLT_10GBE);
-    private static final OduCltPort D2P3 =
-            new DefaultOduCltPort(new DefaultPort(device2, PortNumber.portNumber(3), true, annotations1),
-                                  CltSignalType.CLT_10GBE);
-
-
-    private OpticalCircuitIntent intent;
-
-    /**
-     * Mocks the device service so that devices and ports appear available in the test.
-     */
-    private static class MockDeviceService extends DeviceServiceAdapter {
-        @Override
-        public boolean isAvailable(DeviceId deviceId) {
-            return true;
-        }
-
-        @Override
-        public List<Port> getPorts(DeviceId deviceId) {
-            if (deviceId.equals(deviceId(DEV1))) {
-                return ImmutableList.of((Port) D1P1, (Port) D1P2, (Port) D1P3);
-            }
-
-            if (deviceId.equals(deviceId(DEV2))) {
-                return ImmutableList.of((Port) D2P1, (Port) D2P2, (Port) D2P3);
-            }
-            return Collections.emptyList();
-        }
-
-        @Override
-        public Port getPort(DeviceId deviceId, PortNumber portNumber) {
-            if (deviceId.equals(deviceId(DEV1))) {
-                switch (portNumber.toString()) {
-                    case "1":
-                        return D1P1;
-                    case "2":
-                        return D1P2;
-                    case "3":
-                        return D1P3;
-                    default:
-                        return null;
-                }
-            }
-            if (deviceId.equals(deviceId(DEV2))) {
-                switch (portNumber.toString()) {
-                    case "1":
-                        return D2P1;
-                    case "2":
-                        return D2P2;
-                    case "3":
-                        return D2P3;
-                    default:
-                        return null;
-                }
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Mocks the driver service so it will appear supporting TributarySlotQuery Behaviour in the test.
-     */
-    private static class MockDriverServiceWithTs implements DriverService {
-        @Override
-        public Driver getDriver(String driverName) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Set<Driver> getDrivers() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Set<Driver> getDrivers(Class<? extends Behaviour> withBehaviour) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Driver getDriver(String mfr, String hw, String sw) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Driver getDriver(DeviceId deviceId) {
-            DefaultDriver ddp = new DefaultDriver("foo.base", new ArrayList<>(), "Circus", "lux", "1.2a",
-                    ImmutableMap.of(Behaviour.class,
-                                    TestBehaviourImpl.class,
-                                    TributarySlotQuery.class,
-                                    TestBehaviourTwoImpl.class),
-                    ImmutableMap.of("foo", "bar"));
-            return ddp;
-        }
-
-        @Override
-        public DriverHandler createHandler(DeviceId deviceId,
-                String... credentials) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-    }
-
-    /**
-     * Mocks the driver service so it will appear not-supporting TributarySlotQuery Behaviour in the test.
-     */
-    private static class MockDriverServiceNoTs implements DriverService {
-        @Override
-        public Driver getDriver(String driverName) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Set<Driver> getDrivers() {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Set<Driver> getDrivers(Class<? extends Behaviour> withBehaviour) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Driver getDriver(String mfr, String hw, String sw) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public Driver getDriver(DeviceId deviceId) {
-            DefaultDriver ddp = new DefaultDriver("foo.base", new ArrayList<>(), "Circus", "lux", "1.2a",
-                    ImmutableMap.of(Behaviour.class,
-                                    TestBehaviourImpl.class),
-                    ImmutableMap.of("foo", "bar"));
-            return ddp;
-        }
-
-        @Override
-        public DriverHandler createHandler(DeviceId deviceId,
-                String... credentials) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-    }
-
-    private static class MockIntentSetMultimap implements IntentSetMultimap {
-        @Override
-        public boolean allocateMapping(IntentId keyIntentId,
-                IntentId valIntentId) {
-            // TODO Auto-generated method stub
-            return false;
-        }
-
-        @Override
-        public Set<IntentId> getMapping(IntentId intentId) {
-            // TODO Auto-generated method stub
-            return null;
-        }
-
-        @Override
-        public void releaseMapping(IntentId intentId) {
-            // TODO Auto-generated method stub
-        }
-
-    }
-
-    /**
-     * Represents a fake IntentService class that easily allows to store and
-     * retrieve intents without implementing the IntentService logic.
-     */
-    private class TestIntentService extends IntentServiceAdapter {
-
-        private Set<Intent> intents;
-
-        public TestIntentService() {
-            intents = Sets.newHashSet();
-        }
-
-        @Override
-        public void submit(Intent intent) {
-            intents.add(intent);
-        }
-
-        @Override
-        public long getIntentCount() {
-            return intents.size();
-        }
-
-        @Override
-        public Iterable<Intent> getIntents() {
-            return intents;
-        }
-
-        @Override
-        public Intent getIntent(Key intentKey) {
-            for (Intent intent : intents) {
-                if (intent.key().equals(intentKey)) {
-                    return intent;
-                }
-            }
-            return null;
-        }
-    }
-
-    @BeforeClass
-    public static void setUpClass() {
-        AbstractProjectableModel.setDriverService("key", new DriverServiceAdapter());
-    }
-
-    @Before
-    public void setUp() {
-        sut = new OpticalCircuitIntentCompiler();
-        coreService = createMock(CoreService.class);
-        expect(coreService.registerApplication("org.onosproject.net.intent"))
-                .andReturn(appId);
-        sut.coreService = coreService;
-        sut.deviceService = new MockDeviceService();
-        sut.resourceService = new MockResourceService();
-        sut.intentService = new TestIntentService();
-        sut.intentSetMultimap = new MockIntentSetMultimap();
-
-        Intent.bindIdGenerator(idGenerator);
-
-        intentExtensionService = createMock(IntentExtensionService.class);
-        intentExtensionService.registerCompiler(OpticalCircuitIntent.class, sut);
-        intentExtensionService.unregisterCompiler(OpticalCircuitIntent.class);
-        sut.intentManager = intentExtensionService;
-        replay(coreService, intentExtensionService);
-
-        // mocking ComponentConfigService
-        ComponentConfigService mockConfigService =
-                EasyMock.createMock(ComponentConfigService.class);
-        expect(mockConfigService.getProperties(anyObject())).andReturn(ImmutableSet.of());
-        mockConfigService.registerProperties(sut.getClass());
-        expectLastCall();
-        mockConfigService.unregisterProperties(sut.getClass(), false);
-        expectLastCall();
-        expect(mockConfigService.getProperties(anyObject())).andReturn(ImmutableSet.of());
-        sut.cfgService = mockConfigService;
-        replay(mockConfigService);
-
-    }
-
-    @After
-    public void tearDown() {
-        Intent.unbindIdGenerator(idGenerator);
-    }
-
-    /**
-     * Tests compile of OpticalCircuitIntent with allocation of TributarySlots.
-     * Compile two ODUCLT ports (with CLT_1GBE), over OCH ports (with ODU2):
-     *   - only one TributarySlot is used
-     */
-    @Test
-    public void test1GbeMultiplexOverOdu2() {
-
-        // Use driver with TributarySlotQuery Behaviour
-        sut.driverService = new MockDriverServiceWithTs();
-
-        ConnectPoint oduCltSrcCP = new ConnectPoint(device1.id(), D1P1.number());
-        ConnectPoint oduCltDstCP = new ConnectPoint(device2.id(), D2P1.number());
-        ConnectPoint ochSrcCP = new ConnectPoint(device1.id(), D1P2.number());
-        ConnectPoint ochDstCP = new ConnectPoint(device2.id(), D2P2.number());
-
-        intent = OpticalCircuitIntent.builder()
-                .appId(APP_ID)
-                .key(KEY1)
-                .src(oduCltSrcCP)
-                .dst(oduCltDstCP)
-                .signalType(D1P1.signalType())
-                .bidirectional(false)
-                .build();
-
-        sut.activate(null);
-
-        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
-        assertThat(compiled, hasSize(1));
-
-        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
-
-        FlowRule rule1 = rules.stream()
-                .filter(x -> x.deviceId().equals(device1.id()))
-                .findFirst()
-                .get();
-        // validate SRC selector
-        TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
-        selectorBuilder1.matchInPort(oduCltSrcCP.port());
-        selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
-        assertThat(rule1.selector(), is(selectorBuilder1.build()));
-
-        // validate SRC treatment  (with OduSignalId, where 1 TributarySlot is used)
-        TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
-        Set<TributarySlot> slots = new HashSet<>();
-        slots.add(TributarySlot.of(1));
-        OduSignalId oduSignalId = OduSignalUtils.buildOduSignalId(D1P2.signalType(), slots);
-        treatmentBuilder1.add(Instructions.modL1OduSignalId(oduSignalId));
-        treatmentBuilder1.setOutput(ochSrcCP.port());
-        assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
-
-        FlowRule rule2 = rules.stream()
-                .filter(x -> x.deviceId().equals(device2.id()))
-                .findFirst()
-                .get();
-        // validate DST selector (with OduSignalId, where the same TributarySlot is used)
-        TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
-        selectorBuilder2.matchInPort(ochDstCP.port());
-        selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
-        selectorBuilder2.add(Criteria.matchOduSignalId(oduSignalId));
-        assertThat(rule2.selector(), is(selectorBuilder2.build()));
-
-        // validate DST treatment
-        assertThat(rule2.treatment(), is(
-                DefaultTrafficTreatment.builder().setOutput(oduCltDstCP.port()).build()
-                ));
-
-        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
-                intent.priority(), rule.priority()));
-
-        sut.deactivate();
-    }
-
-    /**
-     * Tests compile of OpticalCircuitIntent with allocation of TributarySlots.
-     * Compile two ODUCLT ports (with CLT_10GBE), over OCH ports (with ODU2):
-     *   - All TributarySlots are used
-     */
-    @Test
-    public void test10GbeMultiplexOverOdu2() {
-
-        // Use driver with TributarySlotQuery Behaviour
-        sut.driverService = new MockDriverServiceWithTs();
-
-        ConnectPoint oduCltSrcCP = new ConnectPoint(device1.id(), D1P3.number());
-        ConnectPoint oduCltDstCP = new ConnectPoint(device2.id(), D2P3.number());
-        ConnectPoint ochSrcCP = new ConnectPoint(device1.id(), D1P2.number());
-        ConnectPoint ochDstCP = new ConnectPoint(device2.id(), D2P2.number());
-
-        intent = OpticalCircuitIntent.builder()
-                .appId(APP_ID)
-                .key(KEY1)
-                .src(oduCltSrcCP)
-                .dst(oduCltDstCP)
-                .signalType(D1P3.signalType())
-                .bidirectional(false)
-                .build();
-
-        sut.activate(null);
-
-        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
-        assertThat(compiled, hasSize(1));
-
-        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
-
-        FlowRule rule1 = rules.stream()
-                .filter(x -> x.deviceId().equals(device1.id()))
-                .findFirst()
-                .get();
-        // validate SRC selector
-        TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
-        selectorBuilder1.matchInPort(oduCltSrcCP.port());
-        selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
-        assertThat(rule1.selector(), is(selectorBuilder1.build()));
-
-        // validate SRC treatment (without OduSignalId, i.e. All TributarySlots are used)
-        TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
-        treatmentBuilder1.setOutput(ochSrcCP.port());
-        assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
-
-        FlowRule rule2 = rules.stream()
-                .filter(x -> x.deviceId().equals(device2.id()))
-                .findFirst()
-                .get();
-        // validate DST selector (without OduSignalId, i.e. All TributarySlots are used)
-        TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
-        selectorBuilder2.matchInPort(ochDstCP.port());
-        selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
-        assertThat(rule2.selector(), is(selectorBuilder2.build()));
-
-        // validate DST treatment
-        assertThat(rule2.treatment(), is(
-                DefaultTrafficTreatment.builder().setOutput(oduCltDstCP.port()).build()
-                ));
-
-        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
-                intent.priority(), rule.priority()));
-
-        sut.deactivate();
-    }
-
-    /**
-     * Tests compile of OpticalCircuitIntent without allocation of TributarySlots.
-     * Compile two ODUCLT ports (with CLT_10GBE), over OCH ports (with ODU2):
-     *   - No TributarySlots are used
-     */
-    @Test
-    public void test10GbeNoMuxOverOdu2() {
-
-        // Use driver without support for TributarySlotQuery Behaviour
-        sut.driverService = new MockDriverServiceNoTs();
-
-        ConnectPoint oduCltSrcCP = new ConnectPoint(device1.id(), D1P3.number());
-        ConnectPoint oduCltDstCP = new ConnectPoint(device2.id(), D2P3.number());
-        ConnectPoint ochSrcCP = new ConnectPoint(device1.id(), D1P2.number());
-        ConnectPoint ochDstCP = new ConnectPoint(device2.id(), D2P2.number());
-
-        intent = OpticalCircuitIntent.builder()
-                .appId(APP_ID)
-                .key(KEY1)
-                .src(oduCltSrcCP)
-                .dst(oduCltDstCP)
-                .signalType(D1P3.signalType())
-                .bidirectional(false)
-                .build();
-
-        sut.activate(null);
-
-        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
-        assertThat(compiled, hasSize(1));
-
-        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
-
-        FlowRule rule1 = rules.stream()
-                .filter(x -> x.deviceId().equals(device1.id()))
-                .findFirst()
-                .get();
-        // validate SRC selector
-        TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
-        selectorBuilder1.matchInPort(oduCltSrcCP.port());
-        assertThat(rule1.selector(), is(selectorBuilder1.build()));
-
-        // validate SRC treatment (without OduSignalType and OduSignalId: i.e. No TributarySlots are used)
-        TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
-        treatmentBuilder1.setOutput(ochSrcCP.port());
-        assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
-
-        FlowRule rule2 = rules.stream()
-                .filter(x -> x.deviceId().equals(device2.id()))
-                .findFirst()
-                .get();
-        // validate DST selector (without OduSignalType and OduSignalId: i.e. No TributarySlots are used)
-        TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
-        selectorBuilder2.matchInPort(ochDstCP.port());
-        assertThat(rule2.selector(), is(selectorBuilder2.build()));
-        // validate DST treatment
-        assertThat(rule2.treatment(), is(
-                DefaultTrafficTreatment.builder().setOutput(oduCltDstCP.port()).build()
-                ));
-
-        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
-                intent.priority(), rule.priority()));
-
-        sut.deactivate();
-    }
-
-}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalOduIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalOduIntentCompilerTest.java
deleted file mode 100644
index a6ba3fe..0000000
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalOduIntentCompilerTest.java
+++ /dev/null
@@ -1,454 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.net.intent.impl.compiler;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.onlab.packet.ChassisId;
-import org.onosproject.TestApplicationId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.core.IdGenerator;
-import org.onosproject.net.AbstractProjectableModel;
-import org.onosproject.net.Annotations;
-import org.onosproject.net.DefaultAnnotations;
-import org.onosproject.net.CltSignalType;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultDevice;
-import org.onosproject.net.DefaultLink;
-import org.onosproject.net.DefaultPath;
-import org.onosproject.net.DefaultPort;
-import org.onosproject.net.Device;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.Link;
-import org.onosproject.net.OduSignalId;
-import org.onosproject.net.OduSignalType;
-import org.onosproject.net.OduSignalUtils;
-import org.onosproject.net.OtuSignalType;
-import org.onosproject.net.Path;
-import org.onosproject.net.Port;
-import org.onosproject.net.PortNumber;
-import org.onosproject.net.TributarySlot;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.flow.criteria.Criteria;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.net.intent.FlowRuleIntent;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentExtensionService;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.MockIdGenerator;
-import org.onosproject.net.intent.OpticalOduIntent;
-import org.onosproject.net.optical.OduCltPort;
-import org.onosproject.net.optical.OtuPort;
-import org.onosproject.net.optical.impl.DefaultOduCltPort;
-import org.onosproject.net.optical.impl.DefaultOtuPort;
-import org.onosproject.net.provider.ProviderId;
-import org.onosproject.net.topology.LinkWeight;
-import org.onosproject.net.topology.Topology;
-import org.onosproject.net.topology.TopologyServiceAdapter;
-import org.onosproject.net.device.DeviceServiceAdapter;
-import org.onosproject.net.driver.DriverService;
-import org.onosproject.net.driver.DriverServiceAdapter;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Sets;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasSize;
-import static org.hamcrest.Matchers.is;
-import static org.junit.Assert.assertEquals;
-import static org.onosproject.net.AnnotationKeys.STATIC_PORT;
-import static org.onosproject.net.AnnotationKeys.PORT_NAME;
-import static org.onosproject.net.Device.Type.OTN;
-import static org.onosproject.net.DeviceId.deviceId;
-import static org.onosproject.net.Link.Type.OPTICAL;
-import static org.onosproject.net.NetTestTools.APP_ID;
-import static org.onosproject.net.NetTestTools.PID;
-
-public class OpticalOduIntentCompilerTest {
-
-    private static final String DEV1 = "of:1";
-    private static final String DEV2 = "of:2";
-    private static final String DEV3 = "of:3";
-
-    static final Key KEY1 = Key.of(5L, APP_ID);
-
-    private static final String STATIC_TRUE = "true";
-    private static final String PNAME = "p2";
-
-    private CoreService coreService;
-    private IntentExtensionService intentExtensionService;
-    private final IdGenerator idGenerator = new MockIdGenerator();
-    private OpticalOduIntentCompiler sut;
-
-    private final ApplicationId appId = new TestApplicationId("test");
-    private static Device device1 = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), OTN,
-            "m", "h", "s", "n", new ChassisId(0L));
-    private static Device device2 = new DefaultDevice(ProviderId.NONE, deviceId(DEV2), OTN,
-            "m", "h", "s", "n", new ChassisId(1L));
-    private static Device device3 = new DefaultDevice(ProviderId.NONE, deviceId(DEV3), OTN,
-            "m", "h", "s", "n", new ChassisId(2L));
-
-    private static Annotations annotations1 = DefaultAnnotations.builder().set(STATIC_PORT, STATIC_TRUE).build();
-    private static Annotations annotations2 = DefaultAnnotations.builder().set(PORT_NAME, PNAME).build();
-
-    // OduClt ports with signalType=1GBE
-    private static final OduCltPort D1P1 =
-            new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(1), true, annotations1),
-                                  CltSignalType.CLT_1GBE);
-    private static final OduCltPort D3P2 =
-            new DefaultOduCltPort(new DefaultPort(device3, PortNumber.portNumber(2), true, annotations1),
-                                  CltSignalType.CLT_1GBE);
-
-    // Otu ports with signalType=ODU2
-    private static final OtuPort D1P2 =
-            new DefaultOtuPort(new DefaultPort(device1, PortNumber.portNumber(2), true, annotations2),
-                               OtuSignalType.OTU2);
-    private static final OtuPort D2P1 =
-            new DefaultOtuPort(new DefaultPort(device2, PortNumber.portNumber(1), true, annotations2),
-                               OtuSignalType.OTU2);
-    private static final OtuPort D2P2 =
-            new DefaultOtuPort(new DefaultPort(device2, PortNumber.portNumber(2), true, annotations2),
-                               OtuSignalType.OTU2);
-    private static final OtuPort D3P1 =
-            new DefaultOtuPort(new DefaultPort(device3, PortNumber.portNumber(1), true, annotations2),
-                               OtuSignalType.OTU2);
-
-    // OduClt ports with signalType=10GBE
-    private static final OduCltPort D1P3 =
-            new DefaultOduCltPort(new DefaultPort(device1, PortNumber.portNumber(3), true, annotations1),
-                                  CltSignalType.CLT_10GBE);
-    private static final OduCltPort D3P3 =
-            new DefaultOduCltPort(new DefaultPort(device3, PortNumber.portNumber(3), true, annotations1),
-                                  CltSignalType.CLT_10GBE);
-
-    // OduCltPort ConnectPoints
-    private final ConnectPoint d1p1 = new ConnectPoint(device1.id(), D1P1.number());
-    private final ConnectPoint d1p3 = new ConnectPoint(device1.id(), D1P3.number());
-    private final ConnectPoint d3p2 = new ConnectPoint(device3.id(), D3P2.number());
-    private final ConnectPoint d3p3 = new ConnectPoint(device3.id(), D3P3.number());
-
-    // OtuPort ConnectPoints
-    private final ConnectPoint d1p2 = new ConnectPoint(device1.id(), D1P2.number());
-    private final ConnectPoint d2p1 = new ConnectPoint(device2.id(), D2P1.number());
-    private final ConnectPoint d2p2 = new ConnectPoint(device2.id(), D2P2.number());
-    private final ConnectPoint d3p1 = new ConnectPoint(device3.id(), D3P1.number());
-
-    private final List<Link> links = Arrays.asList(
-            DefaultLink.builder().providerId(PID).src(d1p2).dst(d2p1).type(OPTICAL).build(),
-            DefaultLink.builder().providerId(PID).src(d2p2).dst(d3p1).type(OPTICAL).build()
-    );
-    private final Path path = new DefaultPath(PID, links, 3);
-
-    private OpticalOduIntent intent;
-
-    /**
-     * Mocks the topology service to give paths in the test.
-     */
-    private class MockTopologyService extends TopologyServiceAdapter {
-        Set<Path> paths = Sets.newHashSet(path);
-
-        @Override
-        public Topology currentTopology() {
-            return null;
-        }
-
-        @Override
-        public Set<Path> getPaths(Topology topology, DeviceId src, DeviceId dst, LinkWeight weight) {
-            return paths;
-        }
-    }
-
-    /**
-     * Mocks the device service so that devices and ports appear available in the test.
-     */
-    private static class MockDeviceService extends DeviceServiceAdapter {
-        @Override
-        public boolean isAvailable(DeviceId deviceId) {
-            return true;
-        }
-
-        @Override
-        public List<Port> getPorts(DeviceId deviceId) {
-            if (deviceId.equals(deviceId(DEV1))) {
-                return ImmutableList.of((Port) D1P1, (Port) D1P2, (Port) D1P3);
-            }
-
-            if (deviceId.equals(deviceId(DEV2))) {
-                return ImmutableList.of((Port) D2P1, (Port) D2P2);
-            }
-
-            if (deviceId.equals(deviceId(DEV3))) {
-                return ImmutableList.of((Port) D3P1, (Port) D3P2, (Port) D3P3);
-            }
-
-            return Collections.emptyList();
-        }
-
-        @Override
-        public Port getPort(DeviceId deviceId, PortNumber portNumber) {
-            if (deviceId.equals(deviceId(DEV1))) {
-                switch (portNumber.toString()) {
-                    case "1":
-                        return D1P1;
-                    case "2":
-                        return D1P2;
-                    case "3":
-                        return D1P3;
-                    default:
-                        return null;
-                }
-            }
-            if (deviceId.equals(deviceId(DEV2))) {
-                switch (portNumber.toString()) {
-                    case "1":
-                        return D2P1;
-                    case "2":
-                        return D2P2;
-                    default:
-                        return null;
-                }
-            }
-            if (deviceId.equals(deviceId(DEV3))) {
-                switch (portNumber.toString()) {
-                    case "1":
-                        return D3P1;
-                    case "2":
-                        return D3P2;
-                    case "3":
-                        return D3P3;
-                    default:
-                        return null;
-                }
-            }
-            return null;
-        }
-    }
-
-    private static class MockDriverService extends DriverServiceAdapter
-            implements DriverService {
-        // TODO override to return appropriate driver,
-        // with DefaultOpticalDevice support, etc.
-    }
-
-    @Before
-    public void setUp() {
-        AbstractProjectableModel.setDriverService(null, new MockDriverService());
-        sut =  new OpticalOduIntentCompiler();
-        coreService = createMock(CoreService.class);
-        expect(coreService.registerApplication("org.onosproject.net.intent"))
-                .andReturn(appId);
-        sut.coreService = coreService;
-        sut.deviceService = new MockDeviceService();
-        sut.resourceService = new MockResourceService();
-        sut.topologyService = new MockTopologyService();
-
-        Intent.bindIdGenerator(idGenerator);
-
-        intentExtensionService = createMock(IntentExtensionService.class);
-        intentExtensionService.registerCompiler(OpticalOduIntent.class, sut);
-        intentExtensionService.unregisterCompiler(OpticalOduIntent.class);
-        sut.intentManager = intentExtensionService;
-
-        replay(coreService, intentExtensionService);
-    }
-
-    @After
-    public void tearDown() {
-        Intent.unbindIdGenerator(idGenerator);
-    }
-
-    /**
-     * Tests compile of OpticalOduIntent with allocation of TributarySlots.
-     * Compile two ODUCLT ports (with CLT_1GBE), over OTU ports (with OTU2):
-     *   - only one TributarySlot is used
-     */
-    @Test
-    public void test1GbeMultiplexOverOdu2() {
-
-        intent = OpticalOduIntent.builder()
-                .appId(APP_ID)
-                .key(KEY1)
-                .src(d1p1)
-                .dst(d3p2)
-                .signalType(D1P1.signalType())
-                .bidirectional(false)
-                .build();
-
-        sut.activate();
-
-        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
-        assertThat(compiled, hasSize(1));
-
-        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
-
-        // 1st Device
-        FlowRule rule1 = rules.stream()
-                .filter(x -> x.deviceId().equals(device1.id()))
-                .findFirst()
-                .get();
-        // validate SRC selector
-        TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
-        selectorBuilder1.matchInPort(d1p1.port());
-        selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
-        assertThat(rule1.selector(), is(selectorBuilder1.build()));
-
-        // validate SRC treatment  (with OduSignalId, where 1 TributarySlot is used)
-        TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
-        Set<TributarySlot> slots = new HashSet<>();
-        slots.add(TributarySlot.of(1));
-        OduSignalId oduSignalId = OduSignalUtils.buildOduSignalId(OduSignalType.ODU2, slots);
-        treatmentBuilder1.add(Instructions.modL1OduSignalId(oduSignalId));
-        treatmentBuilder1.setOutput(d1p2.port());
-        assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
-
-        // 2nd Device
-        FlowRule rule2 = rules.stream()
-                .filter(x -> x.deviceId().equals(device2.id()))
-                .findFirst()
-                .get();
-        // validate SRC selector
-        TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
-        selectorBuilder2.matchInPort(d2p1.port());
-        selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
-        selectorBuilder2.add(Criteria.matchOduSignalId(oduSignalId));
-        assertThat(rule2.selector(), is(selectorBuilder2.build()));
-
-        // validate SRC treatment  (with OduSignalId, where 1 TributarySlot is used)
-        TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
-        treatmentBuilder2.add(Instructions.modL1OduSignalId(oduSignalId));
-        treatmentBuilder2.setOutput(d2p2.port());
-        assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
-
-
-        // 3rd Device
-        FlowRule rule3 = rules.stream()
-                .filter(x -> x.deviceId().equals(device3.id()))
-                .findFirst()
-                .get();
-        // validate DST selector (with OduSignalId, where the same TributarySlot is used)
-        TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
-        selectorBuilder3.matchInPort(d3p1.port());
-        selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU0));
-        selectorBuilder3.add(Criteria.matchOduSignalId(oduSignalId));
-        assertThat(rule3.selector(), is(selectorBuilder3.build()));
-
-        // validate DST treatment
-        assertThat(rule3.treatment(), is(
-                DefaultTrafficTreatment.builder().setOutput(d3p2.port()).build()
-                ));
-
-        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
-                intent.priority(), rule.priority()));
-
-        sut.deactivate();
-    }
-
-    /**
-     * Tests compile of OpticalOduIntent with allocation of TributarySlots.
-     * Compile two ODUCLT ports (with CLT_10GBE), over OTU ports (with OTU2):
-     *   - All TributarySlots are used
-     */
-    @Test
-    public void test10GbeMultiplexOverOdu2() {
-
-        intent = OpticalOduIntent.builder()
-                .appId(APP_ID)
-                .key(KEY1)
-                .src(d1p3)
-                .dst(d3p3)
-                .signalType(D1P3.signalType())
-                .bidirectional(false)
-                .build();
-
-        sut.activate();
-
-        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
-        assertThat(compiled, hasSize(1));
-
-        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
-
-        // 1st Device
-        FlowRule rule1 = rules.stream()
-                .filter(x -> x.deviceId().equals(device1.id()))
-                .findFirst()
-                .get();
-        // validate SRC selector
-        TrafficSelector.Builder selectorBuilder1 = DefaultTrafficSelector.builder();
-        selectorBuilder1.matchInPort(d1p3.port());
-        selectorBuilder1.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
-        assertThat(rule1.selector(), is(selectorBuilder1.build()));
-
-        // validate SRC treatment  (without OduSignalId - all TributarySlots are used)
-        TrafficTreatment.Builder treatmentBuilder1 = DefaultTrafficTreatment.builder();
-        treatmentBuilder1.setOutput(d1p2.port());
-        assertThat(rule1.treatment(), is(treatmentBuilder1.build()));
-
-        // 2nd Device
-        FlowRule rule2 = rules.stream()
-                .filter(x -> x.deviceId().equals(device2.id()))
-                .findFirst()
-                .get();
-        // validate SRC selector
-        TrafficSelector.Builder selectorBuilder2 = DefaultTrafficSelector.builder();
-        selectorBuilder2.matchInPort(d2p1.port());
-        selectorBuilder2.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
-        assertThat(rule2.selector(), is(selectorBuilder2.build()));
-
-        // validate SRC treatment  (without OduSignalId - all TributarySlots are used)
-        TrafficTreatment.Builder treatmentBuilder2 = DefaultTrafficTreatment.builder();
-        treatmentBuilder2.setOutput(d2p2.port());
-        assertThat(rule2.treatment(), is(treatmentBuilder2.build()));
-
-
-        // 3rd Device
-        FlowRule rule3 = rules.stream()
-                .filter(x -> x.deviceId().equals(device3.id()))
-                .findFirst()
-                .get();
-        // validate DST selector (without OduSignalId - all TributarySlots are used)
-        TrafficSelector.Builder selectorBuilder3 = DefaultTrafficSelector.builder();
-        selectorBuilder3.matchInPort(d3p1.port());
-        selectorBuilder3.add(Criteria.matchOduSignalType(OduSignalType.ODU2));
-        assertThat(rule3.selector(), is(selectorBuilder3.build()));
-
-        // validate DST treatment
-        assertThat(rule3.treatment(), is(
-                DefaultTrafficTreatment.builder().setOutput(d3p3.port()).build()
-                ));
-
-        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
-                intent.priority(), rule.priority()));
-
-        sut.deactivate();
-    }
-
-}
\ No newline at end of file
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompilerTest.java
deleted file mode 100644
index d2a388f..0000000
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/OpticalPathIntentCompilerTest.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright 2015-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.net.intent.impl.compiler;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.onosproject.TestApplicationId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.core.IdGenerator;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.DefaultLink;
-import org.onosproject.net.DefaultPath;
-import org.onosproject.net.Link;
-import org.onosproject.net.OchSignalType;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.intent.FlowRuleIntent;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentExtensionService;
-import org.onosproject.net.intent.MockIdGenerator;
-import org.onosproject.net.intent.OpticalPathIntent;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import static org.easymock.EasyMock.createMock;
-import static org.easymock.EasyMock.expect;
-import static org.easymock.EasyMock.replay;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.hasSize;
-import static org.junit.Assert.assertEquals;
-import static org.onosproject.net.Link.Type.DIRECT;
-import static org.onosproject.net.NetTestTools.PID;
-import static org.onosproject.net.NetTestTools.connectPoint;
-import static org.onosproject.net.NetTestTools.createLambda;
-
-public class OpticalPathIntentCompilerTest {
-
-    private CoreService coreService;
-    private IntentExtensionService intentExtensionService;
-    private final IdGenerator idGenerator = new MockIdGenerator();
-    private OpticalPathIntentCompiler sut;
-
-    private final ApplicationId appId = new TestApplicationId("test");
-    private final ConnectPoint d1p1 = connectPoint("s1", 0);
-    private final ConnectPoint d2p0 = connectPoint("s2", 0);
-    private final ConnectPoint d2p1 = connectPoint("s2", 1);
-    private final ConnectPoint d3p1 = connectPoint("s3", 1);
-
-    private final List<Link> links = Arrays.asList(
-            DefaultLink.builder().providerId(PID).src(d1p1).dst(d2p0).type(DIRECT).build(),
-            DefaultLink.builder().providerId(PID).src(d2p1).dst(d3p1).type(DIRECT).build()
-    );
-    private final int hops = links.size() + 1;
-    private OpticalPathIntent intent;
-
-    @Before
-    public void setUp() {
-        sut = new OpticalPathIntentCompiler();
-        coreService = createMock(CoreService.class);
-        expect(coreService.registerApplication("org.onosproject.net.intent"))
-                .andReturn(appId);
-        sut.coreService = coreService;
-
-        Intent.bindIdGenerator(idGenerator);
-
-        intent = OpticalPathIntent.builder()
-                .appId(appId)
-                .src(d1p1)
-                .dst(d3p1)
-                .path(new DefaultPath(PID, links, hops))
-                .lambda(createLambda())
-                .signalType(OchSignalType.FIXED_GRID)
-                .build();
-        intentExtensionService = createMock(IntentExtensionService.class);
-        intentExtensionService.registerCompiler(OpticalPathIntent.class, sut);
-        intentExtensionService.unregisterCompiler(OpticalPathIntent.class);
-        sut.intentManager = intentExtensionService;
-
-        replay(coreService, intentExtensionService);
-    }
-
-    @After
-    public void tearDown() {
-        Intent.unbindIdGenerator(idGenerator);
-    }
-
-    @Test
-    public void testCompiler() {
-        sut.activate();
-
-        List<Intent> compiled = sut.compile(intent, Collections.emptyList());
-        assertThat(compiled, hasSize(1));
-
-        Collection<FlowRule> rules = ((FlowRuleIntent) compiled.get(0)).flowRules();
-        rules.stream()
-                .filter(x -> x.deviceId().equals(d1p1.deviceId()))
-                .findFirst()
-                .get();
-
-        rules.stream()
-                .filter(x -> x.deviceId().equals(d2p1.deviceId()))
-                .findFirst()
-                .get();
-
-        rules.stream()
-                .filter(x -> x.deviceId().equals(d3p1.deviceId()))
-                .findFirst()
-                .get();
-
-        rules.forEach(rule -> assertEquals("FlowRule priority is incorrect",
-                                           intent.priority(), rule.priority()));
-
-        sut.deactivate();
-    }
-
-    //TODO test bidirectional optical paths and verify rules
-
-}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PathIntentCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PathIntentCompilerTest.java
index c880823..b3efb24 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PathIntentCompilerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/PathIntentCompilerTest.java
@@ -47,6 +47,7 @@
 import org.onosproject.net.intent.PathIntent;
 import org.onosproject.net.intent.constraint.EncapsulationConstraint;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.resource.MockResourceService;
 
 import java.util.Arrays;
 import java.util.Collection;
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/phase/CompilingTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/phase/CompilingTest.java
index e188ccd..2a55931 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/phase/CompilingTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/phase/CompilingTest.java
@@ -31,11 +31,11 @@
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompilationException;
 import org.onosproject.net.intent.IntentData;
 import org.onosproject.net.intent.MockIdGenerator;
 import org.onosproject.net.intent.PathIntent;
 import org.onosproject.net.intent.PointToPointIntent;
-import org.onosproject.net.intent.impl.IntentCompilationException;
 import org.onosproject.net.intent.impl.IntentProcessor;
 import org.onosproject.net.provider.ProviderId;
 import org.onosproject.store.Timestamp;
