diff --git a/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java b/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
index 5593233..2609cf4 100644
--- a/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
+++ b/apps/optical-model/src/main/java/org/onosproject/net/optical/intent/impl/compiler/OpticalConnectivityIntentCompiler.java
@@ -24,7 +24,6 @@
 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;
@@ -42,8 +41,8 @@
 import org.onosproject.net.intent.OpticalConnectivityIntent;
 import org.onosproject.net.intent.OpticalPathIntent;
 import org.onosproject.net.optical.OchPort;
-import org.onosproject.net.resource.ResourceAllocation;
 import org.onosproject.net.resource.Resource;
+import org.onosproject.net.resource.ResourceAllocation;
 import org.onosproject.net.resource.ResourceService;
 import org.onosproject.net.resource.Resources;
 import org.onosproject.net.topology.AdapterLinkWeigher;
@@ -66,7 +65,6 @@
 import java.util.stream.Stream;
 
 import static com.google.common.base.Preconditions.checkArgument;
-import static org.onosproject.net.OchSignal.toFlexGrid;
 import static org.onosproject.net.optical.device.OpticalDeviceServiceView.opticalView;
 
 /**
@@ -108,10 +106,9 @@
         // 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);
+        checkArgument(deviceService.getPort(src.deviceId(), src.port()) instanceof OchPort);
+        checkArgument(deviceService.getPort(dst.deviceId(), dst.port()) instanceof OchPort);
+        List<Resource> resources = new LinkedList<>();
 
         log.debug("Compiling optical connectivity intent between {} and {}", src, dst);
 
@@ -121,101 +118,30 @@
         resourceService.release(intent.key());
 
         // Check OCh port availability
+        // If ports are not available, compilation fails
+        // Else add port to resource reservation list
         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)) {
             log.error("Ports for the intent are not available. Intent: {}", intent);
             throw new OpticalIntentCompilationException("Ports for the intent are not available. Intent: " + intent);
         }
-
-        List<Resource> resources = new ArrayList<>();
         resources.add(srcPortResource);
         resources.add(dstPortResource);
 
-        // Calculate available light paths
+        // Find first path that has the required resources
         Stream<Path> paths = getOpticalPaths(intent);
-
-        // Static or dynamic lambda allocation
-        String staticLambda = srcPort.annotations().value(AnnotationKeys.STATIC_LAMBDA);
-        OchPort srcOchPort = (OchPort) srcPort;
-        OchPort dstOchPort = (OchPort) dstPort;
-
-        // FIXME: need to actually reserve the lambda for static lambda's
-        // static lambda case: early return
-        if (staticLambda != null) {
-
-            OchSignal lambda = new OchSignal(Frequency.ofHz(Long.parseLong(staticLambda)),
-                                             srcOchPort.lambda().channelSpacing(),
-                                             srcOchPort.lambda().slotGranularity());
-            log.debug("Using statically assigned lambda : {}", lambda);
-
-            List<Resource> res = new ArrayList<>();
-
-            Path satPath = paths.filter(path -> {
-                // FIXME trimming both ends (staticLambda assigned ports)
-                // Proper fix is to let device advertise static lambda as resource.
-                LinkedList<Link> links = new LinkedList<>(path.links());
-                links.pollFirst();
-                links.pollLast();
-
-                List<Resource> r = convertToResources(links, toFlexGrid(lambda));
-                if (r.stream().allMatch(resourceService::isAvailable)) {
-                    // FIXME bad practice to have side-effect during stream
-                    res.addAll(r);
-                    return true;
-                }
-                return false;
-            }).findFirst().orElse(null);
-
-            if (satPath == null) {
-                // FIXME doing something very wrong to preserve old behavior
-                // as a fallback
-                log.warn("No feasible path between {}-{} using {}",
-                         src, dst, lambda);
-
-                satPath = getOpticalPaths(intent).iterator().next();
-                if (satPath == null) {
-                    throw new OpticalIntentCompilationException(
-                        "Unable to find suitable lightpath for intent " + intent);
-                }
-                return ImmutableList.of(createIntent(intent, satPath, lambda));
-            }
-
-            resources.addAll(res);
-            allocateResources(intent, resources);
-
-            return ImmutableList.of(createIntent(intent, satPath, lambda));
-        }
-
-        // FIXME: also check destination OCh port
-        // non-tunable case: early return
-        if (!srcOchPort.isTunable() || !dstOchPort.isTunable()) {
-            Path firstPath = paths.findAny().orElse(null);
-            if (firstPath == null) {
-                log.error("Unable to find suitable lightpath for intent {}", intent);
-                throw new OpticalIntentCompilationException("Unable to find suitable lightpath for intent " + intent);
-            }
-            OchSignal lambda = srcOchPort.lambda();
-            // TODO apply the same as static lambda case above
-            // - pick feasible path
-            // - allocate resources
-            //resources.addAll(convertToResources(firstPath.links(), toFlexGrid(lambda)));
-            allocateResources(intent, resources);
-            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
-                .map(path -> Maps.immutableEntry(path, findFirstAvailableOch(path)))
+                .map(path ->
+                        Maps.immutableEntry(path, findFirstAvailableLambda(path)))
                 .filter(entry -> !entry.getValue().isEmpty())
-                .filter(entry -> convertToResources(entry.getKey().links(),
+                .filter(entry -> convertToResources(entry.getKey(),
                         entry.getValue()).stream().allMatch(resourceService::isAvailable))
                 .findFirst();
 
+        // Allocate resources and create optical path intent
         if (found.isPresent()) {
-            resources.addAll(convertToResources(found.get().getKey().links(), found.get().getValue()));
+            resources.addAll(convertToResources(found.get().getKey(), found.get().getValue()));
 
             allocateResources(intent, resources);
 
@@ -227,9 +153,16 @@
         }
     }
 
+    /**
+     * Create installable optical path intent.
+     * Only supports fixed grid for now.
+     *
+     * @param parentIntent this intent (used for resource tracking)
+     * @param path the path to use
+     * @param lambda the lambda to use
+     * @return optical path 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()
@@ -245,8 +178,30 @@
                 .build();
     }
 
+    /**
+     * Convert given lambda as discrete resource of all path ports.
+     *
+     * @param path the path
+     * @param lambda the lambda
+     * @return list of discrete resources
+     */
+    private List<Resource> convertToResources(Path path, Collection<OchSignal> lambda) {
+        return path.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());
+    }
+
+    /**
+     * Reserve all required resources for this intent.
+     *
+     * @param intent the intent
+     * @param resources list of resources to reserve
+     */
     private void allocateResources(Intent intent, List<Resource> resources) {
-        // reserve all of required resources
         List<ResourceAllocation> allocations = resourceService.allocate(intent.key(), resources);
         if (allocations.isEmpty()) {
             log.error("Resource allocation for {} failed (resource request: {})", intent.key(), resources);
@@ -259,8 +214,14 @@
         }
     }
 
-    private List<OchSignal> findFirstAvailableOch(Path path) {
-        Set<OchSignal> lambdas = findCommonLambdasOverLinks(path.links());
+    /**
+     * Find the first available lambda on the given path by checking all the port resources.
+     *
+     * @param path the path
+     * @return list of consecutive and available OChSignals
+     */
+    private List<OchSignal> findFirstAvailableLambda(Path path) {
+        Set<OchSignal> lambdas = findCommonLambdas(path);
         if (lambdas.isEmpty()) {
             return Collections.emptyList();
         }
@@ -268,16 +229,6 @@
         return findFirstLambda(lambdas, slotCount());
     }
 
-    private List<Resource> convertToResources(List<Link> links, Collection<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.
      *
@@ -290,8 +241,14 @@
         return SLOT_COUNT;
     }
 
-    private Set<OchSignal> findCommonLambdasOverLinks(List<Link> links) {
-        return links.stream()
+    /**
+     * Find common lambdas on all ports that compose the path.
+     *
+     * @param path the path
+     * @return set of common lambdas
+     */
+    private Set<OchSignal> findCommonLambdas(Path path) {
+        return path.links().stream()
                 .flatMap(x -> Stream.of(
                         Resources.discrete(x.src().deviceId(), x.src().port()).id(),
                         Resources.discrete(x.dst().deviceId(), x.dst().port()).id()
