diff --git a/core/api/src/test/java/org/onosproject/net/NetTestTools.java b/core/api/src/test/java/org/onosproject/net/NetTestTools.java
index dd03a09..86ee0f7 100644
--- a/core/api/src/test/java/org/onosproject/net/NetTestTools.java
+++ b/core/api/src/test/java/org/onosproject/net/NetTestTools.java
@@ -234,6 +234,12 @@
                 .build();
     }
 
+    public static TrafficSelector ethDstSelector(String macAddress) {
+        return DefaultTrafficSelector.builder()
+                .matchEthDst(MacAddress.valueOf(macAddress))
+                .build();
+    }
+
     /**
      * Builds an empty treatment.
      *
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
index 40f7f77..e14115c 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/IntentConfigurableRegistrator.java
@@ -17,6 +17,7 @@
 package org.onosproject.net.intent.impl.compiler;
 
 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;
@@ -35,6 +36,7 @@
 import org.slf4j.Logger;
 
 import java.util.Map;
+import java.util.Set;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
 import static org.slf4j.LoggerFactory.getLogger;
@@ -79,8 +81,22 @@
             label = "Indicates whether or not to use copy ttl in the link collection compiler")
     private boolean useCopyTtl = DEFAULT_COPY_TTL;
 
+    /**
+     * Temporary for switching old compiler and new compiler.
+     * @deprecated 1.10 Kingfisher
+     */
+    private static final String DEFAULT_FLOW_OBJECTIVE_COMPILER =
+            "org.onosproject.net.intent.impl.compiler.LinkCollectionIntentFlowObjectiveCompiler";
+    @Deprecated
+    @Property(name = "defaultFlowObjectiveCompiler",
+            value = DEFAULT_FLOW_OBJECTIVE_COMPILER,
+            label = "Default compiler to generate flow objective")
+    private String defaultFlowObjectiveCompiler = DEFAULT_FLOW_OBJECTIVE_COMPILER;
+
     private final Map<Class<Intent>, IntentCompiler<Intent>> flowRuleBased = Maps.newConcurrentMap();
-    private final Map<Class<Intent>, IntentCompiler<Intent>> flowObjectiveBased = Maps.newConcurrentMap();
+
+    // FIXME: temporary code for switching old compiler to new compiler
+    private final Map<Class<Intent>, Set<IntentCompiler<Intent>>> flowObjectiveBased = Maps.newConcurrentMap();
 
     @Activate
     public void activate() {
@@ -101,6 +117,9 @@
             log.info("Settings: labelSelection={}", labelSelection);
             log.info("Settings: useFlowOptimization={}", useFlowOptimization);
             log.info("Settings: useCopyTtl={}", useCopyTtl);
+
+            // FIXME: temporary code for switching old compiler to new compiler
+            log.info("Settings: defaultFlowObjectiveCompiler={}", defaultFlowObjectiveCompiler);
             return;
         }
 
@@ -118,6 +137,21 @@
             log.info("Settings: useFlowObjectives={}", useFlowObjectives);
         }
 
+        // FIXME: temporary code for switching old compiler to new compiler
+        String newDefaultFlowObjectiveCompiler;
+        try {
+            String s = Tools.get(context.getProperties(), "defaultFlowObjectiveCompiler");
+            newDefaultFlowObjectiveCompiler = isNullOrEmpty(s) ? defaultFlowObjectiveCompiler : s.trim();
+        } catch (ClassCastException e) {
+            newDefaultFlowObjectiveCompiler = defaultFlowObjectiveCompiler;
+        }
+
+        if (!defaultFlowObjectiveCompiler.equals(newDefaultFlowObjectiveCompiler)) {
+            defaultFlowObjectiveCompiler = newDefaultFlowObjectiveCompiler;
+            changeCompilers();
+            log.info("Settings: defaultFlowObjectiveCompiler={}", defaultFlowObjectiveCompiler);
+        }
+
         String newLabelSelection;
         try {
             String s = Tools.get(context.getProperties(), "labelSelection");
@@ -173,7 +207,15 @@
     <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler,
                                              boolean flowBased) {
         if (flowBased) {
-            flowObjectiveBased.put((Class<Intent>) cls, (IntentCompiler<Intent>) compiler);
+            // FIXME: temporary code for switching old compiler to new compiler
+            flowObjectiveBased.compute((Class<Intent>) cls, (clz, compilers) -> {
+                if (compilers == null) {
+                    compilers = Sets.newHashSet();
+                }
+
+                compilers.add((IntentCompiler<Intent>) compiler);
+                return compilers;
+            });
         } else {
             flowRuleBased.put((Class<Intent>) cls, (IntentCompiler<Intent>) compiler);
         }
@@ -204,7 +246,15 @@
     private void changeCompilers() {
         if (useFlowObjectives) {
             flowRuleBased.forEach((cls, compiler) -> extensionService.unregisterCompiler(cls));
-            flowObjectiveBased.forEach((cls, compiler) -> extensionService.registerCompiler(cls, compiler));
+            // FIXME: temporary code for switching old compiler to new compiler
+            flowObjectiveBased.forEach((cls, compilers) -> {
+                compilers.forEach(compiler -> {
+                    // filter out flow objective compiler which doesn't match
+                    if (compiler.getClass().getName().equals(defaultFlowObjectiveCompiler)) {
+                        extensionService.registerCompiler(cls, compiler);
+                    }
+                });
+            });
         } else {
             flowObjectiveBased.forEach((cls, compiler) -> extensionService.unregisterCompiler(cls));
             flowRuleBased.forEach((cls, compiler) -> extensionService.registerCompiler(cls, compiler));
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentFlowObjectiveCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentFlowObjectiveCompiler.java
index 0aa4e87..9396ab5 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentFlowObjectiveCompiler.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentFlowObjectiveCompiler.java
@@ -52,7 +52,9 @@
 
 /**
  * Compiler to produce flow objectives from link collections.
+ * @deprecated 1.10 Kingfisher
  */
+@Deprecated
 @Component(immediate = true)
 public class LinkCollectionIntentFlowObjectiveCompiler
         extends LinkCollectionCompiler<Objective>
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentObjectiveCompiler.java b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentObjectiveCompiler.java
new file mode 100644
index 0000000..2af0be5
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentObjectiveCompiler.java
@@ -0,0 +1,292 @@
+/*
+ * 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 com.google.common.collect.HashMultimap;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.SetMultimap;
+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.Identifier;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.intent.FlowObjectiveIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentCompiler;
+import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.intent.constraint.EncapsulationConstraint;
+import org.onosproject.net.resource.ResourceService;
+import org.onosproject.net.resource.impl.LabelAllocator;
+
+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 static org.onosproject.net.flow.instructions.Instruction.Type.OUTPUT;
+
+/**
+ * Compiler to produce flow objectives from link collections.
+ */
+@Component(immediate = true)
+public class LinkCollectionIntentObjectiveCompiler
+        extends LinkCollectionCompiler<Objective>
+        implements IntentCompiler<LinkCollectionIntent> {
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentConfigurableRegistrator registrator;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ResourceService resourceService;
+
+    private ApplicationId appId;
+
+    @Activate
+    public void activate() {
+        appId = coreService.registerApplication("org.onosproject.net.intent");
+        registrator.registerCompiler(LinkCollectionIntent.class, this, true);
+        if (labelAllocator == null) {
+            labelAllocator = new LabelAllocator(resourceService);
+        }
+    }
+
+
+    @Deactivate
+    public void deactivate() {
+        registrator.unregisterCompiler(LinkCollectionIntent.class, true);
+    }
+
+    @Override
+    public List<Intent> compile(LinkCollectionIntent intent, List<Intent> installable) {
+
+        SetMultimap<DeviceId, PortNumber> inputPorts = HashMultimap.create();
+        SetMultimap<DeviceId, PortNumber> outputPorts = HashMultimap.create();
+        Map<ConnectPoint, Identifier<?>> labels = ImmutableMap.of();
+
+        Optional<EncapsulationConstraint> encapConstraint = this.getIntentEncapConstraint(intent);
+
+        computePorts(intent, inputPorts, outputPorts);
+
+        if (encapConstraint.isPresent()) {
+            labels = labelAllocator.assignLabelToPorts(intent.links(),
+                                                       intent.id(),
+                                                       encapConstraint.get().encapType());
+        }
+
+        List<Objective> objectives = new ArrayList<>();
+        List<DeviceId> devices = new ArrayList<>();
+        for (DeviceId deviceId: outputPorts.keySet()) {
+            List<Objective> deviceObjectives =
+                    createRules(intent,
+                                deviceId,
+                                inputPorts.get(deviceId),
+                                outputPorts.get(deviceId),
+                                labels);
+            deviceObjectives.forEach(objective -> {
+                objectives.add(objective);
+                devices.add(deviceId);
+            });
+        }
+        return Collections.singletonList(
+                new FlowObjectiveIntent(appId, intent.key(), devices,
+                                        objectives,
+                                        intent.resources(),
+                                        intent.resourceGroup()));
+    }
+
+    @Override
+    protected List<Objective> createRules(LinkCollectionIntent intent,
+                                          DeviceId deviceId,
+                                          Set<PortNumber> inPorts,
+                                          Set<PortNumber> outPorts,
+                                          Map<ConnectPoint, Identifier<?>> labels) {
+
+        List<Objective> objectives = new ArrayList<>(inPorts.size() * 2);
+
+        /*
+         * Looking for the encapsulation constraint
+         */
+        Optional<EncapsulationConstraint> encapConstraint = this.getIntentEncapConstraint(intent);
+
+        inPorts.forEach(inport -> {
+
+            ForwardingInstructions instructions = this.createForwardingInstruction(
+                    encapConstraint,
+                    intent,
+                    inport,
+                    outPorts,
+                    deviceId,
+                    labels
+            );
+
+            Set<TrafficTreatment> treatmentsWithDifferentPort =
+                    Sets.newHashSet();
+
+            TrafficTreatment.Builder treatmentBuilder =
+                    DefaultTrafficTreatment.builder();
+
+            for (Instruction inst : instructions.treatment().allInstructions()) {
+                if (inst.type() == OUTPUT) {
+                    treatmentBuilder.add(inst);
+                    treatmentsWithDifferentPort.add(treatmentBuilder.build());
+                    treatmentBuilder = DefaultTrafficTreatment.builder();
+                } else {
+                    treatmentBuilder.add(inst);
+                }
+            }
+
+            EthCriterion ethDst = (EthCriterion) instructions.selector()
+                    .getCriterion(Criterion.Type.ETH_DST);
+            boolean broadcastObjective = ethDst != null &&
+                    (ethDst.mac().isBroadcast() || ethDst.mac().isMulticast());
+
+            if (treatmentsWithDifferentPort.size() < 2 && !broadcastObjective) {
+                objectives.addAll(createSimpleNextObjective(instructions, intent));
+            } else {
+                objectives.addAll(createBroadcastObjective(instructions,
+                                                           treatmentsWithDifferentPort,
+                                                           intent));
+            }
+        });
+
+        return objectives;
+    }
+
+    private List<Objective> createBroadcastObjective(ForwardingInstructions instructions,
+                                                     Set<TrafficTreatment> treatmentsWithDifferentPort,
+                                                     LinkCollectionIntent intent) {
+        List<Objective> objectives = Lists.newArrayList();
+        FilteringObjective filteringObjective;
+        ForwardingObjective forwardingObjective;
+        NextObjective nextObjective;
+
+        Integer nextId = flowObjectiveService.allocateNextId();
+
+        forwardingObjective = buildForwardingObjective(instructions.selector(),
+                                                       nextId, intent.priority());
+
+        DefaultNextObjective.Builder nxBuilder = DefaultNextObjective.builder();
+        nxBuilder.withId(nextId)
+                .withMeta(instructions.selector())
+                .withType(NextObjective.Type.BROADCAST)
+                .fromApp(appId)
+                .withPriority(intent.priority())
+                .makePermanent();
+
+        treatmentsWithDifferentPort.forEach(nxBuilder::addTreatment);
+        nextObjective = nxBuilder.add();
+
+        filteringObjective = buildFilteringObjective(instructions.selector(), intent.priority());
+
+        objectives.add(filteringObjective);
+        objectives.add(forwardingObjective);
+        objectives.add(nextObjective);
+
+        return objectives;
+    }
+
+    private List<Objective> createSimpleNextObjective(ForwardingInstructions instructions,
+                                                      LinkCollectionIntent intent) {
+        List<Objective> objectives = Lists.newArrayList();
+        FilteringObjective filteringObjective;
+        ForwardingObjective forwardingObjective;
+        NextObjective nextObjective;
+
+        Integer nextId = flowObjectiveService.allocateNextId();
+
+        forwardingObjective = buildForwardingObjective(instructions.selector(),
+                                                       nextId, intent.priority());
+
+        DefaultNextObjective.Builder nxBuilder = DefaultNextObjective.builder();
+        nextObjective = nxBuilder.withId(nextId)
+                .withMeta(instructions.selector())
+                .addTreatment(instructions.treatment())
+                .withType(NextObjective.Type.SIMPLE)
+                .fromApp(appId)
+                .makePermanent()
+                .withPriority(intent.priority())
+                .add();
+
+        filteringObjective = buildFilteringObjective(instructions.selector(), intent.priority());
+
+        objectives.add(filteringObjective);
+        objectives.add(forwardingObjective);
+        objectives.add(nextObjective);
+
+        return objectives;
+    }
+
+    private ForwardingObjective buildForwardingObjective(TrafficSelector selector, Integer nextId, int priority) {
+        return DefaultForwardingObjective.builder()
+                .withMeta(selector)
+                .withSelector(selector)
+                .nextStep(nextId)
+                .fromApp(appId)
+                .withPriority(priority)
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .makePermanent()
+                .add();
+    }
+
+    private FilteringObjective buildFilteringObjective(TrafficSelector selector, int priority) {
+        FilteringObjective.Builder builder = DefaultFilteringObjective.builder();
+        builder.fromApp(appId)
+                .permit()
+                .makePermanent()
+                .withPriority(priority);
+
+        Criterion inPortCriterion =
+                selector.getCriterion(Criterion.Type.IN_PORT);
+
+        if (inPortCriterion != null) {
+            builder.withKey(inPortCriterion);
+        }
+
+        selector.criteria().forEach(builder::addCondition);
+        return builder.add();
+    }
+
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
index bd2c7c7..f6e5dc8 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/AbstractLinkCollectionTest.java
@@ -24,6 +24,7 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.Link;
+import org.onosproject.net.ResourceGroup;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
@@ -66,6 +67,7 @@
 
     final ConnectPoint of1p1 = connectPoint("of1", 1);
     final ConnectPoint of1p2 = connectPoint("of1", 2);
+    final ConnectPoint of1p3 = connectPoint("of1", 3);
     final ConnectPoint of2p1 = connectPoint("of2", 1);
     final ConnectPoint of2p2 = connectPoint("of2", 2);
     final ConnectPoint of2p3 = connectPoint("of2", 3);
@@ -124,6 +126,9 @@
     final TrafficSelector mpls100Selector = mplsSelector("100");
     final TrafficSelector mpls200Selector = mplsSelector("200");
     final TrafficSelector ipPrefixSelector = ipPrefixDstSelector("192.168.100.0/24");
+    final TrafficSelector ethDstSelector = ethDstSelector("C0:FF:EE:C0:FF:EE");
+    final ResourceGroup resourceGroup1 = ResourceGroup.of(1L);
+    final ResourceGroup resourceGroup2 = ResourceGroup.of(1L);
 
     final List<Constraint> constraintsForVlan = vlanConstraint();
     final List<Constraint> constraintsForMPLS = mplsConstraint();
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentObjectiveCompilerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentObjectiveCompilerTest.java
new file mode 100644
index 0000000..22ecf48
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/compiler/LinkCollectionIntentObjectiveCompilerTest.java
@@ -0,0 +1,862 @@
+/*
+ * Copyright 2017-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.ImmutableSet;
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.cfg.ComponentConfigAdapter;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.Link;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.PortCriterion;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.intent.FlowObjectiveIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.LinkCollectionIntent;
+import org.onosproject.net.resource.MockResourceService;
+import org.onosproject.net.resource.ResourceService;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.CoreMatchers.hasItem;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.nullValue;
+import static org.onosproject.net.Link.Type.DIRECT;
+import static org.onosproject.net.NetTestTools.PID;
+
+public class LinkCollectionIntentObjectiveCompilerTest extends AbstractLinkCollectionTest {
+
+    private LinkCollectionIntentObjectiveCompiler compiler;
+    private FlowObjectiveServiceAdapter flowObjectiveService;
+
+    private NextObjective nextObjective;
+    private ForwardingObjective forwardingObjective;
+    private FilteringObjective filteringObjective;
+
+    private ResourceService resourceService;
+
+    @Before
+    public void setUp() {
+        compiler = new LinkCollectionIntentObjectiveCompiler();
+        coreService = createMock(CoreService.class);
+        expect(coreService.registerApplication("org.onosproject.net.intent"))
+                .andReturn(appId);
+        flowObjectiveService = new FlowObjectiveServiceAdapter();
+        resourceService = new MockResourceService();
+        compiler.coreService = coreService;
+        compiler.flowObjectiveService = flowObjectiveService;
+
+        Intent.bindIdGenerator(idGenerator);
+
+        intentExtensionService = createMock(IntentExtensionService.class);
+        intentExtensionService.registerCompiler(LinkCollectionIntent.class, compiler);
+        intentExtensionService.unregisterCompiler(LinkCollectionIntent.class);
+
+        registrator = new IntentConfigurableRegistrator();
+        registrator.extensionService = intentExtensionService;
+        registrator.cfgService = new ComponentConfigAdapter();
+        registrator.activate();
+
+        compiler.registrator = registrator;
+        compiler.resourceService = resourceService;
+
+        LinkCollectionCompiler.optimize = false;
+        LinkCollectionCompiler.copyTtl = false;
+
+        replay(coreService, intentExtensionService);
+
+    }
+
+    @After
+    public void tearDown() {
+        Intent.unbindIdGenerator(idGenerator);
+    }
+
+    /**
+     * We test the proper compilation of a simple link collection intent
+     * with connect points, empty trivial treatment and empty trivial selector.
+     */
+    @Test
+    public void testCompile() {
+        compiler.activate();
+
+        LinkCollectionIntent intent = LinkCollectionIntent.builder()
+                .appId(appId)
+                .selector(selector)
+                .treatment(treatment)
+                .links(links)
+                .filteredIngressPoints(ImmutableSet.of(new FilteredConnectPoint(d1p1)))
+                .filteredEgressPoints(ImmutableSet.of(new FilteredConnectPoint(d3p1)))
+                .build();
+
+        List<Intent> result = compiler.compile(intent, Collections.emptyList());
+        assertThat(result, hasSize(1));
+        assertThat(result.get(0), instanceOf(FlowObjectiveIntent.class));
+
+        FlowObjectiveIntent foIntent = (FlowObjectiveIntent) result.get(0);
+        List<Objective> objectives = foIntent.objectives();
+        assertThat(objectives, hasSize(9));
+
+        /*
+         * First set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(0);
+        forwardingObjective = (ForwardingObjective) objectives.get(1);
+        nextObjective = (NextObjective) objectives.get(2);
+
+        // expect selector and treatment
+        TrafficSelector expectSelector = DefaultTrafficSelector.builder()
+                .matchInPort(PortNumber.portNumber(1))
+                .build();
+        TrafficTreatment expectTreatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.portNumber(1))
+                .build();
+        PortCriterion inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * Second set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(3);
+        forwardingObjective = (ForwardingObjective) objectives.get(4);
+        nextObjective = (NextObjective) objectives.get(5);
+
+
+        expectSelector = DefaultTrafficSelector.builder()
+                .matchInPort(PortNumber.portNumber(0))
+                .build();
+
+        inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for second next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for second forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * 3rd set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(6);
+        forwardingObjective = (ForwardingObjective) objectives.get(7);
+        nextObjective = (NextObjective) objectives.get(8);
+
+        expectSelector = DefaultTrafficSelector.builder()
+                .matchInPort(PortNumber.portNumber(1))
+                .build();
+
+        inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for 3rd next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for 3rd forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        compiler.deactivate();
+    }
+
+    /**
+     * Single point to multi point case. Scenario is the follow:
+     *
+     * -1 of1 2-1 of2 2--1 of3 2-
+     *             3
+     *             `-1 of4 2-
+     *
+     * We test the proper compilation of sp2mp with trivial selector,
+     * empty treatment and points.
+     *
+     */
+    @Test
+    public void testFilteredConnectPointForSp() {
+        compiler.activate();
+        Set<Link> testLinks = ImmutableSet.of(
+                DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
+                DefaultLink.builder().providerId(PID).src(of2p2).dst(of3p1).type(DIRECT).build(),
+                DefaultLink.builder().providerId(PID).src(of2p3).dst(of4p1).type(DIRECT).build()
+        );
+
+        Set<FilteredConnectPoint> ingress = ImmutableSet.of(
+                new FilteredConnectPoint(of1p1, vlan100Selector)
+        );
+
+        Set<FilteredConnectPoint> egress = ImmutableSet.of(
+                new FilteredConnectPoint(of3p2, vlan100Selector),
+                new FilteredConnectPoint(of4p2, vlan100Selector)
+        );
+
+        TrafficSelector broadcastSelector = DefaultTrafficSelector.builder()
+                .matchEthDst(MacAddress.BROADCAST)
+                .build();
+
+        LinkCollectionIntent intent = LinkCollectionIntent.builder()
+                .appId(appId)
+                .selector(broadcastSelector)
+                .treatment(treatment)
+                .links(testLinks)
+                .filteredIngressPoints(ingress)
+                .filteredEgressPoints(egress)
+                .applyTreatmentOnEgress(true)
+                .resourceGroup(resourceGroup1)
+                .build();
+
+        List<Intent> result = compiler.compile(intent, Collections.emptyList());
+        assertThat(result, hasSize(1));
+        assertThat(result.get(0), instanceOf(FlowObjectiveIntent.class));
+
+        FlowObjectiveIntent foIntent = (FlowObjectiveIntent) result.get(0);
+        List<Objective> objectives = foIntent.objectives();
+        assertThat(objectives, hasSize(12));
+
+        /*
+         * First set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(0);
+        forwardingObjective = (ForwardingObjective) objectives.get(1);
+        nextObjective = (NextObjective) objectives.get(2);
+
+        // expect selector and treatment
+        TrafficSelector expectSelector = DefaultTrafficSelector.builder()
+                .matchInPort(PortNumber.portNumber(1))
+                .matchVlanId(VlanId.vlanId("100"))
+                .matchEthDst(MacAddress.BROADCAST)
+                .build();
+        TrafficTreatment expectTreatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.portNumber(2))
+                .build();
+
+        PortCriterion inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.BROADCAST));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * Second set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(3);
+        forwardingObjective = (ForwardingObjective) objectives.get(4);
+        nextObjective = (NextObjective) objectives.get(5);
+
+        inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for second next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.BROADCAST));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for second forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * 3rd set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(6);
+        forwardingObjective = (ForwardingObjective) objectives.get(7);
+        nextObjective = (NextObjective) objectives.get(8);
+
+        inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for 3rd next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.BROADCAST));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for 3rd forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * 4th set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(9);
+        forwardingObjective = (ForwardingObjective) objectives.get(10);
+        nextObjective = (NextObjective) objectives.get(11);
+
+        inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for 3rd next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.BROADCAST));
+
+        // have 2 treatments in this objective
+        assertThat(nextObjective.next(), hasSize(2));
+        expectTreatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.portNumber(2))
+                .build();
+        assertThat(nextObjective.next(), hasItem(expectTreatment));
+
+        expectTreatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.portNumber(3))
+                .build();
+        assertThat(nextObjective.next(), hasItem(expectTreatment));
+
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for 3rd forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        compiler.deactivate();
+    }
+
+    /**
+     * Multi point to single point intent with filtered connect point.
+     * Scenario is the follow:
+     *
+     * -1 of1 2-1 of2 2-1 of4 2-
+     *             3
+     * -1 of3 2---/
+     *
+     */
+    @Test
+    public void testFilteredConnectPointForMp() {
+        compiler.activate();
+        Set<Link> testLinks = ImmutableSet.of(
+                DefaultLink.builder().providerId(PID).src(of1p2).dst(of2p1).type(DIRECT).build(),
+                DefaultLink.builder().providerId(PID).src(of3p2).dst(of2p3).type(DIRECT).build(),
+                DefaultLink.builder().providerId(PID).src(of2p2).dst(of4p1).type(DIRECT).build()
+        );
+
+        Set<FilteredConnectPoint> ingress = ImmutableSet.of(
+                new FilteredConnectPoint(of3p1, vlan100Selector),
+                new FilteredConnectPoint(of1p1, vlan100Selector)
+        );
+
+        Set<FilteredConnectPoint> egress = ImmutableSet.of(
+                new FilteredConnectPoint(of4p2, vlan100Selector)
+        );
+
+
+
+        LinkCollectionIntent intent = LinkCollectionIntent.builder()
+                .appId(appId)
+                .selector(ethDstSelector)
+                .treatment(treatment)
+                .links(testLinks)
+                .filteredIngressPoints(ingress)
+                .filteredEgressPoints(egress)
+                .build();
+
+        List<Intent> result = compiler.compile(intent, Collections.emptyList());
+        assertThat(result, hasSize(1));
+        assertThat(result.get(0), instanceOf(FlowObjectiveIntent.class));
+
+        FlowObjectiveIntent foIntent = (FlowObjectiveIntent) result.get(0);
+        List<Objective> objectives = foIntent.objectives();
+        assertThat(objectives, hasSize(15));
+
+        TrafficSelector expectSelector = DefaultTrafficSelector
+                .builder(ethDstSelector)
+                .matchInPort(PortNumber.portNumber(1))
+                .matchVlanId(VlanId.vlanId("100"))
+                .build();
+
+        TrafficTreatment expectTreatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.portNumber(2))
+                .build();
+
+        /*
+         * First set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(0);
+        forwardingObjective = (ForwardingObjective) objectives.get(1);
+        nextObjective = (NextObjective) objectives.get(2);
+
+        PortCriterion inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * Second set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(3);
+        forwardingObjective = (ForwardingObjective) objectives.get(4);
+        nextObjective = (NextObjective) objectives.get(5);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * 3rd set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(6);
+        forwardingObjective = (ForwardingObjective) objectives.get(7);
+        nextObjective = (NextObjective) objectives.get(8);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * 4th set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(9);
+        forwardingObjective = (ForwardingObjective) objectives.get(10);
+        nextObjective = (NextObjective) objectives.get(11);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * 5th set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(12);
+        forwardingObjective = (ForwardingObjective) objectives.get(13);
+        nextObjective = (NextObjective) objectives.get(14);
+
+        expectSelector = DefaultTrafficSelector.builder(ethDstSelector)
+                .matchVlanId(VlanId.vlanId("100"))
+                .matchInPort(PortNumber.portNumber(3))
+                .build();
+
+        inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+        compiler.deactivate();
+    }
+
+    /**
+     * Multiple point to single point intent with only one switch.
+     * We test the proper compilation of mp2sp with
+     * trivial selector, trivial treatment and 1 hop.
+     */
+    @Test
+    public void singleHopTestForMp() {
+        compiler.activate();
+        Set<Link> testLinks = ImmutableSet.of();
+
+        Set<FilteredConnectPoint> ingress = ImmutableSet.of(
+                new FilteredConnectPoint(of1p1, vlan100Selector),
+                new FilteredConnectPoint(of1p2, vlan100Selector)
+        );
+
+        Set<FilteredConnectPoint> egress = ImmutableSet.of(
+                new FilteredConnectPoint(of1p3, vlan100Selector)
+        );
+
+
+        LinkCollectionIntent intent = LinkCollectionIntent.builder()
+                .appId(appId)
+                .selector(ethDstSelector)
+                .treatment(treatment)
+                .links(testLinks)
+                .filteredIngressPoints(ingress)
+                .filteredEgressPoints(egress)
+                .build();
+
+        List<Intent> result = compiler.compile(intent, Collections.emptyList());
+        assertThat(result, hasSize(1));
+        assertThat(result.get(0), instanceOf(FlowObjectiveIntent.class));
+
+        FlowObjectiveIntent foIntent = (FlowObjectiveIntent) result.get(0);
+        List<Objective> objectives = foIntent.objectives();
+        assertThat(objectives, hasSize(6));
+
+        TrafficSelector expectSelector = DefaultTrafficSelector
+                .builder(ethDstSelector)
+                .matchInPort(PortNumber.portNumber(1))
+                .matchVlanId(VlanId.vlanId("100"))
+                .build();
+
+        TrafficTreatment expectTreatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.portNumber(3))
+                .build();
+
+        /*
+         * First set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(0);
+        forwardingObjective = (ForwardingObjective) objectives.get(1);
+        nextObjective = (NextObjective) objectives.get(2);
+
+        PortCriterion inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        /*
+         * Second set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(3);
+        forwardingObjective = (ForwardingObjective) objectives.get(4);
+        nextObjective = (NextObjective) objectives.get(5);
+
+        expectSelector = DefaultTrafficSelector.builder(ethDstSelector)
+                .matchInPort(PortNumber.portNumber(2))
+                .matchVlanId(VlanId.vlanId("100"))
+                .build();
+
+        inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.SIMPLE));
+        assertThat(nextObjective.next(), hasSize(1));
+        assertThat(nextObjective.next().iterator().next(), is(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+        compiler.deactivate();
+    }
+
+    /**
+     * Single point to multiple point intent with only one switch.
+     * We test the proper compilation of sp2mp with
+     * trivial selector, trivial treatment and 1 hop.
+     */
+    @Test
+    public void singleHopTestForSp() {
+        compiler.activate();
+        Set<Link> testLinks = ImmutableSet.of();
+
+        Set<FilteredConnectPoint> ingress = ImmutableSet.of(
+                new FilteredConnectPoint(of1p1, vlan100Selector)
+        );
+
+        Set<FilteredConnectPoint> egress = ImmutableSet.of(
+                new FilteredConnectPoint(of1p2, vlan100Selector),
+                new FilteredConnectPoint(of1p3, vlan100Selector)
+        );
+
+
+        LinkCollectionIntent intent = LinkCollectionIntent.builder()
+                .appId(appId)
+                .selector(ethDstSelector)
+                .treatment(treatment)
+                .links(testLinks)
+                .filteredIngressPoints(ingress)
+                .filteredEgressPoints(egress)
+                .applyTreatmentOnEgress(true)
+                .resourceGroup(resourceGroup2)
+                .build();
+
+        List<Intent> result = compiler.compile(intent, Collections.emptyList());
+        assertThat(result, hasSize(1));
+        assertThat(result.get(0), instanceOf(FlowObjectiveIntent.class));
+
+        FlowObjectiveIntent foIntent = (FlowObjectiveIntent) result.get(0);
+        List<Objective> objectives = foIntent.objectives();
+        assertThat(objectives, hasSize(3));
+
+        TrafficSelector expectSelector = DefaultTrafficSelector
+                .builder(ethDstSelector)
+                .matchInPort(PortNumber.portNumber(1))
+                .matchVlanId(VlanId.vlanId("100"))
+                .build();
+
+        TrafficTreatment expectTreatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.portNumber(3))
+                .build();
+
+        /*
+         * First set of objective
+         */
+        filteringObjective = (FilteringObjective) objectives.get(0);
+        forwardingObjective = (ForwardingObjective) objectives.get(1);
+        nextObjective = (NextObjective) objectives.get(2);
+
+        PortCriterion inPortCriterion =
+                (PortCriterion) expectSelector.getCriterion(Criterion.Type.IN_PORT);
+
+        // test case for first filtering objective
+        assertThat(filteringObjective.key(), is(inPortCriterion));
+        assertThat(filteringObjective.priority(), is(intent.priority()));
+        assertThat(filteringObjective.meta(), nullValue());
+        assertThat(filteringObjective.appId(), is(appId));
+        assertThat(filteringObjective.permanent(), is(true));
+        assertThat(filteringObjective.conditions(), is(Lists.newArrayList(expectSelector.criteria())));
+
+        // test case for first next objective
+        assertThat(nextObjective.type(), is(NextObjective.Type.BROADCAST));
+        assertThat(nextObjective.next(), hasSize(2));
+        assertThat(nextObjective.next(), hasItem(expectTreatment));
+        expectTreatment = DefaultTrafficTreatment.builder()
+                .setOutput(PortNumber.portNumber(3))
+                .build();
+        assertThat(nextObjective.next(), hasItem(expectTreatment));
+        assertThat(nextObjective.meta(), is(expectSelector));
+        assertThat(nextObjective.op(), is(Objective.Operation.ADD));
+
+        // test case for first forwarding objective
+        assertThat(forwardingObjective.op(), is(Objective.Operation.ADD));
+        assertThat(forwardingObjective.selector(), is(expectSelector));
+        assertThat(forwardingObjective.nextId(), is(nextObjective.id()));
+        assertThat(forwardingObjective.flag(), is(ForwardingObjective.Flag.SPECIFIC));
+
+        compiler.deactivate();
+
+    }
+
+
+}
