diff --git a/cli/src/main/java/org/onosproject/cli/net/FlowObjectiveCompositionCommand.java b/cli/src/main/java/org/onosproject/cli/net/FlowObjectiveCompositionCommand.java
new file mode 100644
index 0000000..9bacc7a
--- /dev/null
+++ b/cli/src/main/java/org/onosproject/cli/net/FlowObjectiveCompositionCommand.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2015 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.cli.net;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+
+/**
+ * Manages FlowObjectiveComposition policy.
+ */
+@Command(scope = "onos", name = "policy",
+        description = "Manages FlowObjectiveComposition policy")
+public class FlowObjectiveCompositionCommand extends AbstractShellCommand {
+
+    @Argument(index = 0, name = "command",
+            description = "Command name (install)",
+            required = true, multiValued = false)
+    String command = null;
+
+    @Argument(index = 1, name = "names", description = "policy string",
+            required = true, multiValued = true)
+    String[] policies = null;
+
+    @Override
+    protected void execute() {
+        FlowObjectiveService service = get(FlowObjectiveService.class);
+        service.initPolicy(policies[0]);
+        print("Policy %s installed", policies[0]);
+    }
+}
diff --git a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index ca470e3..367013c 100644
--- a/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
+++ b/cli/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -30,6 +30,10 @@
         </command>
 
         <command>
+            <action class="org.onosproject.cli.net.FlowObjectiveCompositionCommand"/>
+        </command>
+
+        <command>
             <action class="org.onosproject.cli.app.ApplicationsListCommand"/>
         </command>
 
diff --git a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
index cb9a248..d325415 100644
--- a/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
+++ b/core/api/src/main/java/org/onosproject/net/flowobjective/FlowObjectiveService.java
@@ -56,4 +56,10 @@
      */
     int allocateNextId();
 
+    /**
+     * Installs the filtering rules onto the specified device.
+     *
+     * @param policy            policy expression
+     */
+    void initPolicy(String policy);
 }
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
index 4247f03..7d0713b 100644
--- a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/FlowObjectiveManager.java
@@ -218,6 +218,9 @@
         return flowObjectiveStore.allocateNextId();
     }
 
+    @Override
+    public void initPolicy(String policy) {}
+
     private boolean queueObjective(DeviceId deviceId, ForwardingObjective fwd) {
         if (fwd.nextId() != null &&
                 flowObjectiveStore.getNextGroup(fwd.nextId()) == null) {
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FilterTable.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FilterTable.java
new file mode 100644
index 0000000..b46ce8b
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FilterTable.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 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.flowobjective.impl.composition;
+
+import org.onosproject.net.flowobjective.FilteringObjective;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides a table to store Fitler.
+ */
+public class FilterTable {
+
+    protected Map<Integer, FilteringObjective> filterMap;
+
+    public FilterTable() {
+        this.filterMap = new HashMap<>();
+    }
+
+    public List<FilteringObjective> updateFilter(FilteringObjective filteringObjective) {
+        List<FilteringObjective> updates = new ArrayList<>();
+        switch (filteringObjective.op()) {
+            case ADD:
+                this.filterMap.put(filteringObjective.id(), filteringObjective);
+                updates.add(filteringObjective);
+                break;
+            case REMOVE:
+                this.filterMap.remove(filteringObjective.id());
+                updates.add(filteringObjective);
+                break;
+            default:
+                break;
+        }
+        return updates;
+    }
+
+    public List<FilteringObjective> updateFilter(List<FilteringObjective> filteringObjectives) {
+        List<FilteringObjective> updates = new ArrayList<>();
+        for (FilteringObjective filteringObjective : filteringObjectives) {
+            updates.addAll(this.updateFilter(filteringObjective));
+        }
+        return updates;
+    }
+
+}
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java
new file mode 100644
index 0000000..1d25c2e
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionManager.java
@@ -0,0 +1,439 @@
+/*
+ * Copyright 2015 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.flowobjective.impl.composition;
+
+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.apache.felix.scr.annotations.Service;
+import org.onlab.osgi.DefaultServiceDirectory;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.util.ItemNotFoundException;
+import org.onosproject.cluster.ClusterService;
+import org.onosproject.core.Permission;
+import org.onosproject.mastership.MastershipEvent;
+import org.onosproject.mastership.MastershipListener;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.behaviour.PipelinerContext;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.driver.DefaultDriverProviderService;
+import org.onosproject.net.driver.DriverHandler;
+import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.FlowObjectiveStore;
+import org.onosproject.net.flowobjective.FlowObjectiveStoreDelegate;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.flowobjective.ObjectiveEvent;
+import org.onosproject.net.group.GroupService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static java.util.concurrent.Executors.newFixedThreadPool;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.security.AppGuard.checkPermission;
+
+
+/**
+ * Provides implementation of the flow objective programming service with composition feature.
+ *
+ * Note: This is an experimental, alternative implementation of the FlowObjectiveManager
+ * that supports composition. It can be enabled by setting the enable flag below to true,
+ * and you should also add "enabled = false" to the FlowObjectiveManager.
+ *
+ * The implementation relies a FlowObjectiveCompositionTree that is not yet distributed,
+ * so it will not have high availability and may break if device mastership changes.
+ * Therefore, it is safest to use this component in a single instance scenario.
+ * This comment will be removed when a distributed implementation is available.
+ */
+@Component(immediate = true, enabled = false)
+@Service
+public class FlowObjectiveCompositionManager implements FlowObjectiveService {
+
+    public enum PolicyOperator {
+        Parallel,
+        Sequential,
+        Override,
+        Application
+    }
+
+    public static final int INSTALL_RETRY_ATTEMPTS = 5;
+    public static final long INSTALL_RETRY_INTERVAL = 1000; // ms
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DriverService driverService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ClusterService clusterService;
+
+    // Note: The following dependencies are added on behalf of the pipeline
+    // driver behaviours to assure these services are available for their
+    // initialization.
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected GroupService groupService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveStore flowObjectiveStore;
+
+    // Note: This must remain an optional dependency to allow re-install of default drivers.
+    // Note: For now disabled until we can move to OPTIONAL_UNARY dependency
+    // @Reference(cardinality = ReferenceCardinality.OPTIONAL_UNARY, policy = ReferencePolicy.DYNAMIC)
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DefaultDriverProviderService defaultDriverService;
+
+    private final FlowObjectiveStoreDelegate delegate = new InternalStoreDelegate();
+
+    private final Map<DeviceId, DriverHandler> driverHandlers = Maps.newConcurrentMap();
+    private final Map<DeviceId, Pipeliner> pipeliners = Maps.newConcurrentMap();
+
+    private final PipelinerContext context = new InnerPipelineContext();
+    private final MastershipListener mastershipListener = new InnerMastershipListener();
+    private final DeviceListener deviceListener = new InnerDeviceListener();
+
+    protected ServiceDirectory serviceDirectory = new DefaultServiceDirectory();
+
+    private Map<Integer, Set<PendingNext>> pendingForwards = Maps.newConcurrentMap();
+
+    private ExecutorService executorService;
+
+    private String policy;
+    private Map<DeviceId, FlowObjectiveCompositionTree> deviceCompositionTreeMap;
+
+    @Activate
+    protected void activate() {
+        executorService = newFixedThreadPool(4, groupedThreads("onos/objective-installer", "%d"));
+        flowObjectiveStore.setDelegate(delegate);
+        mastershipService.addListener(mastershipListener);
+        deviceService.addListener(deviceListener);
+        deviceService.getDevices().forEach(device -> setupPipelineHandler(device.id()));
+        deviceCompositionTreeMap = Maps.newConcurrentMap();
+        log.info("Started");
+    }
+
+    @Deactivate
+    protected void deactivate() {
+        flowObjectiveStore.unsetDelegate(delegate);
+        mastershipService.removeListener(mastershipListener);
+        deviceService.removeListener(deviceListener);
+        executorService.shutdown();
+        pipeliners.clear();
+        driverHandlers.clear();
+        deviceCompositionTreeMap.clear();
+        log.info("Stopped");
+    }
+
+    /**
+     * Task that passes the flow objective down to the driver. The task will
+     * make a few attempts to find the appropriate driver, then eventually give
+     * up and report an error if no suitable driver could be found.
+     */
+    private class ObjectiveInstaller implements Runnable {
+        private final DeviceId deviceId;
+        private final Objective objective;
+
+        private final int numAttempts;
+
+        public ObjectiveInstaller(DeviceId deviceId, Objective objective) {
+            this(deviceId, objective, 1);
+        }
+
+        public ObjectiveInstaller(DeviceId deviceId, Objective objective, int attemps) {
+            this.deviceId = checkNotNull(deviceId);
+            this.objective = checkNotNull(objective);
+            this.numAttempts = checkNotNull(attemps);
+        }
+
+        @Override
+        public void run() {
+            try {
+                Pipeliner pipeliner = getDevicePipeliner(deviceId);
+
+                if (pipeliner != null) {
+                    if (objective instanceof NextObjective) {
+                        pipeliner.next((NextObjective) objective);
+                    } else if (objective instanceof ForwardingObjective) {
+                        pipeliner.forward((ForwardingObjective) objective);
+                    } else {
+                        pipeliner.filter((FilteringObjective) objective);
+                    }
+                } else if (numAttempts < INSTALL_RETRY_ATTEMPTS) {
+                    Thread.sleep(INSTALL_RETRY_INTERVAL);
+                    executorService.submit(new ObjectiveInstaller(deviceId, objective, numAttempts + 1));
+                } else {
+                    // Otherwise we've tried a few times and failed, report an
+                    // error back to the user.
+                    objective.context().ifPresent(
+                            c -> c.onError(objective, ObjectiveError.DEVICEMISSING));
+                }
+            } catch (Exception e) {
+                log.warn("Exception while installing flow objective", e);
+            }
+        }
+    }
+
+    @Override
+    public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
+        checkPermission(Permission.FLOWRULE_WRITE);
+
+        List<FilteringObjective> filteringObjectives
+                = this.deviceCompositionTreeMap.get(deviceId).updateFilter(filteringObjective);
+        for (FilteringObjective tmp : filteringObjectives) {
+            executorService.submit(new ObjectiveInstaller(deviceId, tmp));
+        }
+    }
+
+    @Override
+    public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
+        checkPermission(Permission.FLOWRULE_WRITE);
+
+        if (queueObjective(deviceId, forwardingObjective)) {
+            return;
+        }
+        List<ForwardingObjective> forwardingObjectives
+                = this.deviceCompositionTreeMap.get(deviceId).updateForward(forwardingObjective);
+        for (ForwardingObjective tmp : forwardingObjectives) {
+            executorService.submit(new ObjectiveInstaller(deviceId, tmp));
+        }
+    }
+
+    @Override
+    public void next(DeviceId deviceId, NextObjective nextObjective) {
+        checkPermission(Permission.FLOWRULE_WRITE);
+
+        List<NextObjective> nextObjectives = this.deviceCompositionTreeMap.get(deviceId).updateNext(nextObjective);
+        for (NextObjective tmp : nextObjectives) {
+            executorService.submit(new ObjectiveInstaller(deviceId, tmp));
+        }
+    }
+
+    @Override
+    public int allocateNextId() {
+        checkPermission(Permission.FLOWRULE_WRITE);
+
+        return flowObjectiveStore.allocateNextId();
+    }
+
+    private boolean queueObjective(DeviceId deviceId, ForwardingObjective fwd) {
+        if (fwd.nextId() != null &&
+                flowObjectiveStore.getNextGroup(fwd.nextId()) == null) {
+            log.trace("Queuing forwarding objective for nextId {}", fwd.nextId());
+            if (pendingForwards.putIfAbsent(fwd.nextId(),
+                    Sets.newHashSet(new PendingNext(deviceId, fwd))) != null) {
+                Set<PendingNext> pending = pendingForwards.get(fwd.nextId());
+                pending.add(new PendingNext(deviceId, fwd));
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void initPolicy(String policy) {
+        this.policy = policy;
+        deviceService.getDevices().forEach(device ->
+                this.deviceCompositionTreeMap.put(device.id(), FlowObjectiveCompositionUtil.parsePolicyString(policy)));
+        log.info("Initialize policy {}", policy);
+    }
+
+    // Retrieves the device pipeline behaviour from the cache.
+    private Pipeliner getDevicePipeliner(DeviceId deviceId) {
+        Pipeliner pipeliner = pipeliners.get(deviceId);
+        return pipeliner;
+    }
+
+    private void setupPipelineHandler(DeviceId deviceId) {
+        if (defaultDriverService == null) {
+            // We're not ready to go to work yet.
+            return;
+        }
+
+        // Attempt to lookup the handler in the cache
+        DriverHandler handler = driverHandlers.get(deviceId);
+        if (handler == null) {
+            try {
+                // Otherwise create it and if it has pipeline behaviour, cache it
+                handler = driverService.createHandler(deviceId);
+                if (!handler.driver().hasBehaviour(Pipeliner.class)) {
+                    log.warn("Pipeline behaviour not supported for device {}",
+                            deviceId);
+                    return;
+                }
+            } catch (ItemNotFoundException e) {
+                log.warn("No applicable driver for device {}", deviceId);
+                return;
+            }
+
+            driverHandlers.put(deviceId, handler);
+        }
+
+        // Always (re)initialize the pipeline behaviour
+        log.info("Driver {} bound to device {} ... initializing driver",
+                handler.driver().name(), deviceId);
+        Pipeliner pipeliner = handler.behaviour(Pipeliner.class);
+        pipeliner.init(deviceId, context);
+        pipeliners.putIfAbsent(deviceId, pipeliner);
+    }
+
+    // Triggers driver setup when the local node becomes a device master.
+    private class InnerMastershipListener implements MastershipListener {
+        @Override
+        public void event(MastershipEvent event) {
+            switch (event.type()) {
+                case MASTER_CHANGED:
+                    log.debug("mastership changed on device {}", event.subject());
+                    if (deviceService.isAvailable(event.subject())) {
+                        setupPipelineHandler(event.subject());
+                    }
+                    break;
+                case BACKUPS_CHANGED:
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    // Triggers driver setup when a device is (re)detected.
+    private class InnerDeviceListener implements DeviceListener {
+        @Override
+        public void event(DeviceEvent event) {
+            switch (event.type()) {
+                case DEVICE_ADDED:
+                case DEVICE_AVAILABILITY_CHANGED:
+                    log.debug("Device either added or availability changed {}",
+                            event.subject().id());
+                    if (deviceService.isAvailable(event.subject().id())) {
+                        log.debug("Device is now available {}", event.subject().id());
+                        setupPipelineHandler(event.subject().id());
+                    }
+                    break;
+                case DEVICE_UPDATED:
+                    break;
+                case DEVICE_REMOVED:
+                    break;
+                case DEVICE_SUSPENDED:
+                    break;
+                case PORT_ADDED:
+                    break;
+                case PORT_UPDATED:
+                    break;
+                case PORT_REMOVED:
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    // Processing context for initializing pipeline driver behaviours.
+    private class InnerPipelineContext implements PipelinerContext {
+        @Override
+        public ServiceDirectory directory() {
+            return serviceDirectory;
+        }
+
+        @Override
+        public FlowObjectiveStore store() {
+            return flowObjectiveStore;
+        }
+    }
+
+    private class InternalStoreDelegate implements FlowObjectiveStoreDelegate {
+        @Override
+        public void notify(ObjectiveEvent event) {
+            log.debug("Received notification of obj event {}", event);
+            Set<PendingNext> pending = pendingForwards.remove(event.subject());
+
+            if (pending == null) {
+                log.debug("Nothing pending for this obj event");
+                return;
+            }
+
+            log.debug("Processing pending forwarding objectives {}", pending.size());
+
+            pending.forEach(p -> getDevicePipeliner(p.deviceId())
+                    .forward(p.forwardingObjective()));
+
+        }
+    }
+
+    /**
+     * Data class used to hold a pending forwarding objective that could not
+     * be processed because the associated next object was not present.
+     */
+    private class PendingNext {
+        private final DeviceId deviceId;
+        private final ForwardingObjective fwd;
+
+        public PendingNext(DeviceId deviceId, ForwardingObjective fwd) {
+            this.deviceId = deviceId;
+            this.fwd = fwd;
+        }
+
+        public DeviceId deviceId() {
+            return deviceId;
+        }
+
+        public ForwardingObjective forwardingObjective() {
+            return fwd;
+        }
+    }
+
+    public static String forwardingObjectiveToString(ForwardingObjective forwardingObjective) {
+        String str = forwardingObjective.priority() + " ";
+        str += "selector( ";
+        for (Criterion criterion : forwardingObjective.selector().criteria()) {
+            str += criterion + " ";
+        }
+        str += ") treatment( ";
+        for (Instruction instruction : forwardingObjective.treatment().allInstructions()) {
+            str += instruction + " ";
+        }
+        str += ")";
+        return str;
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionTree.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionTree.java
new file mode 100644
index 0000000..152622b
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionTree.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2015 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.flowobjective.impl.composition;
+
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * Provides a policy tree to store all flow tables for each device.
+ *
+ * Note: This class uses in-memory structures and is not yet distributed.
+ */
+public class FlowObjectiveCompositionTree {
+
+    public FlowObjectiveCompositionManager.PolicyOperator operator;
+    public FlowObjectiveCompositionTree leftChild;
+    public FlowObjectiveCompositionTree rightChild;
+    public short applicationId;
+    protected FilterTable filterTable;
+    protected ForwardTable forwardTable;
+    protected NextTable nextTable;
+
+    protected int priorityMultiplier;
+    protected int priorityAddend;
+
+    public FlowObjectiveCompositionTree(short applicationId) {
+        this.operator = FlowObjectiveCompositionManager.PolicyOperator.Application;
+        this.leftChild = null;
+        this.rightChild = null;
+        this.applicationId = applicationId;
+        this.filterTable = new FilterTable();
+        this.forwardTable = new ForwardTable();
+        this.nextTable = new NextTable();
+        this.priorityMultiplier = 10;
+        this.priorityAddend = 10;
+    }
+
+    public FlowObjectiveCompositionTree(Character ch) {
+        switch (ch) {
+            case '+':
+                this.operator = FlowObjectiveCompositionManager.PolicyOperator.Parallel;
+                break;
+            case '>':
+                this.operator = FlowObjectiveCompositionManager.PolicyOperator.Sequential;
+                break;
+            case '/':
+                this.operator = FlowObjectiveCompositionManager.PolicyOperator.Override;
+                break;
+            default:
+                this.operator = FlowObjectiveCompositionManager.PolicyOperator.Application;
+                break;
+        }
+        this.leftChild = null;
+        this.rightChild = null;
+        this.applicationId = (short) -1;
+        this.filterTable = new FilterTable();
+        this.forwardTable = new ForwardTable();
+        this.nextTable = new NextTable();
+        this.priorityMultiplier = 10;
+        this.priorityAddend = 10;
+    }
+
+    protected List<FilteringObjective> updateFilter(FilteringObjective filteringObjective) {
+        switch (this.operator) {
+            case Parallel:
+                return updateFilterParallel(filteringObjective);
+            case Sequential:
+                return updateFilterSequential(filteringObjective);
+            case Override:
+                return updateFilterOverride(filteringObjective);
+            case Application:
+                if (filteringObjective.appId().id() == this.applicationId) {
+                    return this.filterTable.updateFilter(filteringObjective);
+                } else {
+                    return new ArrayList<>();
+                }
+            default:
+                    return new ArrayList<>();
+        }
+    }
+
+    // Parallel composition: the filter set is the union of the children
+    protected List<FilteringObjective> updateFilterParallel(FilteringObjective filteringObjective) {
+        List<FilteringObjective> leftUpdates = this.leftChild.updateFilter(filteringObjective);
+        List<FilteringObjective> rightUpdates = this.rightChild.updateFilter(filteringObjective);
+
+        List<FilteringObjective> updates = new ArrayList<>();
+        updates.addAll(leftUpdates);
+        updates.addAll(rightUpdates);
+
+        return this.filterTable.updateFilter(updates);
+    }
+
+    // Sequential composition: the filter set is the filter set of the left child
+    protected List<FilteringObjective> updateFilterSequential(FilteringObjective filteringObjective) {
+        List<FilteringObjective> leftUpdates = this.leftChild.updateFilter(filteringObjective);
+        List<FilteringObjective> rightUpdates = this.rightChild.updateFilter(filteringObjective);
+        return this.filterTable.updateFilter(leftUpdates);
+    }
+
+    // Override composition: the filter set is the filter set of the left child
+    protected List<FilteringObjective> updateFilterOverride(FilteringObjective filteringObjective) {
+        List<FilteringObjective> leftUpdates = this.leftChild.updateFilter(filteringObjective);
+        List<FilteringObjective> rightUpdates = this.rightChild.updateFilter(filteringObjective);
+        return this.filterTable.updateFilter(leftUpdates);
+    }
+
+    public List<ForwardingObjective> updateForward(ForwardingObjective forwardingObjective) {
+        return this.updateForwardNode(forwardingObjective).toForwardingObjectiveList();
+    }
+
+    public ForwardUpdateTable updateForwardNode(ForwardingObjective forwardingObjective) {
+        switch (this.operator) {
+            case Parallel:
+            case Sequential:
+            case Override:
+                return updateForwardComposition(forwardingObjective);
+            case Application:
+                if (forwardingObjective.appId().id() == this.applicationId) {
+                    return this.forwardTable.updateForward(forwardingObjective);
+                } else {
+                    return (new ForwardUpdateTable());
+                }
+            default:
+                return (new ForwardUpdateTable());
+        }
+    }
+
+    protected ForwardUpdateTable updateForwardComposition(ForwardingObjective forwardingObjective) {
+        ForwardUpdateTable leftUpdates = this.leftChild.updateForwardNode(forwardingObjective);
+        ForwardUpdateTable rightUpdates = this.rightChild.updateForwardNode(forwardingObjective);
+
+        List<ForwardingObjective> addUpdates = new ArrayList<>();
+        List<ForwardingObjective> removeUpdates = new ArrayList<>();
+        // Handle ADD
+        if (this.operator == FlowObjectiveCompositionManager.PolicyOperator.Parallel
+                || this.operator == FlowObjectiveCompositionManager.PolicyOperator.Sequential) {
+            for (ForwardingObjective fo1 : leftUpdates.addObjectives) {
+                for (ForwardingObjective fo2 : this.rightChild.forwardTable.getForwardingObjectives()) {
+                    ForwardingObjective composedFo = null;
+                    if (this.operator == FlowObjectiveCompositionManager.PolicyOperator.Parallel) {
+                        composedFo = FlowObjectiveCompositionUtil.composeParallel(fo1, fo2);
+                    } else {
+                        composedFo = FlowObjectiveCompositionUtil.composeSequential(fo1, fo2, this.priorityMultiplier);
+                    }
+                    if (composedFo != null) {
+                        addUpdates.add(composedFo);
+                        this.leftChild.forwardTable.addGeneratedParentForwardingObjective(fo1, composedFo);
+                        this.rightChild.forwardTable.addGeneratedParentForwardingObjective(fo2, composedFo);
+                    }
+                }
+            }
+            Collection<ForwardingObjective> leftTableWithoutAdd = FlowObjectiveCompositionUtil
+                    .minusForwardingObjectives(this.leftChild.forwardTable.getForwardingObjectives(),
+                            leftUpdates.addObjectives);
+            for (ForwardingObjective fo1 : leftTableWithoutAdd) {
+                for (ForwardingObjective fo2 : rightUpdates.addObjectives) {
+                    ForwardingObjective composedFo = null;
+                    if (this.operator == FlowObjectiveCompositionManager.PolicyOperator.Parallel) {
+                        composedFo = FlowObjectiveCompositionUtil.composeParallel(fo1, fo2);
+                    } else {
+                        composedFo = FlowObjectiveCompositionUtil.composeSequential(fo1, fo2, this.priorityMultiplier);
+                    }
+                    if (composedFo != null) {
+                        addUpdates.add(composedFo);
+                        this.leftChild.forwardTable.addGeneratedParentForwardingObjective(fo1, composedFo);
+                        this.rightChild.forwardTable.addGeneratedParentForwardingObjective(fo2, composedFo);
+                    }
+                }
+            }
+        } else {
+            for (ForwardingObjective fo : leftUpdates.addObjectives) {
+                ForwardingObjective composedFo = FlowObjectiveCompositionUtil.composeOverride(fo, this.priorityAddend);
+                addUpdates.add(composedFo);
+                this.leftChild.forwardTable.addGeneratedParentForwardingObjective(fo, composedFo);
+            }
+            for (ForwardingObjective fo : rightUpdates.addObjectives) {
+                ForwardingObjective composedFo = FlowObjectiveCompositionUtil.composeOverride(fo, 0);
+                addUpdates.add(composedFo);
+                this.rightChild.forwardTable.addGeneratedParentForwardingObjective(fo, composedFo);
+            }
+        }
+
+        // Handle REMOVE
+        for (ForwardingObjective fo : leftUpdates.removeObjectives) {
+            List<ForwardingObjective> fos = this.leftChild.forwardTable
+                    .getGeneratedParentForwardingObjectiveForRemove(fo);
+            removeUpdates.addAll(fos);
+        }
+        this.leftChild.forwardTable.deleteGeneratedParentForwardingObjective(leftUpdates.removeObjectives);
+        for (ForwardingObjective fo : rightUpdates.removeObjectives) {
+            List<ForwardingObjective> fos = this.rightChild.forwardTable
+                    .getGeneratedParentForwardingObjectiveForRemove(fo);
+            removeUpdates.addAll(fos);
+        }
+        this.rightChild.forwardTable.deleteGeneratedParentForwardingObjective(rightUpdates.removeObjectives);
+
+        ForwardUpdateTable updates = new ForwardUpdateTable();
+        updates.addUpdateTable(this.forwardTable.updateForward(addUpdates));
+        updates.addUpdateTable(this.forwardTable.updateForward(removeUpdates));
+        return updates;
+    }
+
+    public List<NextObjective> updateNext(NextObjective nextObjective) {
+        switch (this.operator) {
+            case Parallel:
+            case Sequential:
+            case Override:
+                return updateNextComposition(nextObjective);
+            case Application:
+                if (nextObjective.appId().id() == this.applicationId) {
+                    return this.nextTable.updateNext(nextObjective);
+                } else {
+                    return new ArrayList<>();
+                }
+            default:
+                return new ArrayList<>();
+        }
+    }
+
+    // Next: the union of the children
+    protected List<NextObjective> updateNextComposition(NextObjective nextObjective) {
+        List<NextObjective> leftUpdates = this.leftChild.updateNext(nextObjective);
+        List<NextObjective> rightUpdates = this.rightChild.updateNext(nextObjective);
+
+        List<NextObjective> updates = new ArrayList<>();
+        updates.addAll(leftUpdates);
+        updates.addAll(rightUpdates);
+
+        return this.nextTable.updateNext(updates);
+    }
+
+    @Override
+    public String toString() {
+        String str = null;
+        switch (this.operator) {
+            case Parallel:
+                str = "(" + this.leftChild + "+" + this.rightChild + ")";
+                break;
+            case Sequential:
+                str = "(" + this.leftChild + ">" + this.rightChild + ")";
+                break;
+            case Override:
+                str = "(" + this.leftChild + "/" + this.rightChild + ")";
+                break;
+            default:
+                str = " " + applicationId + " ";
+                break;
+        }
+        return str;
+    }
+
+}
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java
new file mode 100644
index 0000000..0cc383b
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/FlowObjectiveCompositionUtil.java
@@ -0,0 +1,488 @@
+/*
+ * Copyright 2015 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.flowobjective.impl.composition;
+
+import org.onlab.packet.IpPrefix;
+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.LambdaCriterion;
+import org.onosproject.net.flow.criteria.OchSignalCriterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.criteria.VlanPcpCriterion;
+import org.onosproject.net.flow.criteria.MplsCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L0ModificationInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+
+/**
+ * Provide util functions for FlowObjectiveComposition.
+ */
+public final class FlowObjectiveCompositionUtil {
+
+    private FlowObjectiveCompositionUtil() {}
+
+    // only work with VERSATILE
+    public static ForwardingObjective composeParallel(ForwardingObjective fo1, ForwardingObjective fo2) {
+
+        TrafficSelector trafficSelector = intersectTrafficSelector(fo1.selector(), fo2.selector());
+        if (trafficSelector == null) {
+            return null;
+        }
+
+        TrafficTreatment trafficTreatment = unionTrafficTreatment(fo1.treatment(), fo2.treatment());
+
+        return DefaultForwardingObjective.builder()
+                .fromApp(fo1.appId())
+                .makePermanent()
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .withPriority(fo1.priority() + fo2.priority())
+                .withSelector(trafficSelector)
+                .withTreatment(trafficTreatment)
+                .add();
+    }
+
+    public static ForwardingObjective composeSequential(ForwardingObjective fo1,
+                                                        ForwardingObjective fo2,
+                                                        int priorityMultiplier) {
+
+        TrafficSelector revertTrafficSelector = revertTreatmentSelector(fo1.treatment(), fo2.selector());
+        if (revertTrafficSelector == null) {
+            return null;
+        }
+
+        TrafficSelector trafficSelector = intersectTrafficSelector(fo1.selector(), revertTrafficSelector);
+        if (trafficSelector == null) {
+            return null;
+        }
+
+        TrafficTreatment trafficTreatment = unionTrafficTreatment(fo1.treatment(), fo2.treatment());
+
+        return DefaultForwardingObjective.builder()
+                .fromApp(fo1.appId())
+                .makePermanent()
+                .withFlag(ForwardingObjective.Flag.VERSATILE)
+                .withPriority(fo1.priority() * priorityMultiplier + fo2.priority())
+                .withSelector(trafficSelector)
+                .withTreatment(trafficTreatment)
+                .add();
+    }
+
+    public static ForwardingObjective composeOverride(ForwardingObjective fo, int priorityAddend) {
+        return DefaultForwardingObjective.builder()
+                .fromApp(fo.appId())
+                .makePermanent()
+                .withFlag(fo.flag())
+                .withPriority(fo.priority() + priorityAddend)
+                .withSelector(fo.selector())
+                .withTreatment(fo.treatment())
+                .add();
+    }
+
+    public static TrafficSelector intersectTrafficSelector(TrafficSelector ts1, TrafficSelector ts2) {
+
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+
+        Set<Criterion.Type> ts1IntersectTs2 = getTypeSet(ts1);
+        ts1IntersectTs2.retainAll(getTypeSet(ts2));
+        for (Criterion.Type type : ts1IntersectTs2) {
+            Criterion criterion = intersectCriterion(ts1.getCriterion(type), ts2.getCriterion(type));
+            if (criterion == null) {
+                return null;
+            } else {
+                selectorBuilder.add(criterion);
+            }
+        }
+
+        Set<Criterion.Type> ts1MinusTs2 = getTypeSet(ts1);
+        ts1MinusTs2.removeAll(getTypeSet(ts2));
+        for (Criterion.Type type : ts1MinusTs2) {
+            selectorBuilder.add(ts1.getCriterion(type));
+        }
+
+        Set<Criterion.Type> ts2MinusTs1 = getTypeSet(ts2);
+        ts2MinusTs1.removeAll(getTypeSet(ts1));
+        for (Criterion.Type type : ts2MinusTs1) {
+            selectorBuilder.add(ts2.getCriterion(type));
+        }
+
+        return selectorBuilder.build();
+    }
+
+    public static TrafficTreatment unionTrafficTreatment(TrafficTreatment tt1, TrafficTreatment tt2) {
+
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+
+        for (Instruction instruction : tt1.allInstructions()) {
+            treatmentBuilder.add(instruction);
+        }
+
+        for (Instruction instruction : tt2.allInstructions()) {
+            treatmentBuilder.add(instruction);
+        }
+
+        return treatmentBuilder.build();
+    }
+
+    public static TrafficSelector revertTreatmentSelector(TrafficTreatment trafficTreatment,
+                                                          TrafficSelector trafficSelector) {
+
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+
+        Map<Criterion.Type, Criterion> criterionMap = new HashMap<>();
+        for (Criterion criterion : trafficSelector.criteria()) {
+            criterionMap.put(criterion.type(), criterion);
+        }
+
+        for (Instruction instruction : trafficTreatment.allInstructions()) {
+            switch (instruction.type()) {
+                case DROP:
+                    return null;
+                case OUTPUT:
+                    break;
+                case GROUP:
+                    break;
+                case L0MODIFICATION: {
+                    L0ModificationInstruction l0 = (L0ModificationInstruction) instruction;
+                    switch (l0.subtype()) {
+                        case LAMBDA:
+                            if (criterionMap.containsKey(Criterion.Type.OCH_SIGID)) {
+                                if (((LambdaCriterion) criterionMap.get((Criterion.Type.OCH_SIGID))).lambda()
+                                        == ((L0ModificationInstruction.ModLambdaInstruction) l0).lambda()) {
+                                    criterionMap.remove(Criterion.Type.OCH_SIGID);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        case OCH:
+                            if (criterionMap.containsKey(Criterion.Type.OCH_SIGID)) {
+                                if (((OchSignalCriterion) criterionMap.get((Criterion.Type.OCH_SIGID))).lambda()
+                                        .equals(((L0ModificationInstruction.ModOchSignalInstruction) l0).lambda())) {
+                                    criterionMap.remove(Criterion.Type.OCH_SIGID);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        default:
+                            break;
+                    }
+                    break;
+                }
+                case L2MODIFICATION: {
+                    L2ModificationInstruction l2 = (L2ModificationInstruction) instruction;
+                    switch (l2.subtype()) {
+                        case ETH_SRC:
+                            if (criterionMap.containsKey(Criterion.Type.ETH_SRC)) {
+                                if (((EthCriterion) criterionMap.get((Criterion.Type.ETH_SRC))).mac()
+                                        .equals(((L2ModificationInstruction.ModEtherInstruction) l2).mac())) {
+                                    criterionMap.remove(Criterion.Type.ETH_SRC);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        case ETH_DST:
+                            if (criterionMap.containsKey(Criterion.Type.ETH_DST)) {
+                                if (((EthCriterion) criterionMap.get((Criterion.Type.ETH_DST))).mac()
+                                        .equals(((L2ModificationInstruction.ModEtherInstruction) l2).mac())) {
+                                    criterionMap.remove(Criterion.Type.ETH_DST);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        case VLAN_ID:
+                            if (criterionMap.containsKey(Criterion.Type.VLAN_VID)) {
+                                if (((VlanIdCriterion) criterionMap.get((Criterion.Type.VLAN_VID))).vlanId()
+                                        .equals(((L2ModificationInstruction.ModVlanIdInstruction) l2).vlanId())) {
+                                    criterionMap.remove(Criterion.Type.VLAN_VID);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        case VLAN_PCP:
+                            if (criterionMap.containsKey(Criterion.Type.VLAN_PCP)) {
+                                if (((VlanPcpCriterion) criterionMap.get((Criterion.Type.VLAN_PCP))).priority()
+                                        == ((L2ModificationInstruction.ModVlanPcpInstruction) l2).vlanPcp()) {
+                                    criterionMap.remove(Criterion.Type.VLAN_PCP);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        case MPLS_LABEL:
+                            if (criterionMap.containsKey(Criterion.Type.MPLS_LABEL)) {
+                                if (((MplsCriterion) criterionMap.get((Criterion.Type.MPLS_LABEL))).label()
+                                        .equals(((L2ModificationInstruction.ModMplsLabelInstruction) l2).label())) {
+                                    criterionMap.remove(Criterion.Type.ETH_DST);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        default:
+                            break;
+                    }
+                    break;
+                }
+                case TABLE:
+                    break;
+                case L3MODIFICATION: {
+                    L3ModificationInstruction l3 = (L3ModificationInstruction) instruction;
+                    switch (l3.subtype()) {
+                        case IPV4_SRC:
+                            if (criterionMap.containsKey(Criterion.Type.IPV4_SRC)) {
+                                if (((IPCriterion) criterionMap.get(Criterion.Type.IPV4_SRC)).ip()
+                                        .contains(((L3ModificationInstruction.ModIPInstruction) l3).ip())) {
+                                    criterionMap.remove(Criterion.Type.IPV4_SRC);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        case IPV4_DST:
+                            if (criterionMap.containsKey(Criterion.Type.IPV4_DST)) {
+                                if (((IPCriterion) criterionMap.get(Criterion.Type.IPV4_DST)).ip()
+                                        .contains(((L3ModificationInstruction.ModIPInstruction) l3).ip())) {
+                                    criterionMap.remove(Criterion.Type.IPV4_DST);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        case IPV6_SRC:
+                            if (criterionMap.containsKey(Criterion.Type.IPV6_SRC)) {
+                                if (((IPCriterion) criterionMap.get(Criterion.Type.IPV6_SRC)).ip()
+                                        .contains(((L3ModificationInstruction.ModIPInstruction) l3).ip())) {
+                                    criterionMap.remove(Criterion.Type.IPV6_SRC);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        case IPV6_DST:
+                            if (criterionMap.containsKey(Criterion.Type.IPV6_DST)) {
+                                if (((IPCriterion) criterionMap.get(Criterion.Type.IPV6_DST)).ip()
+                                        .contains(((L3ModificationInstruction.ModIPInstruction) l3).ip())) {
+                                    criterionMap.remove(Criterion.Type.IPV6_DST);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        case IPV6_FLABEL:
+                            if (criterionMap.containsKey(Criterion.Type.IPV6_FLABEL)) {
+                                if (((IPCriterion) criterionMap.get(Criterion.Type.IPV6_FLABEL)).ip()
+                                        .equals(((L3ModificationInstruction.ModIPv6FlowLabelInstruction) l3)
+                                                .flowLabel())) {
+                                    criterionMap.remove(Criterion.Type.IPV4_SRC);
+                                } else {
+                                    return null;
+                                }
+                            } else {
+                                break;
+                            }
+                        default:
+                            break;
+                    }
+                    break;
+                }
+                case METADATA:
+                    break;
+                default:
+                    break;
+            }
+        }
+
+        for (Criterion criterion : criterionMap.values()) {
+            selectorBuilder.add(criterion);
+        }
+
+        return selectorBuilder.build();
+    }
+
+    public static Set<Criterion.Type> getTypeSet(TrafficSelector trafficSelector) {
+        Set<Criterion.Type> typeSet = new HashSet<>();
+        for (Criterion criterion : trafficSelector.criteria()) {
+            typeSet.add(criterion.type());
+        }
+        return typeSet;
+    }
+
+    public static Criterion intersectCriterion(Criterion c1, Criterion c2) {
+        switch (c1.type()) {
+            case IPV4_SRC: {
+                IpPrefix ipPrefix = intersectIpPrefix(((IPCriterion) c1).ip(), ((IPCriterion) c2).ip());
+                if (ipPrefix == null) {
+                    return null;
+                } else {
+                    return Criteria.matchIPSrc(ipPrefix);
+                }
+            }
+            case IPV4_DST: {
+                IpPrefix ipPrefix = intersectIpPrefix(((IPCriterion) c1).ip(), ((IPCriterion) c2).ip());
+                if (ipPrefix == null) {
+                    return null;
+                } else {
+                    return Criteria.matchIPDst(ipPrefix);
+                }
+            }
+            case IPV6_SRC: {
+                IpPrefix ipPrefix = intersectIpPrefix(((IPCriterion) c1).ip(), ((IPCriterion) c2).ip());
+                if (ipPrefix == null) {
+                    return null;
+                } else {
+                    return Criteria.matchIPv6Src(ipPrefix);
+                }
+            }
+            case IPV6_DST: {
+                IpPrefix ipPrefix = intersectIpPrefix(((IPCriterion) c1).ip(), ((IPCriterion) c2).ip());
+                if (ipPrefix == null) {
+                    return null;
+                } else {
+                    return Criteria.matchIPv6Dst(ipPrefix);
+                }
+            }
+            default:
+                if (!c1.equals(c2)) {
+                    return null;
+                } else {
+                    return c1;
+                }
+        }
+    }
+
+    public static IpPrefix intersectIpPrefix(IpPrefix ip1, IpPrefix ip2) {
+        if (ip1.contains(ip2)) {
+            return ip1;
+        } else if (ip2.contains(ip1)) {
+            return ip2;
+        } else {
+            return null;
+        }
+    }
+
+    public static FlowObjectiveCompositionTree parsePolicyString(String policy) {
+        List<FlowObjectiveCompositionTree> postfix = transformToPostfixForm(policy);
+        return buildPolicyTree(postfix);
+    }
+
+    private static List<FlowObjectiveCompositionTree> transformToPostfixForm(String policy) {
+        Stack<Character> stack = new Stack<>();
+        List<FlowObjectiveCompositionTree> postfix = new ArrayList<>();
+
+        for (int i = 0; i < policy.length(); i++) {
+            Character ch = policy.charAt(i);
+            if (Character.isDigit(ch)) {
+
+                int applicationId = ch - '0';
+                while (i + 1 < policy.length() && Character.isDigit(policy.charAt(i + 1))) {
+                    i++;
+                    applicationId = applicationId * 10 + policy.charAt(i) - '0';
+                }
+
+                postfix.add(new FlowObjectiveCompositionTree((short) applicationId));
+            } else if (ch == '(') {
+                stack.push(ch);
+            } else if (ch == ')') {
+                while (stack.peek() != '(') {
+                    postfix.add(new FlowObjectiveCompositionTree(stack.pop()));
+                }
+                stack.pop();
+            } else {
+                while (!stack.isEmpty() && compareOperatorPriority(stack.peek(), ch)) {
+                    postfix.add(new FlowObjectiveCompositionTree(stack.pop()));
+                }
+                stack.push(ch);
+            }
+        }
+        while (!stack.isEmpty()) {
+            postfix.add(new FlowObjectiveCompositionTree(stack.pop()));
+        }
+
+        return postfix;
+    }
+
+    private static boolean compareOperatorPriority(char peek, char cur) {
+        if (peek == '/' && (cur == '+' || cur == '>' || cur == '/')) {
+            return true;
+        } else if (peek == '>' && (cur == '+' || cur == '>')) {
+            return true;
+        } else if (peek == '+' && cur == '+') {
+            return true;
+        }
+        return false;
+    }
+
+    private static FlowObjectiveCompositionTree buildPolicyTree(List<FlowObjectiveCompositionTree> postfix) {
+        Stack<FlowObjectiveCompositionTree> stack = new Stack<>();
+        for (FlowObjectiveCompositionTree node : postfix) {
+            if (node.operator == FlowObjectiveCompositionManager.PolicyOperator.Application) {
+                stack.push(node);
+            } else {
+                node.rightChild = stack.pop();
+                node.leftChild = stack.pop();
+                stack.push(node);
+            }
+        }
+        return stack.pop();
+    }
+
+    public static Collection<ForwardingObjective> minusForwardingObjectives(Collection<ForwardingObjective> fo1,
+                                                                            Collection<ForwardingObjective> fo2) {
+        Map<Integer, ForwardingObjective> map = new HashMap<>();
+        for (ForwardingObjective fo : fo1) {
+            map.put(fo.id(), fo);
+        }
+        for (ForwardingObjective fo : fo2) {
+            map.remove(fo.id());
+        }
+        return map.values();
+    }
+
+
+}
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardTable.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardTable.java
new file mode 100644
index 0000000..1384bbe
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardTable.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2015 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.flowobjective.impl.composition;
+
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Provides a table to store Forward.
+ */
+public class ForwardTable {
+
+    protected Map<Integer, ForwardingObjective> forwardMap;
+    protected Map<Integer, List<ForwardingObjective>> generatedParentForwardingObjectiveMap;
+
+    public ForwardTable() {
+        this.forwardMap = new HashMap<>();
+        this.generatedParentForwardingObjectiveMap = new HashMap<>();
+    }
+
+    public ForwardUpdateTable updateForward(ForwardingObjective forwardingObjective) {
+        ForwardUpdateTable updates = new ForwardUpdateTable();
+        switch (forwardingObjective.op()) {
+            case ADD:
+                this.forwardMap.put(forwardingObjectiveHash(forwardingObjective), forwardingObjective);
+                this.generatedParentForwardingObjectiveMap
+                        .put(forwardingObjectiveHash(forwardingObjective), new ArrayList<>());
+                updates.addObjectives.add(forwardingObjective);
+                break;
+            case REMOVE:
+                if (this.forwardMap.remove(forwardingObjectiveHash(forwardingObjective)) != null) {
+                    updates.removeObjectives.add(forwardingObjective);
+                }
+                break;
+            default:
+                break;
+        }
+        return updates;
+    }
+
+    public ForwardUpdateTable updateForward(List<ForwardingObjective> forwardingObjectives) {
+        ForwardUpdateTable updates = new ForwardUpdateTable();
+        for (ForwardingObjective forwardingObjective : forwardingObjectives) {
+            updates.addUpdateTable(this.updateForward(forwardingObjective));
+        }
+        return updates;
+    }
+
+    public void addGeneratedParentForwardingObjective(ForwardingObjective child, ForwardingObjective parent) {
+        this.generatedParentForwardingObjectiveMap.get(forwardingObjectiveHash(child)).add(parent);
+    }
+
+    public void deleteGeneratedParentForwardingObjective(List<ForwardingObjective> children) {
+        for (ForwardingObjective fo : children) {
+            this.generatedParentForwardingObjectiveMap.remove(forwardingObjectiveHash(fo));
+        }
+    }
+
+    private List<ForwardingObjective> getGeneratedParentForwardingObjective(ForwardingObjective child) {
+        return this.generatedParentForwardingObjectiveMap.get(forwardingObjectiveHash(child));
+    }
+
+    public List<ForwardingObjective> getGeneratedParentForwardingObjectiveForRemove(ForwardingObjective child) {
+        List<ForwardingObjective> fos = this.generatedParentForwardingObjectiveMap.get(forwardingObjectiveHash(child));
+        List<ForwardingObjective> removeFos = new ArrayList<>();
+        for (ForwardingObjective fo : fos) {
+            removeFos.add(DefaultForwardingObjective.builder()
+                    .fromApp(fo.appId())
+                    .makePermanent()
+                    .withFlag(fo.flag())
+                    .withPriority(fo.priority())
+                    .withSelector(fo.selector())
+                    .withTreatment(fo.treatment())
+                    .remove());
+        }
+        return removeFos;
+    }
+
+    public Collection<ForwardingObjective> getForwardingObjectives() {
+        return this.forwardMap.values();
+    }
+
+    public static int forwardingObjectiveHash(ForwardingObjective forwardingObjective) {
+        return Objects.hash(forwardingObjective.selector(), forwardingObjective.flag(),
+                forwardingObjective.permanent(), forwardingObjective.timeout(),
+                forwardingObjective.appId(), forwardingObjective.priority(),
+                forwardingObjective.nextId(), forwardingObjective.treatment());
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardUpdateTable.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardUpdateTable.java
new file mode 100644
index 0000000..9818cfd
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/ForwardUpdateTable.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2015 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.flowobjective.impl.composition;
+
+import org.onosproject.net.flowobjective.ForwardingObjective;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Provides an update table for Forward.
+ */
+public class ForwardUpdateTable {
+    public List<ForwardingObjective> addObjectives;
+    public List<ForwardingObjective> removeObjectives;
+
+    public ForwardUpdateTable() {
+        this.addObjectives = new ArrayList<>();
+        this.removeObjectives = new ArrayList<>();
+    }
+
+    public void addUpdateTable(ForwardUpdateTable updateTable) {
+        this.addObjectives.addAll(updateTable.addObjectives);
+        this.removeObjectives.addAll(updateTable.removeObjectives);
+    }
+
+    public List<ForwardingObjective> toForwardingObjectiveList() {
+        List<ForwardingObjective> forwardingObjectives = new ArrayList<>();
+        forwardingObjectives.addAll(this.addObjectives);
+        forwardingObjectives.addAll(this.removeObjectives);
+        return forwardingObjectives;
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/NextTable.java b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/NextTable.java
new file mode 100644
index 0000000..e2787ed
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/flowobjective/impl/composition/NextTable.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2015 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.flowobjective.impl.composition;
+
+import org.onosproject.net.flowobjective.NextObjective;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Provides a table to store Next.
+ */
+public class NextTable {
+
+    protected Map<Integer, NextObjective> nextMap;
+
+    public NextTable() {
+        this.nextMap = new HashMap<>();
+    }
+
+    public List<NextObjective> updateNext(NextObjective nextObjective) {
+        List<NextObjective> updates = new ArrayList<>();
+        switch (nextObjective.op()) {
+            case ADD:
+                this.nextMap.put(nextObjective.id(), nextObjective);
+                updates.add(nextObjective);
+                break;
+            case REMOVE:
+                this.nextMap.remove(nextObjective.id());
+                updates.add(nextObjective);
+                break;
+            default:
+                break;
+        }
+        return updates;
+    }
+
+    public List<NextObjective> updateNext(List<NextObjective> nextObjectives) {
+        List<NextObjective> updates = new ArrayList<>();
+        for (NextObjective nextObjective : nextObjectives) {
+            updates.addAll(this.updateNext(nextObjective));
+        }
+        return updates;
+    }
+
+}
diff --git a/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveCompositionTreeTest.java b/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveCompositionTreeTest.java
new file mode 100644
index 0000000..1e898d3
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/flowobjective/impl/FlowObjectiveCompositionTreeTest.java
@@ -0,0 +1,603 @@
+/*
+ * Copyright 2014-2015 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.flowobjective.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test FlowObjectiveCompositionTree.
+ */
+@Ignore
+public class FlowObjectiveCompositionTreeTest {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Before
+    public void setUp() {}
+
+    @After
+    public void tearDown() {}
+
+    /*@Test
+    public void testParallelComposition() {
+        FlowObjectiveCompositionTree policyTree = FlowObjectiveCompositionUtil.parsePolicyString("31+32");
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPSrc(IpPrefix.valueOf("1.0.0.0/24"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder().build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(0)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.1/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(1))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.2/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(2))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder().build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(0)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        System.out.println("---------- Parallel ----------");
+        for (ForwardingObjective fo : policyTree.forwardTable.getForwardingObjectives()) {
+            System.out.println(forwardingObjectiveToString(fo));
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.3/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(3))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+            helper(policyTree, forwardingObjective);
+        }
+
+        System.out.println("---------- Parallel ----------");
+        for (ForwardingObjective fo : policyTree.forwardTable.getForwardingObjectives()) {
+            System.out.println(forwardingObjectiveToString(fo));
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.3/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(3))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .remove();
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPSrc(IpPrefix.valueOf("1.0.0.0/24"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .remove();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder().build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(0)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .remove();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        System.out.println("---------- Parallel ----------");
+        for (ForwardingObjective fo : policyTree.forwardTable.getForwardingObjectives()) {
+            System.out.println(forwardingObjectiveToString(fo));
+        }
+    }
+
+    @Test
+    public void testSequentialComposition() {
+        FlowObjectiveCompositionTree policyTree = FlowObjectiveCompositionUtil.parsePolicyString("31>32");
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPSrc(IpPrefix.valueOf("0.0.0.0/2"))
+                    .matchIPDst(IpPrefix.valueOf("3.0.0.0/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setIpDst(IpAddress.valueOf("2.0.0.1"))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(3)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("3.0.0.0/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setIpDst(IpAddress.valueOf("2.0.0.2"))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder().build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(0)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.1/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(1))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.2/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(2))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder().build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(0)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        System.out.println("---------- Sequential ----------");
+        for (ForwardingObjective fo : policyTree.forwardTable.getForwardingObjectives()) {
+            System.out.println(forwardingObjectiveToString(fo));
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.3/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(3))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPSrc(IpPrefix.valueOf("0.0.0.0/1"))
+                    .matchIPDst(IpPrefix.valueOf("3.0.0.0/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setIpDst(IpAddress.valueOf("2.0.0.3"))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(3)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        System.out.println("---------- Sequential ----------");
+        for (ForwardingObjective fo : policyTree.forwardTable.getForwardingObjectives()) {
+            System.out.println(forwardingObjectiveToString(fo));
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.3/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(3))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .remove();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPSrc(IpPrefix.valueOf("0.0.0.0/1"))
+                    .matchIPDst(IpPrefix.valueOf("3.0.0.0/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setIpDst(IpAddress.valueOf("2.0.0.3"))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(3)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .remove();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        System.out.println("---------- Sequential ----------");
+        for (ForwardingObjective fo : policyTree.forwardTable.getForwardingObjectives()) {
+            System.out.println(forwardingObjectiveToString(fo));
+        }
+    }
+
+    @Test
+    public void testOverrideComposition() {
+        FlowObjectiveCompositionTree policyTree = FlowObjectiveCompositionUtil.parsePolicyString("31/32");
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPSrc(IpPrefix.valueOf("1.0.0.0/32"))
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.1/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(3))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(31, "a"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.1/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(1))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.2/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(2))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+            helper(policyTree, forwardingObjective);
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder().build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder().build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(0)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+
+            helper(policyTree, forwardingObjective);
+        }
+
+        System.out.println("---------- Override ----------");
+        for (ForwardingObjective fo : policyTree.forwardTable.getForwardingObjectives()) {
+            System.out.println(forwardingObjectiveToString(fo));
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.3/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(3))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .add();
+            helper(policyTree, forwardingObjective);
+        }
+
+        System.out.println("---------- Override ----------");
+        for (ForwardingObjective fo : policyTree.forwardTable.getForwardingObjectives()) {
+            System.out.println(forwardingObjectiveToString(fo));
+        }
+
+        {
+            TrafficSelector selector = DefaultTrafficSelector.builder()
+                    .matchIPDst(IpPrefix.valueOf("2.0.0.3/32"))
+                    .build();
+
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .setOutput(PortNumber.portNumber(3))
+                    .build();
+
+            ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder()
+                    .fromApp(new DefaultApplicationId(32, "b"))
+                    .makePermanent()
+                    .withFlag(ForwardingObjective.Flag.VERSATILE)
+                    .withPriority(1)
+                    .withSelector(selector)
+                    .withTreatment(treatment)
+                    .remove();
+            helper(policyTree, forwardingObjective);
+        }
+
+        System.out.println("---------- Override ----------");
+        for (ForwardingObjective fo : policyTree.forwardTable.getForwardingObjectives()) {
+            System.out.println(forwardingObjectiveToString(fo));
+        }
+    }
+
+    private void helper(FlowObjectiveCompositionTree policyTree, ForwardingObjective forwardingObjective) {
+        log.info("before composition");
+        log.info("\t{}", forwardingObjectiveToString(forwardingObjective));
+        List<ForwardingObjective> forwardingObjectives
+                = policyTree.updateForward(forwardingObjective);
+        log.info("after composition");
+        for (ForwardingObjective fo : forwardingObjectives) {
+            log.info("\t{}", forwardingObjectiveToString(fo));
+        }
+    }*/
+}
