diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentExtensionService.java b/core/api/src/main/java/org/onosproject/net/intent/IntentExtensionService.java
index b4d40c9..f36b356 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/IntentExtensionService.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentExtensionService.java
@@ -48,4 +48,37 @@
      * @return the set of compiler bindings
      */
     Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers();
+
+    /**
+     * Registers the specific installer for the given intent class.
+     *
+     * @param cls intent class
+     * @param installer intent installer
+     * @param <T> the type of intent
+     */
+     <T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer);
+
+    /**
+     * Unregisters the installer for the specific intent class.
+     *
+     * @param cls intent class
+     * @param <T> the type of intent
+     */
+    <T extends Intent> void unregisterInstaller(Class<T> cls);
+
+    /**
+     * Returns immutable set of binding of currently registered intent installers.
+     *
+     * @return the set of installer bindings
+     */
+    Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers();
+
+    /**
+     * Returns the installer for specific installable intent.
+     *
+     * @param cls the type of intent
+     * @param <T> the type of intent
+     * @return the installer for specific installable intent
+     */
+    <T extends Intent> IntentInstaller<T> getInstaller(Class<T> cls);
 }
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentInstallCoordinator.java b/core/api/src/main/java/org/onosproject/net/intent/IntentInstallCoordinator.java
new file mode 100644
index 0000000..6ba0935
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentInstallCoordinator.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent;
+
+/**
+ * Contact point for installers to report progress of intent installation and to
+ * update intent-specific status and context appropriately.
+ */
+public interface IntentInstallCoordinator {
+    /**
+     * Handles success state for an Intent operation context.
+     *
+     * @param context the Intent operation context
+     */
+    void intentInstallSuccess(IntentOperationContext context);
+
+    /**
+     * Handles failed state for an Intent operation context.
+     *
+     * @param context the Intent operation context
+     */
+    void intentInstallFailed(IntentOperationContext context);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentInstallationContext.java b/core/api/src/main/java/org/onosproject/net/intent/IntentInstallationContext.java
new file mode 100644
index 0000000..3656c16
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentInstallationContext.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+
+import java.util.Optional;
+import java.util.Set;
+
+/**
+ * Installation context for a high level Intent.
+ * Records pending and error operation contexts of installable Intents for the
+ * high level Intent.
+ */
+public class IntentInstallationContext {
+    private IntentData toUninstall;
+    private IntentData toInstall;
+    private Set<IntentOperationContext> pendingContexts = Sets.newConcurrentHashSet();
+    private Set<IntentOperationContext> errorContexts = Sets.newConcurrentHashSet();
+
+    /**
+     * Creates an Intent installation context by given information.
+     *
+     * @param toUninstall the Intent to uninstall
+     * @param toInstall the Intent to install
+     */
+    public IntentInstallationContext(IntentData toUninstall, IntentData toInstall) {
+        this.toUninstall = toUninstall;
+        this.toInstall = toInstall;
+    }
+
+    /**
+     * Removes a pending operation context.
+     *
+     * @param context the operation context to be added
+     */
+    public void removePendingContext(IntentOperationContext context) {
+        this.pendingContexts.remove(context);
+    }
+
+    /**
+     * Adds a pending context.
+     *
+     * @param context the operation context to be added
+     */
+    public void addPendingContext(IntentOperationContext context) {
+        this.pendingContexts.add(context);
+    }
+
+    /**
+     * Adds an error context.
+     *
+     * @param context the error context to be added.
+     */
+    public void addErrorContext(IntentOperationContext context) {
+        this.errorContexts.add(context);
+    }
+
+    /**
+     * Retrieves the pending contexts.
+     *
+     * @return the pending contexts
+     */
+    public Set<IntentOperationContext> pendingContexts() {
+        return ImmutableSet.copyOf(pendingContexts);
+    }
+
+    /**
+     * Retrieves the error contexts.
+     *
+     * @return the error contexts
+     */
+    public Set<IntentOperationContext> errorContexts() {
+        return ImmutableSet.copyOf(errorContexts);
+    }
+
+    /**
+     * Check if pending context is empty.
+     *
+     * @return true if pending contexts is empty; false otherwise
+     */
+    public synchronized boolean isPendingContextsEmpty() {
+        return pendingContexts.isEmpty();
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("pendingContexts", pendingContexts)
+                .add("errorContexts", errorContexts)
+                .toString();
+    }
+
+    /**
+     * Retrieves the Intent data which to be uninstalled.
+     *
+     * @return the Intent data; empty value if not exists
+     */
+    public Optional<IntentData> toUninstall() {
+        return Optional.ofNullable(toUninstall);
+    }
+
+    /**
+     * Retrieves the Intent data which to be installed.
+     *
+     * @return the Intent data; empty value if not exists
+     */
+    public Optional<IntentData> toInstall() {
+        return Optional.ofNullable(toInstall);
+    }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentInstaller.java b/core/api/src/main/java/org/onosproject/net/intent/IntentInstaller.java
new file mode 100644
index 0000000..ac41865
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentInstaller.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent;
+
+/**
+ * Manage installation process for specific installable Intents.
+ */
+public interface IntentInstaller<T extends Intent> {
+
+    /**
+     * The installation direction.
+     */
+    enum Direction {
+        /**
+         * Direction for adding any installable objects(flows, configs...).
+         */
+        ADD,
+
+        /**
+         * Direction for removing any installable objects(flows, configs...).
+         */
+        REMOVE
+    }
+
+    /**
+     * Applies an Intent operation context.
+     *
+     * @param context the Intent operation context
+     */
+    void apply(IntentOperationContext<T> context);
+}
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentOperationContext.java b/core/api/src/main/java/org/onosproject/net/intent/IntentOperationContext.java
new file mode 100644
index 0000000..e36d7ec
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentOperationContext.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+/**
+ * Operation context for installable Intent.
+ *
+ * @param <T> the type of installable Intent
+ */
+public class IntentOperationContext<T extends Intent> {
+    private IntentInstallationContext intentInstallationContext;
+    private List<T> intentsToUninstall;
+    private List<T> intentsToInstall;
+
+    /**
+     * Creates an operation context.
+     *
+     * @param intentsToUninstall the Intents to uninstall
+     * @param intentsToInstall the Intents to install
+     * @param intentInstallationContext the high level Intent installation information
+     */
+    public IntentOperationContext(List<T> intentsToUninstall, List<T> intentsToInstall,
+                                  IntentInstallationContext intentInstallationContext) {
+        this.intentsToUninstall = Lists.newArrayList(intentsToUninstall);
+        this.intentsToInstall = Lists.newArrayList(intentsToInstall);
+        this.intentInstallationContext = intentInstallationContext;
+    }
+
+    /**
+     * Retrieves installable Intents to uninstall.
+     *
+     * @return the Intents to uninstall
+     */
+    public List<T> intentsToUninstall() {
+        return intentsToUninstall;
+    }
+
+    /**
+     * Retrieves installable Intents to install.
+     *
+     * @return the Intents to install
+     */
+    public List<T> intentsToInstall() {
+        return intentsToInstall;
+    }
+
+    /**
+     * Retrieves high level Intent installation information.
+     *
+     * @return the high level Intent installation information
+     */
+    public IntentInstallationContext intentInstallationContext() {
+        return intentInstallationContext;
+    }
+
+    /**
+     * Retrieves high level Intent data to uninstall.
+     *
+     * @return high level Intent data to uninstall
+     */
+    public Optional<IntentData> toUninstall() {
+        return intentInstallationContext.toUninstall();
+    }
+
+    /**
+     * Retrieves high level Intent data to install.
+     *
+     * @return high level Intent data to install
+     */
+    public Optional<IntentData> toInstall() {
+        return intentInstallationContext.toInstall();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof IntentOperationContext)) {
+            return false;
+        }
+
+        IntentOperationContext that = (IntentOperationContext) obj;
+        return Objects.equals(intentsToInstall, that.intentsToInstall) &&
+                Objects.equals(intentsToUninstall, that.intentsToUninstall) &&
+                Objects.equals(intentInstallationContext, intentInstallationContext);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(intentsToInstall,
+                            intentsToUninstall,
+                            intentInstallationContext);
+    }
+}
diff --git a/core/api/src/test/java/org/onosproject/net/intent/FakeIntentManager.java b/core/api/src/test/java/org/onosproject/net/intent/FakeIntentManager.java
index 02e8975..b37d8c5 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/FakeIntentManager.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/FakeIntentManager.java
@@ -15,6 +15,8 @@
  */
 package org.onosproject.net.intent;
 
+import com.google.common.collect.ImmutableMap;
+
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
@@ -37,6 +39,7 @@
     private final Set<IntentListener> listeners = new HashSet<>();
 
     private final Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> compilers = new HashMap<>();
+    private final Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> installers = new HashMap<>();
 
     private final ExecutorService executor = Executors.newSingleThreadExecutor();
     private final List<IntentException> exceptions = new ArrayList<>();
@@ -247,6 +250,26 @@
         return Collections.unmodifiableMap(compilers);
     }
 
+    @Override
+    public <T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
+        installers.put(cls, installer);
+    }
+
+    @Override
+    public <T extends Intent> void unregisterInstaller(Class<T> cls) {
+        installers.remove(cls);
+    }
+
+    @Override
+    public Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers() {
+        return ImmutableMap.copyOf(installers);
+    }
+
+    @Override
+    public <T extends Intent> IntentInstaller<T> getInstaller(Class<T> cls) {
+        return (IntentInstaller<T>) installers.get(cls);
+    }
+
     private void registerSubclassCompilerIfNeeded(Intent intent) {
         if (!compilers.containsKey(intent.getClass())) {
             Class<?> cls = intent.getClass();
diff --git a/core/api/src/test/java/org/onosproject/net/intent/IntentExtensionServiceAdapter.java b/core/api/src/test/java/org/onosproject/net/intent/IntentExtensionServiceAdapter.java
new file mode 100644
index 0000000..f9fe65b
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/net/intent/IntentExtensionServiceAdapter.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent;
+
+import java.util.Map;
+
+/**
+ * Test adapter for Intent extension service.
+ */
+public class IntentExtensionServiceAdapter implements IntentExtensionService {
+    @Override
+    public <T extends Intent> void registerCompiler(Class<T> cls, IntentCompiler<T> compiler) {
+
+    }
+
+    @Override
+    public <T extends Intent> void unregisterCompiler(Class<T> cls) {
+
+    }
+
+    @Override
+    public Map<Class<? extends Intent>, IntentCompiler<? extends Intent>> getCompilers() {
+        return null;
+    }
+
+    @Override
+    public <T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
+
+    }
+
+    @Override
+    public <T extends Intent> void unregisterInstaller(Class<T> cls) {
+
+    }
+
+    @Override
+    public Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers() {
+        return null;
+    }
+
+    @Override
+    public <T extends Intent> IntentInstaller<T> getInstaller(Class<T> cls) {
+        return null;
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/InstallCoordinator.java b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallCoordinator.java
new file mode 100644
index 0000000..d5eb1fd
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallCoordinator.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl;
+
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentInstallationContext;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentInstaller;
+import org.onosproject.net.intent.IntentStore;
+import org.slf4j.Logger;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.onosproject.net.intent.IntentState.*;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implementation of IntentInstallCoordinator.
+ */
+public class InstallCoordinator {
+    private static final String INSTALLER_NOT_FOUND = "Intent installer not found, Intent: {}";
+    private final Logger log = getLogger(IntentManager.class);
+
+    private InstallerRegistry installerRegistry;
+    private IntentStore intentStore;
+
+    /**
+     * Creates an InstallCoordinator.
+     *
+     * @param installerRegistry the installer registry
+     * @param intentStore the Intent store
+     */
+    public InstallCoordinator(InstallerRegistry installerRegistry,
+                              IntentStore intentStore) {
+        this.installerRegistry = installerRegistry;
+        this.intentStore = intentStore;
+    }
+
+    /**
+     * Applies Intent data to be uninstalled and to be installed.
+     *
+     * @param toUninstall Intent data to be uninstalled
+     * @param toInstall Intent data to be installed
+     */
+    public void installIntents(Optional<IntentData> toUninstall, Optional<IntentData> toInstall) {
+        // If no any Intents to be uninstalled or installed, ignore it.
+        if (!toUninstall.isPresent() && !toInstall.isPresent()) {
+            return;
+        }
+
+        // Classify installable Intents to different installers.
+        ArrayListMultimap<IntentInstaller, Intent> uninstallInstallers;
+        ArrayListMultimap<IntentInstaller, Intent> installInstallers;
+        Set<IntentInstaller> allInstallers = Sets.newHashSet();
+
+        if (toUninstall.isPresent()) {
+            uninstallInstallers = getInstallers(toUninstall.get());
+            allInstallers.addAll(uninstallInstallers.keySet());
+        } else {
+            uninstallInstallers = ArrayListMultimap.create();
+        }
+
+        if (toInstall.isPresent()) {
+            installInstallers = getInstallers(toInstall.get());
+            allInstallers.addAll(installInstallers.keySet());
+        } else {
+            installInstallers = ArrayListMultimap.create();
+        }
+
+        // Generates an installation context for the high level Intent.
+        IntentInstallationContext installationContext =
+                new IntentInstallationContext(toUninstall.orElse(null), toInstall.orElse(null));
+
+        //Generates different operation context for different installable Intents.
+        Map<IntentInstaller, IntentOperationContext> contexts = Maps.newHashMap();
+        allInstallers.forEach(installer -> {
+            List<Intent> intentsToUninstall = uninstallInstallers.get(installer);
+            List<Intent> intentsToInstall = installInstallers.get(installer);
+
+            // Connect context to high level installation context
+            IntentOperationContext context =
+                    new IntentOperationContext(intentsToUninstall, intentsToInstall,
+                                               installationContext);
+            installationContext.addPendingContext(context);
+            contexts.put(installer, context);
+        });
+
+        // Apply contexts to installers
+        contexts.forEach((installer, context) -> {
+            installer.apply(context);
+        });
+    }
+
+    /**
+     * Generates a mapping for installable Intents to installers.
+     *
+     * @param intentData the Intent data which contains installable Intents
+     * @return the mapping for installable Intents to installers
+     */
+    private ArrayListMultimap<IntentInstaller, Intent> getInstallers(IntentData intentData) {
+        ArrayListMultimap<IntentInstaller, Intent> intentInstallers = ArrayListMultimap.create();
+        intentData.installables().forEach(intent -> {
+            IntentInstaller installer = installerRegistry.getInstaller(intent.getClass());
+            if (installer != null) {
+                intentInstallers.put(installer, intent);
+            } else {
+                log.warn(INSTALLER_NOT_FOUND, intent);
+            }
+        });
+        return intentInstallers;
+    }
+
+    /**
+     * Handles success operation context.
+     *
+     * @param context the operation context
+     */
+    public void success(IntentOperationContext context) {
+        IntentInstallationContext intentInstallationContext =
+                context.intentInstallationContext();
+        intentInstallationContext.removePendingContext(context);
+
+        if (intentInstallationContext.isPendingContextsEmpty()) {
+            finish(intentInstallationContext);
+        }
+    }
+
+    /**
+     * Handles failed operation context.
+     *
+     * @param context the operation context
+     */
+    public void failed(IntentOperationContext context) {
+        IntentInstallationContext intentInstallationContext =
+                context.intentInstallationContext();
+        intentInstallationContext.addErrorContext(context);
+        intentInstallationContext.removePendingContext(context);
+
+        if (intentInstallationContext.isPendingContextsEmpty()) {
+            finish(intentInstallationContext);
+        }
+    }
+
+    /**
+     * Completed the installation context and update the Intent store.
+     *
+     * @param intentInstallationContext the installation context
+     */
+    private void finish(IntentInstallationContext intentInstallationContext) {
+        Set<IntentOperationContext> errCtxs = intentInstallationContext.errorContexts();
+        Optional<IntentData> toUninstall = intentInstallationContext.toUninstall();
+        Optional<IntentData> toInstall = intentInstallationContext.toInstall();
+
+        // Intent install success
+        if (errCtxs == null || errCtxs.isEmpty()) {
+            if (toInstall.isPresent()) {
+                IntentData installData = toInstall.get();
+                log.debug("Completed installing: {}", installData.key());
+                installData.setState(INSTALLED);
+                intentStore.write(installData);
+            } else if (toUninstall.isPresent()) {
+                IntentData uninstallData = toUninstall.get();
+                log.debug("Completed withdrawing: {}", uninstallData.key());
+                switch (uninstallData.request()) {
+                    case INSTALL_REQ:
+                        log.warn("{} was requested to withdraw during installation?",
+                                 uninstallData.intent());
+                        uninstallData.setState(FAILED);
+                        break;
+                    case WITHDRAW_REQ:
+                    default: //TODO "default" case should not happen
+                        uninstallData.setState(WITHDRAWN);
+                        break;
+                }
+                // Intent has been withdrawn; we can clear the installables
+                intentStore.write(new IntentData(uninstallData, Collections.emptyList()));
+            }
+        } else {
+            // if toInstall was cause of error, then recompile (manage/increment counter, when exceeded -> CORRUPT)
+            if (toInstall.isPresent()) {
+                IntentData installData = toInstall.get();
+                installData.setState(CORRUPT);
+                installData.incrementErrorCount();
+                intentStore.write(installData);
+            }
+            // if toUninstall was cause of error, then CORRUPT (another job will clean this up)
+            if (toUninstall.isPresent()) {
+                IntentData uninstallData = toUninstall.get();
+                uninstallData.setState(CORRUPT);
+                uninstallData.incrementErrorCount();
+                intentStore.write(uninstallData);
+            }
+        }
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/InstallerRegistry.java b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallerRegistry.java
new file mode 100644
index 0000000..db5becc
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/InstallerRegistry.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentInstaller;
+
+import java.util.Map;
+
+/**
+ * The local registry for Intent installer.
+ */
+public class InstallerRegistry {
+    private final Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> installers;
+
+    public InstallerRegistry() {
+        installers = Maps.newConcurrentMap();
+    }
+
+    /**
+     * Registers the specific installer for the given intent class.
+     *
+     * @param cls intent class
+     * @param installer intent installer
+     * @param <T> the type of intent
+     */
+    public <T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
+        installers.put(cls, installer);
+    }
+
+    /**
+     * Unregisters the installer for the specific intent class.
+     *
+     * @param cls intent class
+     * @param <T> the type of intent
+     */
+    public <T extends Intent> void unregisterInstaller(Class<T> cls) {
+        installers.remove(cls);
+    }
+
+    /**
+     * Returns immutable set of binding of currently registered intent installers.
+     *
+     * @return the set of installer bindings
+     */
+    public Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers() {
+        return ImmutableMap.copyOf(installers);
+    }
+
+    /**
+     * Get an Intent installer by given Intent type.
+     *
+     * @param cls the Intent type
+     * @param <T> the Intent type
+     * @return the Intent installer of the Intent type if exists; null otherwise
+     */
+    public <T extends Intent> IntentInstaller<T> getInstaller(Class<T> cls) {
+        return (IntentInstaller<T>) installers.get(cls);
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentInstaller.java
deleted file mode 100644
index d0928ce..0000000
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentInstaller.java
+++ /dev/null
@@ -1,1051 +0,0 @@
-/*
- * Copyright 2016-present Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.onosproject.net.intent.impl;
-
-import com.google.common.collect.ImmutableSet;
-import com.google.common.annotations.Beta;
-import com.google.common.base.MoreObjects;
-import com.google.common.base.MoreObjects.ToStringHelper;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-import org.apache.commons.lang3.tuple.Pair;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.behaviour.protection.ProtectedTransportEndpointDescription;
-import org.onosproject.net.behaviour.protection.ProtectionConfig;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.domain.DomainIntent;
-import org.onosproject.net.domain.DomainIntentOperations;
-import org.onosproject.net.domain.DomainIntentOperationsContext;
-import org.onosproject.net.domain.DomainIntentService;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleOperations;
-import org.onosproject.net.flow.FlowRuleOperationsContext;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flowobjective.FilteringObjective;
-import org.onosproject.net.flowobjective.FlowObjectiveService;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.NextObjective;
-import org.onosproject.net.flowobjective.Objective;
-import org.onosproject.net.flowobjective.ObjectiveContext;
-import org.onosproject.net.flowobjective.ObjectiveError;
-import org.onosproject.net.intent.FlowObjectiveIntent;
-import org.onosproject.net.intent.FlowRuleIntent;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.IntentData;
-import org.onosproject.net.intent.IntentStore;
-import org.onosproject.net.intent.ProtectionEndpointIntent;
-import org.slf4j.Logger;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
-import static org.onosproject.net.flowobjective.ObjectiveError.INSTALLATIONTHRESHOLDEXCEEDED;
-import static org.onosproject.net.intent.IntentState.*;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Auxiliary entity responsible for installing the intents into the environment.
- */
-class IntentInstaller {
-
-    private static final Logger log = getLogger(IntentInstaller.class);
-    private static final long OBJECTIVE_RETRY_THRESHOLD = 5;
-
-    private IntentStore store;
-    private ObjectiveTrackerService trackerService;
-    private FlowRuleService flowRuleService;
-    private FlowObjectiveService flowObjectiveService;
-    private NetworkConfigService networkConfigService;
-    private DomainIntentService domainIntentService;
-
-    private enum Direction {
-        ADD,
-        REMOVE
-    }
-
-    /**
-     * Initializes the installer with references to required services.
-     *
-     * @param intentStore          intent store
-     * @param trackerService       objective tracking service
-     * @param flowRuleService      flow rule service
-     * @param flowObjectiveService flow objective service
-     * @param networkConfigService network configuration service
-     * @param domainIntentService  domain intent service
-     */
-    void init(IntentStore intentStore, ObjectiveTrackerService trackerService,
-              FlowRuleService flowRuleService, FlowObjectiveService flowObjectiveService,
-              NetworkConfigService networkConfigService, DomainIntentService domainIntentService) {
-
-        this.store = intentStore;
-        this.trackerService = trackerService;
-        //TODO Various services should be plugged to the intent installer instead of being hardcoded
-        this.flowRuleService = flowRuleService;
-        this.flowObjectiveService = flowObjectiveService;
-        this.networkConfigService = networkConfigService;
-        this.domainIntentService = domainIntentService;
-    }
-
-    // FIXME: Intent Manager should have never become dependent on a specific intent type(s).
-    // This will be addressed in intent domains work; not now.
-
-    /**
-     * Applies the specified intent updates to the environment by uninstalling
-     * and installing the intents and updating the store references appropriately.
-     *
-     * @param toUninstall optional intent to uninstall
-     * @param toInstall   optional intent to install
-     */
-    void apply(Optional<IntentData> toUninstall, Optional<IntentData> toInstall) {
-        // Hook for handling success at intent installation level.
-        Consumer<IntentInstallationContext> successConsumer = (ctx) -> {
-            if (toInstall.isPresent()) {
-                IntentData installData = toInstall.get();
-                log.debug("Completed installing: {}", installData.key());
-                installData.setState(INSTALLED);
-                store.write(installData);
-            } else if (toUninstall.isPresent()) {
-                IntentData uninstallData = toUninstall.get();
-                log.debug("Completed withdrawing: {}", uninstallData.key());
-                switch (uninstallData.request()) {
-                    case INSTALL_REQ:
-                        // illegal state?
-                        log.warn("{} was requested to withdraw during installation?",
-                                 uninstallData.intent());
-                        uninstallData.setState(FAILED);
-                        break;
-                    case WITHDRAW_REQ:
-                    default: //TODO "default" case should not happen
-                        uninstallData.setState(WITHDRAWN);
-                        break;
-                }
-                // Intent has been withdrawn; we can clear the installables
-                store.write(new IntentData(uninstallData, Collections.emptyList()));
-            }
-        };
-
-        // Hook for handling errors at intent installation level
-        Consumer<IntentInstallationContext> errorConsumer = (ctx) -> {
-            // if toInstall was cause of error, then recompile (manage/increment counter, when exceeded -> CORRUPT)
-            if (toInstall.isPresent()) {
-                IntentData installData = toInstall.get();
-                installData.setState(CORRUPT);
-                installData.incrementErrorCount();
-                store.write(installData);
-            }
-            // if toUninstall was cause of error, then CORRUPT (another job will clean this up)
-            if (toUninstall.isPresent()) {
-                IntentData uninstallData = toUninstall.get();
-                uninstallData.setState(CORRUPT);
-                uninstallData.incrementErrorCount();
-                store.write(uninstallData);
-            }
-        };
-
-        // Hooks at operation level
-        Consumer<OperationContext> successOperationConsumer = (ctx) -> {
-            ctx.intentContext.finishContext(ctx);
-        };
-        Consumer<OperationContext> errorOperationConsumer = (ctx) -> {
-            if (ctx.toInstall.isPresent()) {
-                IntentData installData = toInstall.get();
-                log.warn("Failed installation operation for: {} {} due to {}",
-                         installData.key(), installData.intent(), ctx.error());
-            }
-            if (ctx.toUninstall.isPresent()) {
-                IntentData uninstallData = toUninstall.get();
-                log.warn("Failed withdrawal operation for: {} {} due to {}",
-                         uninstallData.key(), uninstallData.intent(), ctx.error());
-            }
-            ctx.intentContext.handleError(ctx);
-        };
-
-        // Create a context for tracking the backing operations for applying
-        // the intents to the environment.
-        IntentInstallationContext intentContext =
-                new IntentInstallationContext(successConsumer, errorConsumer);
-        Set<OperationContext> contexts = createContext(intentContext, toUninstall, toInstall);
-        intentContext.pendingContexts = contexts;
-        contexts.forEach(ctx -> {
-            ctx.prepare(toUninstall, toInstall, successOperationConsumer, errorOperationConsumer);
-            ctx.apply();
-        });
-    }
-
-    // Context for applying and tracking multiple kinds of operation contexts
-    // related to specific intent data.
-    private final class IntentInstallationContext {
-        private Set<OperationContext> pendingContexts = Sets.newHashSet();
-        private Set<OperationContext> errorContexts = Sets.newHashSet();
-        private Consumer<IntentInstallationContext> successConsumer;
-        private Consumer<IntentInstallationContext> errorConsumer;
-
-        private IntentInstallationContext(Consumer<IntentInstallationContext> succesConsumer,
-                                          Consumer<IntentInstallationContext> errorConsumer) {
-            this.successConsumer = succesConsumer;
-            this.errorConsumer = errorConsumer;
-        }
-
-        private void handleError(OperationContext ctx) {
-            errorContexts.add(ctx);
-            finishContext(ctx);
-        }
-
-        private void finishContext(OperationContext ctx) {
-            synchronized (pendingContexts) {
-                pendingContexts.remove(ctx);
-                if (pendingContexts.isEmpty()) {
-                    if (errorContexts.isEmpty()) {
-                        successConsumer.accept(IntentInstallationContext.this);
-                    } else {
-                        errorConsumer.accept(IntentInstallationContext.this);
-                    }
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            return MoreObjects.toStringHelper(this)
-                    .add("pendingContexts", pendingContexts)
-                    .add("errorContexts", errorContexts)
-                    .toString();
-        }
-    }
-
-    // --- Utilities to support FlowRule vs. FlowObjective vs. DomainIntent behavior ----
-
-    // Creates the set of contexts appropriate for tracking operations of the
-    // the specified intents.
-    private Set<OperationContext> createContext(IntentInstallationContext intentContext,
-                                                Optional<IntentData> toUninstall,
-                                                Optional<IntentData> toInstall) {
-
-        Set<OperationContext> contexts = Sets.newConcurrentHashSet();
-        if (isInstallable(toUninstall, toInstall, FlowRuleIntent.class)) {
-            contexts.add(new FlowRuleOperationContext(intentContext));
-        }
-        if (isInstallable(toUninstall, toInstall, FlowObjectiveIntent.class)) {
-            contexts.add(new FlowObjectiveOperationContext(intentContext));
-        }
-        if (isInstallable(toUninstall, toInstall, ProtectionEndpointIntent.class)) {
-            contexts.add(new ProtectionConfigOperationContext(intentContext));
-        }
-        if (isInstallable(toUninstall, toInstall, DomainIntent.class)) {
-            contexts.add(new DomainIntentOperationContext(intentContext));
-        }
-
-        if (contexts.isEmpty()) {
-            log.warn("{} did not contain installable Intents", intentContext);
-            return ImmutableSet.of(new ErrorContext(intentContext));
-        }
-
-        return contexts;
-    }
-
-    /**
-     * Tests if one of {@code toUninstall} or {@code toInstall} contains
-     * installable Intent of type specified by {@code intentClass}.
-     *
-     * @param toUninstall IntentData to test
-     * @param toInstall   IntentData to test
-     * @param intentClass installable Intent class
-     * @return true if at least one of IntentData contains installable specified.
-     */
-    private boolean isInstallable(Optional<IntentData> toUninstall, Optional<IntentData> toInstall,
-                                  Class<? extends Intent> intentClass) {
-
-        return Stream.concat(toInstall
-                              .map(IntentData::installables)
-                              .map(Collection::stream)
-                              .orElse(Stream.empty()),
-                             toUninstall
-                              .map(IntentData::installables)
-                              .map(Collection::stream)
-                              .orElse(Stream.empty()))
-                .anyMatch(i -> intentClass.isAssignableFrom(i.getClass()));
-    }
-
-    // Base context for applying and tracking operations related to installable intents.
-    private abstract class OperationContext {
-        protected IntentInstallationContext intentContext;
-        protected Optional<IntentData> toUninstall;
-        protected Optional<IntentData> toInstall;
-        /**
-         * Implementation of {@link OperationContext} should call this on success.
-         */
-        protected Consumer<OperationContext> successConsumer;
-        /**
-         * Implementation of {@link OperationContext} should call this on error.
-         */
-        protected Consumer<OperationContext> errorConsumer;
-
-        protected OperationContext(IntentInstallationContext context) {
-            this.intentContext = context;
-        }
-
-        /**
-         * Applies the Intents specified by
-         * {@link #prepareIntents(List, Direction)} call(s) prior to this call.
-         */
-        abstract void apply();
-
-        /**
-         * Returns error state of the context.
-         * <p>
-         * Used for error logging purpose.
-         * Returned Object should have reasonable toString() implementation.
-         * @return context state, describing current error state
-         */
-        abstract Object error();
-
-        /**
-         * Prepares Intent(s) to {@link #apply() apply} in this operation.
-         * <p>
-         * Intents specified by {@code intentsToApply} in a single call
-         * can be applied to the Devices in arbitrary order.
-         * But group of Intents specified in consecutive {@link #prepareIntents(List, Direction)}
-         * calls must be applied in order. (e.g., guarded by barrier)
-         *
-         * @param intentsToApply {@link Intent}s to apply
-         * @param direction of operation
-         */
-        abstract void prepareIntents(List<Intent> intentsToApply, Direction direction);
-
-        void prepare(Optional<IntentData> toUninstall, Optional<IntentData> toInstall,
-                     Consumer<OperationContext> successConsumer,
-                     Consumer<OperationContext> errorConsumer) {
-            this.toUninstall = toUninstall;
-            this.toInstall = toInstall;
-            this.successConsumer = successConsumer;
-            this.errorConsumer = errorConsumer;
-            prepareIntentData(toUninstall, toInstall);
-        }
-
-        private void prepareIntentData(Optional<IntentData> uninstallData,
-                                       Optional<IntentData> installData) {
-            if (!installData.isPresent() && !uninstallData.isPresent()) {
-                return;
-            } else if (!installData.isPresent()) {
-                prepareIntentData(uninstallData, Direction.REMOVE);
-            } else if (!uninstallData.isPresent()) {
-                prepareIntentData(installData, Direction.ADD);
-            } else {
-                IntentData uninstall = uninstallData.get();
-                IntentData install = installData.get();
-                List<Intent> uninstallIntents = Lists.newArrayList(uninstall.installables());
-                List<Intent> installIntents = Lists.newArrayList(install.installables());
-
-                checkState(uninstallIntents.stream().allMatch(this::isSupported),
-                           "Unsupported installable intents detected: %s", uninstallIntents);
-                checkState(installIntents.stream().allMatch(this::isSupported),
-                           "Unsupported installable intents detected: %s", installIntents);
-
-                //TODO: Filter FlowObjective intents
-                // Filter out same intents and intents with same flow rules
-                Iterator<Intent> iterator = installIntents.iterator();
-                while (iterator.hasNext()) {
-                    Intent installIntent = iterator.next();
-                    uninstallIntents.stream().filter(uIntent -> {
-                        if (uIntent.equals(installIntent)) {
-                            return true;
-                        } else if (uIntent instanceof FlowRuleIntent && installIntent instanceof FlowRuleIntent) {
-                            //FIXME we can further optimize this by doing the filtering on a flow-by-flow basis
-                            //      (direction can be implied from intent state)
-                            return !flowRuleIntentChanged(((FlowRuleIntent) uIntent),
-                                                          ((FlowRuleIntent) installIntent));
-                        } else {
-                            return false;
-                        }
-                    }).findFirst().ifPresent(common -> {
-                        uninstallIntents.remove(common);
-                        if (INSTALLED.equals(uninstall.state())) {
-                            // only remove the install intent if the existing
-                            // intent (i.e. the uninstall one) is already
-                            // installed or installing
-                            iterator.remove();
-                        }
-                    });
-                }
-
-                final IntentData newUninstall = new IntentData(uninstall, uninstallIntents);
-                final IntentData newInstall = new IntentData(install, installIntents);
-
-                trackerService.removeTrackedResources(newUninstall.key(), newUninstall.intent().resources());
-                uninstallIntents.forEach(installable ->
-                                                 trackerService.removeTrackedResources(newUninstall.intent().key(),
-                                                                                       installable.resources()));
-                trackerService.addTrackedResources(newInstall.key(), newInstall.intent().resources());
-                installIntents.forEach(installable ->
-                                               trackerService.addTrackedResources(newInstall.key(),
-                                                                                  installable.resources()));
-                prepareIntents(uninstallIntents, Direction.REMOVE);
-                prepareIntents(installIntents, Direction.ADD);
-            }
-        }
-
-        /**
-         * Determines whether there is any flow rule changed
-         * (i.e., different set of flow rules or different treatments)
-         * between FlowRuleIntents to be uninstalled and to be installed.
-         *
-         * @param uninstallIntent FlowRuleIntent to uninstall
-         * @param installIntent FlowRuleIntent to install
-         * @return true if flow rules which to be uninstalled
-         * contains all flow rules which to be installed.
-         */
-        private boolean flowRuleIntentChanged(FlowRuleIntent uninstallIntent,
-                                              FlowRuleIntent installIntent) {
-            Collection<FlowRule> flowRulesToUninstall = uninstallIntent.flowRules();
-            Collection<FlowRule> flowRulesToInstall = installIntent.flowRules();
-
-            // Check if any flow rule changed
-            for (FlowRule flowRuleToInstall : flowRulesToInstall) {
-                if (flowRulesToUninstall.stream().noneMatch(flowRuleToInstall::exactMatch)) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        /**
-         * Applies the specified intent data, if present, to the network using the
-         * specified context.
-         *
-         * @param intentData optional intent data; no-op if not present
-         * @param direction  indicates adding or removal
-         */
-        private void prepareIntentData(Optional<IntentData> intentData, Direction direction) {
-            if (!intentData.isPresent()) {
-                return;
-            }
-
-            IntentData data = intentData.get();
-            List<Intent> intentsToApply = data.installables();
-            checkState(intentsToApply.stream().allMatch(this::isSupported),
-                       "Unsupported installable intents detected: %s", intentsToApply);
-
-            if (direction == Direction.ADD) {
-                trackerService.addTrackedResources(data.key(), data.intent().resources());
-                intentsToApply.forEach(installable ->
-                                               trackerService.addTrackedResources(data.key(),
-                                                                                  installable.resources()));
-            } else {
-                trackerService.removeTrackedResources(data.key(), data.intent().resources());
-                intentsToApply.forEach(installable ->
-                                               trackerService.removeTrackedResources(data.intent().key(),
-                                                                                     installable.resources()));
-            }
-
-            prepareIntents(intentsToApply, direction);
-        }
-
-        private boolean isSupported(Intent intent) {
-            return intent instanceof FlowRuleIntent ||
-                   intent instanceof FlowObjectiveIntent ||
-                   intent instanceof ProtectionEndpointIntent ||
-                   intent instanceof DomainIntent;
-        }
-
-        protected ToStringHelper toStringHelper() {
-            return MoreObjects.toStringHelper(this)
-                    .add("intentContext", intentContext)
-                    .add("toUninstall", toUninstall)
-                    .add("toInstall", toInstall);
-        }
-
-        @Override
-        public String toString() {
-            return toStringHelper()
-                    .toString();
-        }
-    }
-
-
-    // Context for applying and tracking operations related to flow rule intents.
-    private class FlowRuleOperationContext extends OperationContext {
-        FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
-        FlowRuleOperationsContext flowRuleOperationsContext;
-
-        FlowRuleOperationContext(IntentInstallationContext context) {
-            super(context);
-        }
-
-        @Override
-        void apply() {
-            flowRuleOperationsContext = new FlowRuleOperationsContext() {
-                @Override
-                public void onSuccess(FlowRuleOperations ops) {
-                    successConsumer.accept(FlowRuleOperationContext.this);
-                }
-
-                @Override
-                public void onError(FlowRuleOperations ops) {
-                    errorConsumer.accept(FlowRuleOperationContext.this);
-                }
-            };
-            FlowRuleOperations operations = builder.build(flowRuleOperationsContext);
-
-            if (log.isTraceEnabled()) {
-                log.trace("applying intent {} -> {} with {} rules: {}",
-                          toUninstall.map(x -> x.key().toString()).orElse("<empty>"),
-                          toInstall.map(x -> x.key().toString()).orElse("<empty>"),
-                          operations.stages().stream().mapToLong(Set::size).sum(),
-                          operations.stages());
-            }
-
-            flowRuleService.apply(operations);
-        }
-
-        @Override
-        public void prepareIntents(List<Intent> intentsToApply, Direction direction) {
-            // FIXME do FlowRuleIntents have stages??? Can we do uninstall work in parallel? I think so.
-            builder.newStage();
-
-            List<Collection<FlowRule>> stages = intentsToApply.stream()
-                    .filter(x -> x instanceof FlowRuleIntent)
-                    .map(x -> (FlowRuleIntent) x)
-                    .map(FlowRuleIntent::flowRules)
-                    .collect(Collectors.toList());
-
-            for (Collection<FlowRule> rules : stages) {
-                if (direction == Direction.ADD) {
-                    rules.forEach(builder::add);
-                } else {
-                    rules.forEach(builder::remove);
-                }
-            }
-
-        }
-
-        @Override
-        public Object error() {
-            return flowRuleOperationsContext;
-        }
-
-        @Override
-        protected ToStringHelper toStringHelper() {
-            return super.toStringHelper()
-                    .omitNullValues()
-                    .add("flowRuleOperationsContext", flowRuleOperationsContext);
-        }
-    }
-
-    // Context for applying and tracking operations related to flow objective intents.
-    private class FlowObjectiveOperationContext extends OperationContext {
-        private static final String UNSUPPORT_OBJ = "unsupported objective {}";
-        final List<ObjectiveContext> contexts = Lists.newArrayList();
-
-        final Set<ObjectiveContext> pendingContexts = Sets.newConcurrentHashSet();
-
-        // Second stage of pending contexts
-        final Set<ObjectiveContext> nextPendingContexts = Sets.newConcurrentHashSet();
-        final Set<ObjectiveContext> errorContexts = Sets.newConcurrentHashSet();
-
-        FlowObjectiveOperationContext(IntentInstallationContext context) {
-            super(context);
-        }
-
-        @Override
-        public void prepareIntents(List<Intent> intentsToApply, Direction direction) {
-            intentsToApply
-                .stream()
-                .filter(intent -> intent instanceof FlowObjectiveIntent)
-                .map(intent -> buildObjectiveContexts((FlowObjectiveIntent) intent, direction))
-                .flatMap(Collection::stream)
-                .forEach(contexts::add);
-
-            // Two stage for different direction context
-            // We will apply REMOVE context first, and apply ADD context.
-            contexts.forEach(context -> {
-                switch (direction) {
-                    case REMOVE:
-                        pendingContexts.add(context);
-                        break;
-                    case ADD:
-                        nextPendingContexts.add(context);
-                        break;
-                    default:
-                        break;
-                }
-            });
-        }
-
-        // Builds the specified objective in the appropriate direction
-        private Set<? extends ObjectiveContext> buildObjectiveContexts(FlowObjectiveIntent intent,
-                                            Direction direction) {
-            Set<FlowObjectiveInstallationContext> contexts = Sets.newHashSet();
-            int size = intent.objectives().size();
-            List<Objective> objectives = intent.objectives();
-            List<DeviceId> deviceIds = intent.devices();
-
-            if (direction == Direction.ADD) {
-                for (int i = 0; i < size; i++) {
-                    Objective objective = objectives.get(i);
-                    DeviceId deviceId = deviceIds.get(i);
-                    FlowObjectiveInstallationContext ctx =
-                            buildObjectiveContext(objective, deviceId, direction);
-                    contexts.add(ctx);
-                }
-                return contexts;
-            } else {
-                // we need to care about ordering here
-                // basic idea is to chain objective contexts
-                for (int i = 0; i < size; i++) {
-                    Objective objective = intent.objectives().get(i);
-                    DeviceId deviceId = intent.devices().get(i);
-
-                    if (objective instanceof FilteringObjective) {
-                        // don't need to care ordering of filtering objective
-                        FlowObjectiveInstallationContext ctx =
-                                buildObjectiveContext(objective, deviceId, direction);
-                        contexts.add(ctx);
-                    } else if (objective instanceof NextObjective) {
-                        // need to removed after forwarding objective
-                        // nothing to do here
-                    } else if (objective instanceof ForwardingObjective) {
-                        // forwarding objective, also find next objective if
-                        // exist
-                        FlowObjectiveInstallationContext fwdCtx =
-                                buildObjectiveContext(objective, deviceId, direction);
-                        ForwardingObjective fwd = (ForwardingObjective) objective;
-                        NextObjective nxt = null;
-                        Integer nextId = fwd.nextId();
-                        if (nextId != null) {
-                            for (int j = 0; j < size; j++) {
-                                if (objectives.get(j).id() == nextId) {
-                                    nxt = (NextObjective) objectives.get(j);
-                                    break;
-                                }
-                            }
-                            // if a next objective exists in the Intent
-                            if (nxt != null) {
-                                FlowObjectiveInstallationContext nxtCtx =
-                                        buildObjectiveContext(nxt, deviceId, direction);
-                                fwdCtx.nextContext(nxtCtx);
-                            }
-                        }
-                        contexts.add(fwdCtx);
-                    } else {
-                        // possible here?
-                        log.warn(UNSUPPORT_OBJ, objective);
-                    }
-                }
-            }
-            return contexts;
-        }
-
-        private FlowObjectiveInstallationContext buildObjectiveContext(Objective objective,
-                                                                       DeviceId deviceId,
-                                                                       Direction direction) {
-            Objective.Builder builder = objective.copy();
-            FlowObjectiveInstallationContext ctx = new FlowObjectiveInstallationContext();
-            switch (direction) {
-                case ADD:
-                    objective = builder.add(ctx);
-                    break;
-                case REMOVE:
-                    objective = builder.remove(ctx);
-                    break;
-                default:
-                    break;
-            }
-            ctx.setObjective(objective, deviceId);
-            return ctx;
-        }
-
-        @Override
-        void apply() {
-            // If there is no pending contexts, try apply second stage
-            // pending contexts
-            if (pendingContexts.isEmpty()) {
-                pendingContexts.addAll(nextPendingContexts);
-                nextPendingContexts.clear();
-            }
-            final Set<ObjectiveContext> contextsToApply = Sets.newHashSet(pendingContexts);
-            contextsToApply.forEach(ctx -> {
-                FlowObjectiveInstallationContext foiCtx =
-                        (FlowObjectiveInstallationContext) ctx;
-
-                flowObjectiveService.apply(foiCtx.deviceId, foiCtx.objective);
-            });
-        }
-
-        @Override
-        public Object error() {
-            return errorContexts;
-        }
-
-        @Override
-        protected ToStringHelper toStringHelper() {
-            return super.toStringHelper()
-                    .add("contexts", contexts)
-                    .add("pendingContexts", pendingContexts)
-                    .add("errorContexts", errorContexts);
-        }
-
-        private class FlowObjectiveInstallationContext implements ObjectiveContext {
-            Objective objective;
-            DeviceId deviceId;
-            ObjectiveError error;
-            AtomicInteger retry;
-            FlowObjectiveInstallationContext nextContext;
-
-            void setObjective(Objective objective, DeviceId deviceId) {
-                // init function
-                this.objective = objective;
-                this.deviceId = deviceId;
-                this.error = null;
-                this.retry = new AtomicInteger(0);
-                this.nextContext = null;
-            }
-
-            int retryTimes() {
-                return this.retry.get();
-            }
-
-            void increaseRetryValue() {
-                this.retry.incrementAndGet();
-            }
-
-            private void finished(ObjectiveError error) {
-
-                synchronized (pendingContexts) {
-                    if (error != null) {
-                        this.error = error;
-                        handleObjectiveError(this, error);
-                    } else {
-                        // apply next context if exist
-                        if (nextContext != null) {
-                            pendingContexts.add(nextContext);
-                            flowObjectiveService.apply(nextContext.deviceId,
-                                                       nextContext.objective);
-                            pendingContexts.remove(this);
-                        } else {
-                            pendingContexts.remove(this);
-                        }
-                    }
-                    if (!pendingContexts.isEmpty()) {
-                        return;
-                    }
-                    // Apply second stage pending contexts if it is not empty
-                    if (!nextPendingContexts.isEmpty()) {
-                        pendingContexts.addAll(nextPendingContexts);
-                        nextPendingContexts.clear();
-                        final Set<ObjectiveContext> contextsToApply =
-                                Sets.newHashSet(pendingContexts);
-                        contextsToApply.forEach(ctx -> {
-                            FlowObjectiveInstallationContext foiCtx =
-                                    (FlowObjectiveInstallationContext) ctx;
-                            flowObjectiveService.apply(foiCtx.deviceId,
-                                                       foiCtx.objective);
-                        });
-                        return;
-                    }
-                    if (errorContexts.isEmpty()) {
-                        successConsumer.accept(FlowObjectiveOperationContext.this);
-                    } else {
-                        errorConsumer.accept(FlowObjectiveOperationContext.this);
-                    }
-                }
-            }
-
-            @Override
-            public void onSuccess(Objective objective) {
-                finished(null);
-            }
-
-            @Override
-            public void onError(Objective objective, ObjectiveError error) {
-                finished(error);
-            }
-
-            @Override
-            public String toString() {
-                return String.format("(%s on %s for %s)", error, deviceId, objective);
-            }
-
-            public void nextContext(FlowObjectiveInstallationContext nextContext) {
-                this.nextContext = nextContext;
-            }
-        }
-
-        private void handleObjectiveError(FlowObjectiveInstallationContext ctx,
-                                          ObjectiveError error) {
-            log.debug("Got error(s) when install objective: {}, error: {}, retry: {}",
-                      ctx.objective, ctx.error, ctx.retry);
-            if (ctx.retryTimes() > OBJECTIVE_RETRY_THRESHOLD) {
-                ctx.error = INSTALLATIONTHRESHOLDEXCEEDED;
-                errorContexts.add(ctx);
-                return;
-            }
-            // reset error
-            ctx.error = null;
-            // strategies for errors
-            switch (error) {
-                case GROUPEXISTS:
-                    if (ctx.objective.op() == Objective.Operation.ADD) {
-                        // Next group exists
-                        // build new objective with new op ADD_TO_EXIST
-                        NextObjective newObj =
-                                ((NextObjective.Builder) ctx.objective.copy()).addToExisting(ctx);
-                        ctx.setObjective(newObj, ctx.deviceId);
-                        ctx.increaseRetryValue();
-                        flowObjectiveService.apply(ctx.deviceId, ctx.objective);
-                    } else {
-                        pendingContexts.remove(ctx);
-                        errorContexts.add(ctx);
-                    }
-                    break;
-                case GROUPINSTALLATIONFAILED:
-                    // Group install failed, retry again
-                    ctx.increaseRetryValue();
-                    flowObjectiveService.apply(ctx.deviceId, ctx.objective);
-                    break;
-                case GROUPMISSING:
-                    if (ctx.objective.op() == Objective.Operation.ADD_TO_EXISTING) {
-                        // Next group not exist, but we want to add new buckets
-                        // build new objective with new op ADD
-                        NextObjective newObj = (NextObjective) ctx.objective.copy().add(ctx);
-                        ctx.setObjective(newObj, ctx.deviceId);
-                        ctx.increaseRetryValue();
-                        flowObjectiveService.apply(ctx.deviceId, ctx.objective);
-                    } else if (ctx.objective.op() == Objective.Operation.REMOVE ||
-                            ctx.objective.op() == Objective.Operation.REMOVE_FROM_EXISTING) {
-                        // Already removed, no need to do anything
-                        ctx.error = null;
-                        pendingContexts.remove(ctx);
-                        return;
-                    } else {
-                        // Next chaining group missing, try again.
-                        ctx.increaseRetryValue();
-                        flowObjectiveService.apply(ctx.deviceId, ctx.objective);
-                    }
-                    break;
-                case FLOWINSTALLATIONFAILED:
-                case GROUPREMOVALFAILED:
-                case INSTALLATIONTIMEOUT:
-                    // Retry
-                    ctx.increaseRetryValue();
-                    flowObjectiveService.apply(ctx.deviceId, ctx.objective);
-                    break;
-                default:
-                    pendingContexts.remove(ctx);
-                    errorContexts.add(ctx);
-                    break;
-            }
-        }
-    }
-
-    // Context for applying and tracking operations related to domain intents.
-    private class DomainIntentOperationContext extends OperationContext {
-        DomainIntentOperations.Builder builder = DomainIntentOperations.builder();
-        DomainIntentOperationsContext domainOperationsContext;
-
-        DomainIntentOperationContext(IntentInstallationContext context) {
-            super(context);
-        }
-        @Override
-        void apply() {
-            domainOperationsContext = new DomainIntentOperationsContext() {
-                @Override
-                public void onSuccess(DomainIntentOperations ops) {
-                    successConsumer.accept(DomainIntentOperationContext.this);
-                }
-
-                @Override
-                public void onError(DomainIntentOperations ops) {
-                    errorConsumer.accept(DomainIntentOperationContext.this);
-                }
-            };
-            DomainIntentOperations operations = builder.build(domainOperationsContext);
-
-            if (log.isTraceEnabled()) {
-                log.trace("submitting domain intent {} -> {}",
-                          toUninstall.map(x -> x.key().toString()).orElse("<empty>"),
-                          toInstall.map(x -> x.key().toString()).orElse("<empty>"));
-            }
-            domainIntentService.sumbit(operations);
-        }
-
-        @Override
-        public void prepareIntents(List<Intent> intentsToApply, Direction direction) {
-            List<DomainIntent> intents = intentsToApply.stream()
-                    .filter(x -> x instanceof DomainIntent)
-                    .map(x -> (DomainIntent) x)
-                    .collect(Collectors.toList());
-
-            for (DomainIntent intent : intents) {
-                if (direction == Direction.ADD) {
-                    builder.add(intent);
-                } else {
-                    builder.remove(intent);
-                }
-            }
-        }
-
-        @Override
-        public Object error() {
-            return domainOperationsContext;
-        }
-    }
-
-    private class ErrorContext extends OperationContext {
-        ErrorContext(IntentInstallationContext context) {
-            super(context);
-        }
-        @Override
-        void apply() {
-            throw new UnsupportedOperationException("Unsupported installable intent");
-        }
-
-        @Override
-        Object error() {
-            return null;
-        }
-
-        @Override
-        void prepareIntents(List<Intent> intentsToApply, Direction direction) {
-        }
-    }
-
-
-    /**
-     * Context for applying and tracking operations related to
-     * {@link ProtectionEndpointIntent}.
-     */
-    @Beta
-    private class ProtectionConfigOperationContext extends OperationContext {
-
-        ProtectionConfigOperationContext(IntentInstallationContext context) {
-            super(context);
-        }
-
-        /**
-         * Stage of installable Intents which can be processed in parallel.
-         */
-        private final class Stage {
-            // should it have progress state, how far it went?
-            private final Collection<Pair<ProtectionEndpointIntent, Direction>> ops;
-
-            Stage(Collection<Pair<ProtectionEndpointIntent, Direction>> ops) {
-                this.ops = checkNotNull(ops);
-            }
-
-            CompletableFuture<Void> apply() {
-                return ops.stream()
-                    .map(op -> applyOp(op.getRight(), op.getLeft()))
-                    .reduce(CompletableFuture.completedFuture(null),
-                            (l, r) -> {
-                                l.join();
-                                return r;
-                            });
-            }
-
-            private CompletableFuture<Void> applyOp(Direction dir, ProtectionEndpointIntent intent) {
-                log.trace("applying {}: {}", dir, intent);
-                if (dir == Direction.REMOVE) {
-                    networkConfigService.removeConfig(intent.deviceId(), ProtectionConfig.class);
-                } else if (dir == Direction.ADD) {
-                    ProtectedTransportEndpointDescription description = intent.description();
-
-                    // Can't do following. Will trigger empty CONFIG_ADDED
-                    //ProtectionConfig cfg = networkConfigService.addConfig(intent.deviceId(),
-                    //                                                      ProtectionConfig.class);
-                    ProtectionConfig cfg = new ProtectionConfig(intent.deviceId());
-                    cfg.fingerprint(description.fingerprint());
-                    cfg.peer(description.peer());
-                    cfg.paths(description.paths());
-                    //cfg.apply();
-
-                    networkConfigService.applyConfig(intent.deviceId(),
-                                                     ProtectionConfig.class,
-                                                     cfg.node());
-                }
-                // TODO Should monitor progress and complete only after it's
-                // actually done.
-                return CompletableFuture.completedFuture(null);
-            }
-
-            @Override
-            public String toString() {
-                return ops.toString();
-            }
-        }
-
-        /**
-         * List of Stages which must be executed in order.
-         */
-        private final List<Stage> stages = new ArrayList<>();
-
-        private final List<Stage> failed = new CopyOnWriteArrayList<>();
-
-        @Override
-        synchronized void apply() {
-            for (Stage stage : stages) {
-                log.trace("applying Stage {}", stage);
-                CompletableFuture<Void> result = stage.apply();
-                // wait for stage completion
-                result.join();
-                if (result.isCompletedExceptionally()) {
-                    log.error("Stage {} failed", stage);
-                    failed.add(stage);
-                    errorConsumer.accept(ProtectionConfigOperationContext.this);
-                    return;
-                }
-            }
-            successConsumer.accept(ProtectionConfigOperationContext.this);
-        }
-
-        @Override
-        Object error() {
-            // Something to represent error state
-            return failed;
-        }
-
-        @Override
-        synchronized void prepareIntents(List<Intent> intentsToApply,
-                                         Direction direction) {
-
-            stages.add(new Stage(intentsToApply.stream()
-                                 .filter(i -> i instanceof ProtectionEndpointIntent)
-                                 .map(i -> Pair.of((ProtectionEndpointIntent) i, direction))
-                                 .collect(Collectors.toList())));
-        }
-
-        @Override
-        protected ToStringHelper toStringHelper() {
-            return super.toStringHelper()
-                    .add("stages", stages)
-                    .add("failed", failed);
-        }
-    }
-}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index 3b542bd..14d2bea 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -38,9 +38,12 @@
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentBatchDelegate;
 import org.onosproject.net.intent.IntentCompiler;
+import org.onosproject.net.intent.IntentInstallCoordinator;
 import org.onosproject.net.intent.IntentData;
 import org.onosproject.net.intent.IntentEvent;
 import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentInstaller;
 import org.onosproject.net.intent.IntentListener;
 import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.intent.IntentState;
@@ -87,7 +90,7 @@
 @Service
 public class IntentManager
         extends AbstractListenerManager<IntentEvent, IntentListener>
-        implements IntentService, IntentExtensionService {
+        implements IntentService, IntentExtensionService, IntentInstallCoordinator {
 
     private static final Logger log = getLogger(IntentManager.class);
 
@@ -141,17 +144,17 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     private NetworkConfigService networkConfigService;
 
-
     private ExecutorService batchExecutor;
     private ExecutorService workerExecutor;
 
-    private final IntentInstaller intentInstaller = new IntentInstaller();
     private final CompilerRegistry compilerRegistry = new CompilerRegistry();
+    private final InstallerRegistry installerRegistry = new InstallerRegistry();
     private final InternalIntentProcessor processor = new InternalIntentProcessor();
     private final IntentStoreDelegate delegate = new InternalStoreDelegate();
     private final IntentStoreDelegate testOnlyDelegate = new TestOnlyIntentStoreDelegate();
     private final TopologyChangeDelegate topoDelegate = new InternalTopoChangeDelegate();
     private final IntentBatchDelegate batchDelegate = new InternalBatchDelegate();
+    private InstallCoordinator installCoordinator;
     private IdGenerator idGenerator;
 
     private final IntentAccumulator accumulator = new IntentAccumulator(batchDelegate);
@@ -159,9 +162,6 @@
     @Activate
     public void activate() {
         configService.registerProperties(getClass());
-
-        intentInstaller.init(store, trackerService, flowRuleService, flowObjectiveService,
-                             networkConfigService, domainIntentService);
         if (skipReleaseResourcesOnWithdrawal) {
             store.setDelegate(testOnlyDelegate);
         } else {
@@ -174,12 +174,12 @@
         idGenerator = coreService.getIdGenerator("intent-ids");
         Intent.unbindIdGenerator(idGenerator);
         Intent.bindIdGenerator(idGenerator);
+        installCoordinator = new InstallCoordinator(installerRegistry, store);
         log.info("Started");
     }
 
     @Deactivate
     public void deactivate() {
-        intentInstaller.init(null, null, null, null, null, null);
         if (skipReleaseResourcesOnWithdrawal) {
             store.unsetDelegate(testOnlyDelegate);
         } else {
@@ -337,11 +337,42 @@
     }
 
     @Override
+    public <T extends Intent> void registerInstaller(Class<T> cls, IntentInstaller<T> installer) {
+        installerRegistry.registerInstaller(cls, installer);
+    }
+
+    @Override
+    public <T extends Intent> void unregisterInstaller(Class<T> cls) {
+        installerRegistry.unregisterInstaller(cls);
+    }
+
+    @Override
+    public Map<Class<? extends Intent>, IntentInstaller<? extends Intent>> getInstallers() {
+        return installerRegistry.getInstallers();
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <T extends Intent> IntentInstaller<T> getInstaller(Class<T> cls) {
+        return (IntentInstaller<T>) installerRegistry.getInstallers().get(cls);
+    }
+
+    @Override
     public Iterable<Intent> getPending() {
         checkPermission(INTENT_READ);
         return store.getPending();
     }
 
+    @Override
+    public void intentInstallSuccess(IntentOperationContext context) {
+        installCoordinator.success(context);
+    }
+
+    @Override
+    public void intentInstallFailed(IntentOperationContext context) {
+        installCoordinator.failed(context);
+    }
+
     // Store delegate to re-post events emitted from the store.
     private class InternalStoreDelegate implements IntentStoreDelegate {
         @Override
@@ -536,7 +567,7 @@
 
         @Override
         public void apply(Optional<IntentData> toUninstall, Optional<IntentData> toInstall) {
-            intentInstaller.apply(toUninstall, toInstall);
+            installCoordinator.installIntents(toUninstall, toInstall);
         }
     }
 
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/DomainIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/DomainIntentInstaller.java
new file mode 100644
index 0000000..a713034
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/DomainIntentInstaller.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.installer;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.net.domain.DomainIntent;
+import org.onosproject.net.domain.DomainIntentOperations;
+import org.onosproject.net.domain.DomainIntentOperationsContext;
+import org.onosproject.net.domain.DomainIntentService;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentInstallCoordinator;
+import org.onosproject.net.intent.IntentInstaller;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.impl.IntentManager;
+import org.onosproject.net.intent.impl.ObjectiveTrackerService;
+import org.slf4j.Logger;
+
+import java.util.List;
+import java.util.Optional;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Installer for domain Intent.
+ */
+@Component(immediate = true)
+public class DomainIntentInstaller implements IntentInstaller<DomainIntent> {
+
+    private final Logger log = getLogger(IntentManager.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentExtensionService intentExtensionService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ObjectiveTrackerService trackerService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentInstallCoordinator intentInstallCoordinator;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DomainIntentService domainIntentService;
+
+    @Activate
+    public void activated() {
+        intentExtensionService.registerInstaller(DomainIntent.class, this);
+    }
+
+    @Deactivate
+    public void deactivated() {
+        intentExtensionService.unregisterInstaller(DomainIntent.class);
+    }
+
+    @Override
+    public void apply(IntentOperationContext<DomainIntent> context) {
+        Optional<IntentData> toUninstall = context.toUninstall();
+        Optional<IntentData> toInstall = context.toInstall();
+
+        List<DomainIntent> uninstallIntents = context.intentsToUninstall();
+        List<DomainIntent> installIntents = context.intentsToInstall();
+
+        if (!toInstall.isPresent() && !toUninstall.isPresent()) {
+            intentInstallCoordinator.intentInstallSuccess(context);
+            return;
+        }
+
+        if (toUninstall.isPresent()) {
+            IntentData intentData = toUninstall.get();
+            trackerService.removeTrackedResources(intentData.key(), intentData.intent().resources());
+            uninstallIntents.forEach(installable ->
+                                             trackerService.removeTrackedResources(intentData.intent().key(),
+                                                                                   installable.resources()));
+        }
+
+        if (toInstall.isPresent()) {
+            IntentData intentData = toInstall.get();
+            trackerService.addTrackedResources(intentData.key(), intentData.intent().resources());
+            installIntents.forEach(installable ->
+                                           trackerService.addTrackedResources(intentData.key(),
+                                                                              installable.resources()));
+        }
+
+        // Generate domain Intent operations
+        DomainIntentOperations.Builder builder = DomainIntentOperations.builder();
+        DomainIntentOperationsContext domainOperationsContext;
+
+        uninstallIntents.forEach(builder::remove);
+        installIntents.forEach(builder::add);
+
+        domainOperationsContext = new DomainIntentOperationsContext() {
+            @Override
+            public void onSuccess(DomainIntentOperations idops) {
+                intentInstallCoordinator.intentInstallSuccess(context);
+            }
+
+            @Override
+            public void onError(DomainIntentOperations idos) {
+                intentInstallCoordinator.intentInstallFailed(context);
+            }
+        };
+        log.debug("submitting domain intent {} -> {}",
+                  toUninstall.map(x -> x.key().toString()).orElse("<empty>"),
+                  toInstall.map(x -> x.key().toString()).orElse("<empty>"));
+
+        // Submit domain Inten operations with domain context
+        domainIntentService.sumbit(builder.build(domainOperationsContext));
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowObjectiveIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowObjectiveIntentInstaller.java
new file mode 100644
index 0000000..22ff970
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowObjectiveIntentInstaller.java
@@ -0,0 +1,565 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.installer;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+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.onosproject.net.DeviceId;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.flowobjective.Objective;
+import org.onosproject.net.flowobjective.ObjectiveContext;
+import org.onosproject.net.flowobjective.ObjectiveError;
+import org.onosproject.net.intent.FlowObjectiveIntent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentInstallCoordinator;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentInstaller;
+import org.onosproject.net.intent.impl.IntentManager;
+import org.onosproject.net.intent.impl.ObjectiveTrackerService;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.onosproject.net.flowobjective.ObjectiveError.INSTALLATIONTHRESHOLDEXCEEDED;
+import static org.onosproject.net.intent.IntentInstaller.Direction.ADD;
+import static org.onosproject.net.intent.IntentInstaller.Direction.REMOVE;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Installer for FlowObjectiveIntent.
+ */
+@Component(immediate = true)
+public class FlowObjectiveIntentInstaller implements IntentInstaller<FlowObjectiveIntent> {
+    private static final int OBJECTIVE_RETRY_THRESHOLD = 5;
+    private static final String UNSUPPORT_OBJ = "unsupported objective {}";
+    private final Logger log = getLogger(IntentManager.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentExtensionService intentExtensionService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ObjectiveTrackerService trackerService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentInstallCoordinator intentInstallCoordinator;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Activate
+    public void activate() {
+        intentExtensionService.registerInstaller(FlowObjectiveIntent.class, this);
+    }
+
+    @Deactivate
+    public void deactivated() {
+        intentExtensionService.unregisterInstaller(FlowObjectiveIntent.class);
+    }
+
+    @Override
+    public void apply(IntentOperationContext<FlowObjectiveIntent> intentOperationContext) {
+        Objects.requireNonNull(intentOperationContext);
+        Optional<IntentData> toUninstall = intentOperationContext.toUninstall();
+        Optional<IntentData> toInstall = intentOperationContext.toInstall();
+
+        List<FlowObjectiveIntent> uninstallIntents = intentOperationContext.intentsToUninstall();
+        List<FlowObjectiveIntent> installIntents = intentOperationContext.intentsToInstall();
+
+        if (!toInstall.isPresent() && !toUninstall.isPresent()) {
+            intentInstallCoordinator.intentInstallSuccess(intentOperationContext);
+            return;
+        }
+
+        if (toUninstall.isPresent()) {
+            IntentData intentData = toUninstall.get();
+            trackerService.removeTrackedResources(intentData.key(), intentData.intent().resources());
+            uninstallIntents.forEach(installable ->
+                                             trackerService.removeTrackedResources(intentData.intent().key(),
+                                                                                   installable.resources()));
+        }
+
+        if (toInstall.isPresent()) {
+            IntentData intentData = toInstall.get();
+            trackerService.addTrackedResources(intentData.key(), intentData.intent().resources());
+            installIntents.forEach(installable ->
+                                           trackerService.addTrackedResources(intentData.key(),
+                                                                              installable.resources()));
+        }
+
+        FlowObjectiveIntentInstallationContext intentInstallationContext =
+                new FlowObjectiveIntentInstallationContext(intentOperationContext);
+
+        uninstallIntents.stream()
+                .map(intent -> buildObjectiveContexts(intent, REMOVE))
+                .flatMap(Collection::stream)
+                .forEach(context -> {
+                    context.intentInstallationContext(intentInstallationContext);
+                    intentInstallationContext.addContext(context);
+                    intentInstallationContext.addPendingContext(context);
+                });
+
+        installIntents.stream()
+                .map(intent -> buildObjectiveContexts(intent, ADD))
+                .flatMap(Collection::stream)
+                .forEach(context -> {
+                    context.intentInstallationContext(intentInstallationContext);
+                    intentInstallationContext.addContext(context);
+                    intentInstallationContext.addNextPendingContext(context);
+                });
+
+        intentInstallationContext.apply();
+    }
+
+    /**
+     * Builds all objective contexts for a given flow objective Intent with given
+     * operation.
+     *
+     * @param intent the flow objective Intent
+     * @param direction the operation of this Intent
+     * @return all objective context of the Intent with given operation
+     */
+    private Set<FlowObjectiveInstallationContext> buildObjectiveContexts(FlowObjectiveIntent intent,
+                                                                         Direction direction) {
+        Objects.requireNonNull(intent);
+        Objects.requireNonNull(direction);
+        Set<FlowObjectiveInstallationContext> contexts = Sets.newHashSet();
+        int size = intent.objectives().size();
+        List<Objective> objectives = intent.objectives();
+        List<DeviceId> deviceIds = intent.devices();
+
+        if (direction == ADD) {
+            // Install objectives
+            // The flow objective system will handle the installation order
+            for (int i = 0; i < size; i++) {
+                Objective objective = objectives.get(i);
+                DeviceId deviceId = deviceIds.get(i);
+                FlowObjectiveInstallationContext ctx = buildObjectiveContext(objective, deviceId, direction);
+                contexts.add(ctx);
+            }
+            return contexts;
+        } else {
+            // Uninstall objecitves
+            // we need to care about ordering here
+            // basic idea is to chain objective contexts
+            for (int i = 0; i < size; i++) {
+                Objective objective = intent.objectives().get(i);
+                DeviceId deviceId = intent.devices().get(i);
+                if (objective instanceof FilteringObjective) {
+                    // don't need to care ordering of filtering objective
+                    FlowObjectiveInstallationContext ctx =
+                            buildObjectiveContext(objective, deviceId, direction);
+                    contexts.add(ctx);
+                } else if (objective instanceof NextObjective) {
+                    // need to removed after forwarding objective
+                    // nothing to do here
+                } else if (objective instanceof ForwardingObjective) {
+                    // forwarding objective, also find next objective if
+                    // exist
+                    FlowObjectiveInstallationContext fwdCtx =
+                            buildObjectiveContext(objective, deviceId, direction);
+                    ForwardingObjective fwd = (ForwardingObjective) objective;
+                    NextObjective nxt = null;
+                    Integer nextId = fwd.nextId();
+                    if (nextId != null) {
+                        for (int j = 0; j < size; j++) {
+                            if (objectives.get(j).id() == nextId) {
+                                nxt = (NextObjective) objectives.get(j);
+                                break;
+                            }
+                        }
+                        // if a next objective exists in the Intent
+                        if (nxt != null) {
+                            FlowObjectiveInstallationContext nxtCtx =
+                                    buildObjectiveContext(nxt, deviceId, direction);
+                            fwdCtx.nextContext(nxtCtx);
+                        }
+                    }
+                    contexts.add(fwdCtx);
+                } else {
+                    // possible here?
+                    log.warn(UNSUPPORT_OBJ, objective);
+                }
+            }
+        }
+        return contexts;
+    }
+
+    private FlowObjectiveInstallationContext buildObjectiveContext(Objective objective,
+                                                                   DeviceId deviceId,
+                                                                   Direction direction) {
+        Objects.requireNonNull(objective);
+        Objects.requireNonNull(deviceId);
+        Objects.requireNonNull(direction);
+        Objective.Builder builder = objective.copy();
+        FlowObjectiveInstallationContext ctx = new FlowObjectiveInstallationContext();
+        switch (direction) {
+            case ADD:
+                objective = builder.add(ctx);
+                break;
+            case REMOVE:
+                objective = builder.remove(ctx);
+                break;
+            default:
+                break;
+        }
+        ctx.setObjective(objective, deviceId);
+        return ctx;
+    }
+
+    /**
+     * Installation context for flow objective.
+     * Manages installation state of a flow objective.
+     */
+    class FlowObjectiveInstallationContext implements ObjectiveContext {
+        private Objective objective;
+        private DeviceId deviceId;
+        private ObjectiveError error;
+        private AtomicInteger retry;
+        private FlowObjectiveInstallationContext nextContext;
+        private FlowObjectiveIntentInstallationContext intentInstallationContext;
+
+        /**
+         * Set flow objective Intent installation context to this context.
+         *
+         * @param intentInstallationContext the Intent installation context
+         */
+        public void intentInstallationContext(FlowObjectiveIntentInstallationContext intentInstallationContext) {
+            Objects.requireNonNull(intentInstallationContext);
+            this.intentInstallationContext = intentInstallationContext;
+
+            // Set Intent installation context to the next context if exists.
+            if (nextContext != null) {
+                nextContext.intentInstallationContext(intentInstallationContext);
+            }
+        }
+
+        /**
+         * Sets next flow objective installation context.
+         *
+         * @param nextContext the next flow objective installation context
+         */
+        public void nextContext(FlowObjectiveInstallationContext nextContext) {
+            Objects.requireNonNull(nextContext);
+            this.nextContext = nextContext;
+        }
+
+        /**
+         * Sets objective and device id to this context; reset error states.
+         *
+         * @param objective the objective
+         * @param deviceId the device id
+         */
+        void setObjective(Objective objective, DeviceId deviceId) {
+            Objects.requireNonNull(objective);
+            Objects.requireNonNull(deviceId);
+            this.objective = objective;
+            this.deviceId = deviceId;
+            this.error = null;
+            this.retry = new AtomicInteger(0);
+        }
+
+        /**
+         * Gets the number of retries.
+         *
+         * @return the retry count
+         */
+        int retryTimes() {
+            return this.retry.get();
+        }
+
+        /**
+         * Increases the number of retries.
+         */
+        void increaseRetryValue() {
+            this.retry.incrementAndGet();
+        }
+
+        /**
+         * Completed this context.
+         *
+         * @param error the error of this context if exist; null otherwise
+         */
+        private void finished(ObjectiveError error) {
+            synchronized (intentInstallationContext) {
+                if (error != null) {
+                    this.error = error;
+                    intentInstallationContext.handleObjectiveError(this, error);
+                } else {
+                    // apply next context if exist
+                    if (nextContext != null) {
+                        intentInstallationContext.addPendingContext(nextContext);
+                        flowObjectiveService.apply(nextContext.deviceId,
+                                                   nextContext.objective);
+                        intentInstallationContext.removePendingContext(this);
+                    } else {
+                        intentInstallationContext.removePendingContext(this);
+                    }
+                }
+                if (!intentInstallationContext.pendingContexts().isEmpty()) {
+                    return;
+                }
+                // Apply second stage pending contexts if it is not empty
+                if (!intentInstallationContext.nextPendingContexts().isEmpty()) {
+                    intentInstallationContext.moveNextPendingToPending();
+                    final Set<ObjectiveContext> contextsToApply =
+                            Sets.newHashSet(intentInstallationContext.pendingContexts());
+                    contextsToApply.forEach(ctx -> {
+                        FlowObjectiveInstallationContext foiCtx = (FlowObjectiveInstallationContext) ctx;
+                        flowObjectiveService.apply(foiCtx.deviceId,
+                                                   foiCtx.objective);
+                    });
+                    return;
+                }
+                if (intentInstallationContext.errorContexts().isEmpty()) {
+                    intentInstallCoordinator.intentInstallSuccess(intentInstallationContext.intentOperationContext());
+                } else {
+                    intentInstallCoordinator.intentInstallFailed(intentInstallationContext.intentOperationContext());
+                }
+            }
+        }
+
+        @Override
+        public void onSuccess(Objective objective) {
+            finished(null);
+        }
+
+        @Override
+        public void onError(Objective objective, ObjectiveError error) {
+            finished(error);
+        }
+
+        @Override
+        public String toString() {
+            return String.format("(%s on %s for %s)", error, deviceId, objective);
+        }
+    }
+
+    /**
+     * Installation context for FlowObjective Intent.
+     * Manages states of pending and error flow objective contexts.
+     */
+    class FlowObjectiveIntentInstallationContext {
+        private final IntentOperationContext<FlowObjectiveIntent> intentOperationContext;
+        final List<ObjectiveContext> contexts = Lists.newArrayList();
+        final Set<ObjectiveContext> errorContexts = Sets.newConcurrentHashSet();
+        final Set<ObjectiveContext> pendingContexts = Sets.newConcurrentHashSet();
+
+        // Second stage of pending contexts
+        final Set<ObjectiveContext> nextPendingContexts = Sets.newConcurrentHashSet();
+
+        /**
+         * Creates a flow objective installation context.
+         *
+         * @param intentOperationContext the flow objective installation context
+         */
+        public FlowObjectiveIntentInstallationContext(
+                IntentOperationContext<FlowObjectiveIntent> intentOperationContext) {
+            Objects.requireNonNull(intentOperationContext);
+            this.intentOperationContext = intentOperationContext;
+        }
+
+        /**
+         * Gets Intent operation context of this context.
+         *
+         * @return the Intent operation context
+         */
+        public IntentOperationContext<FlowObjectiveIntent> intentOperationContext() {
+            return intentOperationContext;
+        }
+
+        /**
+         * Applies all contexts to flow objective service.
+         */
+        public void apply() {
+            if (pendingContexts.isEmpty()) {
+                moveNextPendingToPending();
+            }
+            final Set<ObjectiveContext> contextsToApply = pendingContexts();
+            contextsToApply.forEach(ctx -> {
+                FlowObjectiveInstallationContext foiCtx =
+                        (FlowObjectiveInstallationContext) ctx;
+                flowObjectiveService.apply(foiCtx.deviceId, foiCtx.objective);
+            });
+        }
+
+        /**
+         * Gets all error contexts.
+         *
+         * @return the error contexts
+         */
+        public Set<ObjectiveContext> errorContexts() {
+            return ImmutableSet.copyOf(errorContexts);
+        }
+
+        /**
+         * Gets all pending contexts.
+         *
+         * @return the pending contexts
+         */
+        public Set<ObjectiveContext> pendingContexts() {
+            return ImmutableSet.copyOf(pendingContexts);
+        }
+
+        /**
+         * Gets all pending contexts of next stage.
+         *
+         * @return the pending contexts for next stage
+         */
+        public Set<ObjectiveContext> nextPendingContexts() {
+            return ImmutableSet.copyOf(nextPendingContexts);
+        }
+
+        /**
+         * Adds a context.
+         *
+         * @param context the context
+         */
+        public void addContext(ObjectiveContext context) {
+            Objects.requireNonNull(context);
+            contexts.add(context);
+        }
+
+        /**
+         * Adds a context to pending context of next stage.
+         *
+         * @param context the context
+         */
+        public void addNextPendingContext(ObjectiveContext context) {
+            Objects.requireNonNull(context);
+            nextPendingContexts.add(context);
+        }
+
+        /**
+         * Adds a context to pending context.
+         *
+         * @param context the context
+         */
+        public void addPendingContext(ObjectiveContext context) {
+            Objects.requireNonNull(context);
+            pendingContexts.add(context);
+        }
+
+        /**
+         * Removes the pending context.
+         *
+         * @param context the context
+         */
+        public void removePendingContext(ObjectiveContext context) {
+            Objects.requireNonNull(context);
+            pendingContexts.remove(context);
+        }
+
+        /**
+         * Moves pending context from next stage to current stage.
+         */
+        public void moveNextPendingToPending() {
+            pendingContexts.addAll(nextPendingContexts);
+            nextPendingContexts.clear();
+        }
+
+        /**
+         * Handles error of objective context.
+         *
+         * @param ctx the objective context
+         * @param error the error
+         */
+        public void handleObjectiveError(FlowObjectiveInstallationContext ctx,
+                                         ObjectiveError error) {
+            Objects.requireNonNull(ctx);
+            Objects.requireNonNull(error);
+            log.debug("Got error(s) when install objective: {}, error: {}, retry: {}",
+                      ctx.objective, ctx.error, ctx.retry);
+            if (ctx.retryTimes() > OBJECTIVE_RETRY_THRESHOLD) {
+                ctx.error = INSTALLATIONTHRESHOLDEXCEEDED;
+                pendingContexts.remove(ctx);
+                errorContexts.add(ctx);
+                return;
+            }
+            // reset error
+            ctx.error = null;
+            // strategies for errors
+            switch (error) {
+                case GROUPEXISTS:
+                    if (ctx.objective.op() == Objective.Operation.ADD &&
+                            ctx.objective instanceof NextObjective) {
+                        // Next group exists
+                        // build new objective with new op ADD_TO_EXIST
+                        NextObjective newObj =
+                                ((NextObjective.Builder) ctx.objective.copy()).addToExisting(ctx);
+                        ctx.setObjective(newObj, ctx.deviceId);
+                        ctx.increaseRetryValue();
+                        flowObjectiveService.apply(ctx.deviceId, ctx.objective);
+                    } else {
+                        pendingContexts.remove(ctx);
+                        errorContexts.add(ctx);
+                    }
+                    break;
+                case GROUPINSTALLATIONFAILED:
+                    // Group install failed, retry again
+                    ctx.increaseRetryValue();
+                    flowObjectiveService.apply(ctx.deviceId, ctx.objective);
+                    break;
+                case GROUPMISSING:
+                    if (ctx.objective.op() == Objective.Operation.ADD_TO_EXISTING) {
+                        // Next group not exist, but we want to add new buckets
+                        // build new objective with new op ADD
+                        NextObjective newObj = (NextObjective) ctx.objective.copy().add(ctx);
+                        ctx.setObjective(newObj, ctx.deviceId);
+                        ctx.increaseRetryValue();
+                        flowObjectiveService.apply(ctx.deviceId, ctx.objective);
+                    } else if (ctx.objective.op() == Objective.Operation.REMOVE ||
+                            ctx.objective.op() == Objective.Operation.REMOVE_FROM_EXISTING) {
+                        // Already removed, no need to do anything
+                        ctx.error = null;
+                        pendingContexts.remove(ctx);
+                        return;
+                    } else {
+                        // Next chaining group missing, try again.
+                        ctx.increaseRetryValue();
+                        flowObjectiveService.apply(ctx.deviceId, ctx.objective);
+                    }
+                    break;
+                case FLOWINSTALLATIONFAILED:
+                case GROUPREMOVALFAILED:
+                case INSTALLATIONTIMEOUT:
+                    // Retry
+                    ctx.increaseRetryValue();
+                    flowObjectiveService.apply(ctx.deviceId, ctx.objective);
+                    break;
+                default:
+                    pendingContexts.remove(ctx);
+                    errorContexts.add(ctx);
+                    break;
+            }
+        }
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
new file mode 100644
index 0000000..f29ceec
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstaller.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.installer;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.FlowRuleService;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.IntentInstallCoordinator;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentInstaller;
+import org.onosproject.net.intent.impl.IntentManager;
+import org.onosproject.net.intent.impl.ObjectiveTrackerService;
+import org.slf4j.Logger;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import static org.onosproject.net.intent.IntentInstaller.Direction.ADD;
+import static org.onosproject.net.intent.IntentInstaller.Direction.REMOVE;
+import static org.onosproject.net.intent.IntentState.INSTALLED;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Installer for FlowRuleIntent.
+ */
+@Component(immediate = true)
+public class FlowRuleIntentInstaller implements IntentInstaller<FlowRuleIntent> {
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentExtensionService intentExtensionService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ObjectiveTrackerService trackerService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentInstallCoordinator intentInstallCoordinator;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowRuleService flowRuleService;
+
+    @Activate
+    public void activate() {
+        intentExtensionService.registerInstaller(FlowRuleIntent.class, this);
+    }
+
+    @Deactivate
+    public void deactivated() {
+        intentExtensionService.unregisterInstaller(FlowRuleIntent.class);
+    }
+
+    protected final Logger log = getLogger(IntentManager.class);
+
+    @Override
+    public void apply(IntentOperationContext<FlowRuleIntent> context) {
+        Optional<IntentData> toUninstall = context.toUninstall();
+        Optional<IntentData> toInstall = context.toInstall();
+
+        List<FlowRuleIntent> uninstallIntents = context.intentsToUninstall();
+        List<FlowRuleIntent> installIntents = context.intentsToInstall();
+
+        if (!toInstall.isPresent() && !toUninstall.isPresent()) {
+            intentInstallCoordinator.intentInstallSuccess(context);
+            return;
+        } else if (!toInstall.isPresent()) {
+            // Uninstall only
+            trackIntentResources(toUninstall.get(), uninstallIntents, REMOVE);
+        } else if (!toUninstall.isPresent()) {
+            // Install only
+            trackIntentResources(toInstall.get(), installIntents, ADD);
+        } else {
+            IntentData uninstall = toUninstall.get();
+            IntentData install = toInstall.get();
+
+            // Filter out same intents and intents with same flow rules
+            Iterator<FlowRuleIntent> iterator = installIntents.iterator();
+            while (iterator.hasNext()) {
+                FlowRuleIntent installIntent = iterator.next();
+                uninstallIntents.stream().filter(uIntent -> {
+                    if (uIntent.equals(installIntent)) {
+                        return true;
+                    } else {
+                        return !flowRuleIntentChanged(uIntent, installIntent);
+                    }
+                }).findFirst().ifPresent(common -> {
+                    uninstallIntents.remove(common);
+                    if (INSTALLED.equals(uninstall.state())) {
+                        // only remove the install intent if the existing
+                        // intent (i.e. the uninstall one) is already
+                        // installed or installing
+                        iterator.remove();
+                    }
+                });
+            }
+            trackIntentResources(uninstall, uninstallIntents, REMOVE);
+            trackIntentResources(install, installIntents, ADD);
+        }
+
+        FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+        builder.newStage();
+
+        toUninstall.ifPresent(intentData -> {
+            uninstallIntents.stream().map(FlowRuleIntent::flowRules)
+                    .flatMap(Collection::stream).forEach(builder::remove);
+        });
+
+        toInstall.ifPresent(intentData -> {
+            installIntents.stream().map(FlowRuleIntent::flowRules)
+                    .flatMap(Collection::stream).forEach(builder::add);
+        });
+
+        FlowRuleOperationsContext flowRuleOperationsContext = new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                intentInstallCoordinator.intentInstallSuccess(context);
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                intentInstallCoordinator.intentInstallFailed(context);
+            }
+        };
+
+        FlowRuleOperations operations = builder.build(flowRuleOperationsContext);
+
+
+        log.debug("applying intent {} -> {} with {} rules: {}",
+                  toUninstall.map(x -> x.key().toString()).orElse("<empty>"),
+                  toInstall.map(x -> x.key().toString()).orElse("<empty>"),
+                  operations.stages().stream().mapToLong(Set::size).sum(),
+                  operations.stages());
+        flowRuleService.apply(operations);
+    }
+
+    /**
+     * Track or un-track network resource of a Intent and it's installable
+     * Intents.
+     *
+     * @param intentData the Intent data
+     * @param intentsToApply the list of flow rule Intents from the Intent
+     * @param direction the direction to determine track or un-track
+     */
+    private void trackIntentResources(IntentData intentData, List<FlowRuleIntent> intentsToApply, Direction direction) {
+        switch (direction) {
+            case ADD:
+                trackerService.addTrackedResources(intentData.key(), intentData.intent().resources());
+                intentsToApply.forEach(installable ->
+                                               trackerService.addTrackedResources(intentData.key(),
+                                                                                  installable.resources()));
+                break;
+            default:
+                trackerService.removeTrackedResources(intentData.key(), intentData.intent().resources());
+                intentsToApply.forEach(installable ->
+                                               trackerService.removeTrackedResources(intentData.intent().key(),
+                                                                                     installable.resources()));
+                break;
+        }
+    }
+
+    /**
+     * Determines whether there is any flow rule changed
+     * (i.e., different set of flow rules or different treatments)
+     * between FlowRuleIntents to be uninstalled and to be installed.
+     *
+     * @param uninstallIntent FlowRuleIntent to uninstall
+     * @param installIntent   FlowRuleIntent to install
+     * @return true if flow rules which to be uninstalled contains all flow
+     *         rules which to be installed; false otherwise
+     */
+    private boolean flowRuleIntentChanged(FlowRuleIntent uninstallIntent,
+                                          FlowRuleIntent installIntent) {
+        Collection<FlowRule> flowRulesToUninstall = uninstallIntent.flowRules();
+        Collection<FlowRule> flowRulesToInstall = installIntent.flowRules();
+
+        // Check if any flow rule changed
+        for (FlowRule flowRuleToInstall : flowRulesToInstall) {
+            if (flowRulesToUninstall.stream().noneMatch(flowRuleToInstall::exactMatch)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+}
\ No newline at end of file
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/ProtectionEndpointIntentInstaller.java b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/ProtectionEndpointIntentInstaller.java
new file mode 100644
index 0000000..58c24e6
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/ProtectionEndpointIntentInstaller.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.installer;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Sets;
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.behaviour.protection.ProtectedTransportEndpointDescription;
+import org.onosproject.net.behaviour.protection.ProtectionConfig;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentException;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentInstallCoordinator;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentInstaller;
+import org.onosproject.net.intent.ProtectionEndpointIntent;
+import org.onosproject.net.intent.impl.IntentManager;
+import org.onosproject.net.intent.impl.ObjectiveTrackerService;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+import java.util.stream.Collectors;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onosproject.net.config.NetworkConfigEvent.Type.*;
+import static org.onosproject.net.intent.IntentInstaller.Direction.ADD;
+import static org.onosproject.net.intent.IntentInstaller.Direction.REMOVE;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Installer for ProtectionEndpointIntent.
+ */
+@Component(immediate = true)
+public class ProtectionEndpointIntentInstaller implements IntentInstaller<ProtectionEndpointIntent> {
+    private static final String CONFIG_FAILED = "Config operation unsuccessful, expected %s, actual %s.";
+    private final Logger log = getLogger(IntentManager.class);
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected IntentExtensionService intentExtensionService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    NetworkConfigService networkConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    IntentInstallCoordinator intentInstallCoordinator;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    ObjectiveTrackerService trackerService;
+
+    @Activate
+    public void activate() {
+        intentExtensionService.registerInstaller(ProtectionEndpointIntent.class, this);
+    }
+
+    @Deactivate
+    public void deactivated() {
+        intentExtensionService.unregisterInstaller(ProtectionEndpointIntent.class);
+    }
+
+    @Override
+    public void apply(IntentOperationContext<ProtectionEndpointIntent> context) {
+        Optional<IntentData> toUninstall = context.toUninstall();
+        Optional<IntentData> toInstall = context.toInstall();
+
+        List<ProtectionEndpointIntent> uninstallIntents = context.intentsToUninstall();
+        List<ProtectionEndpointIntent> installIntents = context.intentsToInstall();
+
+        if (!toInstall.isPresent() && !toUninstall.isPresent()) {
+            intentInstallCoordinator.intentInstallSuccess(context);
+            return;
+        }
+
+        if (toUninstall.isPresent()) {
+            IntentData intentData = toUninstall.get();
+            trackerService.removeTrackedResources(intentData.key(), intentData.intent().resources());
+            uninstallIntents.forEach(installable ->
+                                             trackerService.removeTrackedResources(intentData.intent().key(),
+                                                                                   installable.resources()));
+        }
+
+        if (toInstall.isPresent()) {
+            IntentData intentData = toInstall.get();
+            trackerService.addTrackedResources(intentData.key(), intentData.intent().resources());
+            installIntents.forEach(installable ->
+                                           trackerService.addTrackedResources(intentData.key(),
+                                                                              installable.resources()));
+        }
+
+        List<Stage> stages = new ArrayList<>();
+
+        stages.add(new Stage(uninstallIntents.stream()
+                                     .map(i -> Pair.of(i, REMOVE))
+                                     .collect(Collectors.toList())));
+
+        stages.add(new Stage(installIntents.stream()
+                                     .map(i -> Pair.of(i, ADD))
+                                     .collect(Collectors.toList())));
+        for (Stage stage : stages) {
+            log.debug("applying Stage {}", stage);
+            try {
+                // wait for stage completion
+                stage.apply();
+                stage.listeners().forEach(networkConfigService::removeListener);
+            } catch (IntentException e) {
+                log.error("Stage {} failed, reason: {}", stage, e.toString());
+                intentInstallCoordinator.intentInstallFailed(context);
+                return;
+            }
+        }
+        // All stage success
+        intentInstallCoordinator.intentInstallSuccess(context);
+    }
+
+    /**
+     * Stage of installable Intents which can be processed in parallel.
+     */
+    private final class Stage {
+        // should it have progress state, how far it went?
+        private final Collection<Pair<ProtectionEndpointIntent, Direction>> ops;
+        private final Set<NetworkConfigListener> listeners = Sets.newHashSet();
+
+        /**
+         * Create a stage with given operations.
+         *
+         * @param ops the operations
+         */
+        Stage(Collection<Pair<ProtectionEndpointIntent, Direction>> ops) {
+            this.ops = checkNotNull(ops);
+        }
+
+        /**
+         * Applies all operations for this stage.
+         *
+         * @return the CompletableFuture object for this operation
+         */
+        void apply() {
+            ops.stream()
+                    .map(op -> applyOp(op.getRight(), op.getLeft()))
+                    .forEach(future -> {
+                        try {
+                            future.get(100, TimeUnit.MILLISECONDS);
+                        } catch (TimeoutException | InterruptedException | ExecutionException e) {
+                            throw new IntentException(e.toString());
+                        }
+                    });
+        }
+
+        /**
+         * Applies the protection endpoint Intent with a given direction.
+         *
+         * @param dir the direction
+         * @param intent the protection endpoint Intent
+         * @return the CompletableFuture object for this operation
+         */
+        private CompletableFuture<Void> applyOp(Direction dir, ProtectionEndpointIntent intent) {
+            log.trace("applying {}: {}", dir, intent);
+            if (dir == REMOVE) {
+                ProtectionConfigListener listener =
+                        new ProtectionConfigListener(ImmutableSet.of(CONFIG_REMOVED),
+                                                     intent.deviceId());
+                networkConfigService.addListener(listener);
+                listeners.add(listener);
+                networkConfigService.removeConfig(intent.deviceId(), ProtectionConfig.class);
+                return listener.completableFuture();
+            } else {
+                ProtectedTransportEndpointDescription description = intent.description();
+
+                // Can't do following. Will trigger empty CONFIG_ADDED
+                //ProtectionConfig cfg = networkConfigService.addConfig(intent.deviceId(),
+                //                                                      ProtectionConfig.class);
+                ProtectionConfig cfg = new ProtectionConfig(intent.deviceId());
+                cfg.fingerprint(description.fingerprint());
+                cfg.peer(description.peer());
+                cfg.paths(description.paths());
+                ProtectionConfigListener listener =
+                        new ProtectionConfigListener(ImmutableSet.of(CONFIG_ADDED, CONFIG_UPDATED),
+                                                     intent.deviceId());
+
+                networkConfigService.addListener(listener);
+                listeners.add(listener);
+                networkConfigService.applyConfig(intent.deviceId(),
+                                                 ProtectionConfig.class,
+                                                 cfg.node());
+                return listener.completableFuture();
+            }
+        }
+
+        @Override
+        public String toString() {
+            return ops.toString();
+        }
+
+        public Set<NetworkConfigListener> listeners() {
+            return listeners;
+        }
+
+        /**
+         * Listener for protection config for specific config event and device.
+         */
+        class ProtectionConfigListener implements NetworkConfigListener {
+            private CompletableFuture<Void> completableFuture;
+            private Set<NetworkConfigEvent.Type> listenTypes;
+            private DeviceId listenDevice;
+
+            public ProtectionConfigListener(Set<NetworkConfigEvent.Type> listenTypes, DeviceId listenDevice) {
+                completableFuture = new CompletableFuture<>();
+                this.listenTypes = listenTypes;
+                this.listenDevice = listenDevice;
+            }
+
+            @Override
+            public void event(NetworkConfigEvent event) {
+                if (!event.subject().equals(listenDevice)) {
+                    return;
+                }
+                if (!listenTypes.contains(event.type())) {
+                    String errorMsg = String.format(CONFIG_FAILED, listenTypes.toString(), event.type());
+                    completableFuture.completeExceptionally(new IntentException(errorMsg));
+                } else {
+                    completableFuture.complete(null);
+                }
+            }
+
+            public CompletableFuture<Void> completableFuture() {
+                return completableFuture;
+            }
+        }
+    }
+}
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/installer/package-info.java b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/package-info.java
new file mode 100644
index 0000000..b971165
--- /dev/null
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/installer/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Installers for different installable Intents.
+ */
+package org.onosproject.net.intent.impl.installer;
\ No newline at end of file
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/InstallCoordinatorTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/InstallCoordinatorTest.java
new file mode 100644
index 0000000..2bdf200
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/InstallCoordinatorTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.junit.TestTools;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentInstaller;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MockIdGenerator;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.TestInstallableIntent;
+import org.onosproject.store.intent.impl.IntentStoreAdapter;
+import org.onosproject.store.service.WallClockTimestamp;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.IntStream;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for install coordinator.
+ */
+public class InstallCoordinatorTest {
+    private static final int INSTALL_DELAY = 100;
+    private static final int INSTALL_DURATION = 1000;
+    private static final IdGenerator ID_GENERATOR = new MockIdGenerator();
+
+    private InstallCoordinator installCoordinator;
+    private InstallerRegistry installerRegistry;
+    private TestIntentStore intentStore;
+    private TestIntentInstaller intentInstaller;
+
+
+    @Before
+    public void setup() {
+        Intent.unbindIdGenerator(ID_GENERATOR);
+        Intent.bindIdGenerator(ID_GENERATOR);
+        installerRegistry = new InstallerRegistry();
+        intentStore = new TestIntentStore();
+        intentInstaller = new TestIntentInstaller();
+        installerRegistry.registerInstaller(TestInstallableIntent.class, intentInstaller);
+
+        installCoordinator = new InstallCoordinator(installerRegistry, intentStore);
+    }
+
+    @After
+    public void tearDown() {
+        installerRegistry.unregisterInstaller(TestInstallableIntent.class);
+        Intent.unbindIdGenerator(ID_GENERATOR);
+    }
+
+    /**
+     * Installs test Intents.
+     */
+    @Test
+    public void testInstallIntent() {
+        IntentData toInstall = new IntentData(createTestIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        List<Intent> intents = Lists.newArrayList();
+        IntStream.range(0, 10).forEach(val -> {
+            intents.add(new TestInstallableIntent(val));
+        });
+        toInstall = new IntentData(toInstall, intents);
+        installCoordinator.installIntents(Optional.empty(), Optional.of(toInstall));
+        Intent toInstallIntent = toInstall.intent();
+        TestTools.assertAfter(INSTALL_DELAY, INSTALL_DURATION, () -> {
+            IntentData newData = intentStore.newData;
+            assertEquals(toInstallIntent, newData.intent());
+            assertEquals(IntentState.INSTALLED, newData.state());
+            assertEquals(intents, newData.installables());
+        });
+    }
+
+    /**
+     * Uninstalls test Intents.
+     */
+    @Test
+    public void testUninstallIntent() {
+        IntentData toUninstall = new IntentData(createTestIntent(),
+                                              IntentState.WITHDRAWING,
+                                              new WallClockTimestamp());
+        List<Intent> intents = Lists.newArrayList();
+
+        IntStream.range(0, 10).forEach(val -> {
+            intents.add(new TestInstallableIntent(val));
+        });
+
+        toUninstall = new IntentData(toUninstall, intents);
+
+        installCoordinator.installIntents(Optional.of(toUninstall), Optional.empty());
+        Intent toUninstallIntent = toUninstall.intent();
+        TestTools.assertAfter(INSTALL_DELAY, INSTALL_DURATION, () -> {
+            IntentData newData = intentStore.newData;
+            assertEquals(toUninstallIntent, newData.intent());
+            assertEquals(IntentState.WITHDRAWN, newData.state());
+            assertEquals(ImmutableList.of(), newData.installables());
+        });
+
+    }
+
+    /**
+     * Do both uninstall and install test Intents.
+     */
+    @Test
+    public void testUninstallAndInstallIntent() {
+        IntentData toUninstall = new IntentData(createTestIntent(),
+                                                IntentState.INSTALLED,
+                                                new WallClockTimestamp());
+        IntentData toInstall = new IntentData(createTestIntent(),
+                                                IntentState.INSTALLING,
+                                                new WallClockTimestamp());
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = Lists.newArrayList();
+
+        IntStream.range(0, 10).forEach(val -> {
+            intentsToUninstall.add(new TestInstallableIntent(val));
+        });
+
+        IntStream.range(10, 20).forEach(val -> {
+            intentsToInstall.add(new TestInstallableIntent(val));
+        });
+
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+        toInstall = new IntentData(toInstall, intentsToInstall);
+
+        installCoordinator.installIntents(Optional.of(toUninstall), Optional.of(toInstall));
+        Intent toInstallIntent = toInstall.intent();
+
+        TestTools.assertAfter(INSTALL_DELAY, INSTALL_DURATION, () -> {
+            IntentData newData = intentStore.newData;
+            assertEquals(toInstallIntent, newData.intent());
+            assertEquals(IntentState.INSTALLED, newData.state());
+            assertEquals(intentsToInstall, newData.installables());
+        });
+    }
+
+    /**
+     * Not uninstall nor install anything.
+     */
+    @Test
+    public void testInstallNothing() {
+        installCoordinator.installIntents(Optional.empty(), Optional.empty());
+        assertNull(intentStore.newData);
+    }
+
+    /**
+     * Test Intent install failed.
+     */
+    @Test
+    public void testInstallFailed() {
+        installerRegistry.unregisterInstaller(TestInstallableIntent.class);
+        installerRegistry.registerInstaller(TestInstallableIntent.class, new TestFailedIntentInstaller());
+        IntentData toUninstall = new IntentData(createTestIntent(),
+                                                IntentState.INSTALLED,
+                                                new WallClockTimestamp());
+        IntentData toInstall = new IntentData(createTestIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = Lists.newArrayList();
+
+        IntStream.range(0, 10).forEach(val -> {
+            intentsToUninstall.add(new TestInstallableIntent(val));
+        });
+
+        IntStream.range(10, 20).forEach(val -> {
+            intentsToInstall.add(new TestInstallableIntent(val));
+        });
+
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+        toInstall = new IntentData(toInstall, intentsToInstall);
+
+        installCoordinator.installIntents(Optional.of(toUninstall), Optional.of(toInstall));
+
+        Intent toUninstallIntent = toUninstall.intent();
+        TestTools.assertAfter(INSTALL_DELAY, INSTALL_DURATION, () -> {
+            IntentData newData = intentStore.newData;
+            assertEquals(toUninstallIntent, newData.intent());
+            assertEquals(IntentState.CORRUPT, newData.state());
+            assertEquals(intentsToUninstall, newData.installables());
+        });
+    }
+
+    /**
+     * Creates a test Intent.
+     *
+     * @return the test Intent.
+     */
+    private PointToPointIntent createTestIntent() {
+        FilteredConnectPoint ingress = new FilteredConnectPoint(ConnectPoint.deviceConnectPoint("s1/1"));
+        FilteredConnectPoint egress = new FilteredConnectPoint(ConnectPoint.deviceConnectPoint("s1/2"));
+        ApplicationId appId = TestApplicationId.create("test App");
+        return PointToPointIntent.builder()
+                .filteredIngressPoint(ingress)
+                .filteredEgressPoint(egress)
+                .appId(appId)
+                .key(Key.of("Test key", appId))
+                .build();
+    }
+
+    /**
+     * Test Intent store; records the newest Intent data.
+     */
+    class TestIntentStore extends IntentStoreAdapter {
+        IntentData newData;
+        @Override
+        public void write(IntentData newData) {
+            this.newData = newData;
+        }
+    }
+
+    /**
+     * Test Intent installer; always success for every Intent operation.
+     */
+    class TestIntentInstaller implements IntentInstaller<TestInstallableIntent> {
+        @Override
+        public void apply(IntentOperationContext<TestInstallableIntent> context) {
+            installCoordinator.success(context);
+        }
+    }
+
+    /**
+     * Test Intent installer; always failed for every Intent operation.
+     */
+    class TestFailedIntentInstaller implements IntentInstaller<TestInstallableIntent> {
+        @Override
+        public void apply(IntentOperationContext<TestInstallableIntent> context) {
+            installCoordinator.failed(context);
+        }
+    }
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java
index 585d3a0..45c90e7 100644
--- a/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/IntentManagerTest.java
@@ -33,6 +33,9 @@
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.impl.TestCoreManager;
 import org.onosproject.net.NetworkResource;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleOperationsContext;
+import org.onosproject.net.flow.FlowRuleService;
 import org.onosproject.net.intent.FlowRuleIntent;
 import org.onosproject.net.intent.Intent;
 import org.onosproject.net.intent.IntentCompilationException;
@@ -42,7 +45,10 @@
 import org.onosproject.net.intent.IntentEvent.Type;
 import org.onosproject.net.intent.IntentExtensionService;
 import org.onosproject.net.intent.IntentId;
+import org.onosproject.net.intent.IntentInstallCoordinator;
+import org.onosproject.net.intent.IntentInstaller;
 import org.onosproject.net.intent.IntentListener;
+import org.onosproject.net.intent.IntentOperationContext;
 import org.onosproject.net.intent.IntentService;
 import org.onosproject.net.intent.IntentState;
 import org.onosproject.net.intent.Key;
@@ -93,8 +99,11 @@
 
     protected IntentService service;
     protected IntentExtensionService extensionService;
+    protected IntentInstallCoordinator intentInstallCoordinator;
     protected TestListener listener = new TestListener();
     protected TestIntentCompiler compiler = new TestIntentCompiler();
+    protected TestIntentInstaller installer;
+    protected TestIntentTracker trackerService = new TestIntentTracker();
 
     private static class TestListener implements IntentListener {
         final Multimap<IntentEvent.Type, IntentEvent> events = HashMultimap.create();
@@ -217,6 +226,56 @@
         }
     }
 
+    public static class TestIntentInstaller implements IntentInstaller<MockInstallableIntent> {
+
+        protected IntentExtensionService intentExtensionService;
+        protected ObjectiveTrackerService trackerService;
+        protected IntentInstallCoordinator intentInstallCoordinator;
+        protected FlowRuleService flowRuleService;
+
+        public TestIntentInstaller(IntentExtensionService intentExtensionService,
+                                   ObjectiveTrackerService trackerService,
+                                   IntentInstallCoordinator intentInstallCoordinator,
+                                   FlowRuleService flowRuleService) {
+            this.intentExtensionService = intentExtensionService;
+            this.trackerService = trackerService;
+            this.intentInstallCoordinator = intentInstallCoordinator;
+            this.flowRuleService = flowRuleService;
+        }
+
+        @Override
+        public void apply(IntentOperationContext<MockInstallableIntent> context) {
+            List<MockInstallableIntent> uninstallIntents = context.intentsToUninstall();
+            List<MockInstallableIntent> installIntents = context.intentsToInstall();
+
+            FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
+
+            uninstallIntents.stream()
+                    .map(FlowRuleIntent::flowRules)
+                    .flatMap(Collection::stream)
+                    .forEach(builder::remove);
+
+            installIntents.stream()
+                    .map(FlowRuleIntent::flowRules)
+                    .flatMap(Collection::stream)
+                    .forEach(builder::add);
+
+            FlowRuleOperationsContext ctx = new FlowRuleOperationsContext() {
+                @Override
+                public void onSuccess(FlowRuleOperations ops) {
+                    intentInstallCoordinator.intentInstallSuccess(context);
+                }
+
+                @Override
+                public void onError(FlowRuleOperations ops) {
+                    intentInstallCoordinator.intentInstallFailed(context);
+                }
+            };
+
+            flowRuleService.apply(builder.build(ctx));
+        }
+    }
+
     private static EntryForIntentMatcher hasIntentWithId(IntentId id) {
         return new EntryForIntentMatcher(id);
     }
@@ -227,17 +286,24 @@
         flowRuleService = new MockFlowRuleService();
         manager.store = new SimpleIntentStore();
         injectEventDispatcher(manager, new TestEventDispatcher());
-        manager.trackerService = new TestIntentTracker();
+        manager.trackerService = trackerService;
         manager.flowRuleService = flowRuleService;
         manager.coreService = new TestCoreManager();
         manager.configService = mock(ComponentConfigService.class);
         service = manager;
         extensionService = manager;
+        intentInstallCoordinator = manager;
+
 
         manager.activate();
         service.addListener(listener);
         extensionService.registerCompiler(MockIntent.class, compiler);
 
+        installer = new TestIntentInstaller(extensionService, trackerService,
+                                            intentInstallCoordinator, flowRuleService);
+
+        extensionService.registerInstaller(MockInstallableIntent.class, installer);
+
         assertTrue("store should be empty",
                    Sets.newHashSet(service.getIntents()).isEmpty());
         assertEquals(0L, flowRuleService.getFlowRuleCount());
@@ -269,6 +335,7 @@
     @After
     public void tearDown() {
         extensionService.unregisterCompiler(MockIntent.class);
+        extensionService.unregisterInstaller(MockInstallableIntent.class);
         service.removeListener(listener);
         manager.deactivate();
         // TODO null the other refs?
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/installer/AbstractIntentInstallerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/AbstractIntentInstallerTest.java
new file mode 100644
index 0000000..caa07be
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/AbstractIntentInstallerTest.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.installer;
+
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.IdGenerator;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.ResourceGroup;
+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.intent.Intent;
+import org.onosproject.net.intent.IntentExtensionService;
+import org.onosproject.net.intent.IntentInstallCoordinator;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.Key;
+import org.onosproject.net.intent.MockIdGenerator;
+import org.onosproject.net.intent.PointToPointIntent;
+import org.onosproject.net.intent.impl.ObjectiveTrackerService;
+
+import static org.easymock.EasyMock.createMock;
+
+/**
+ * Abstract class to hold the common variables and pieces of code for Intent
+ * installer test.
+ */
+public class AbstractIntentInstallerTest {
+    protected static final ApplicationId APP_ID = TestApplicationId.create("IntentInstallerTest");
+    protected static final ConnectPoint CP1 = ConnectPoint.deviceConnectPoint("s1/1");
+    protected static final ConnectPoint CP2 = ConnectPoint.deviceConnectPoint("s1/2");
+    protected static final ConnectPoint CP3 = ConnectPoint.deviceConnectPoint("s1/3");
+    protected static final Key KEY1 = Key.of("test intent 1", APP_ID);
+    protected static final ResourceGroup RG1 = ResourceGroup.of("test resource group 1");
+    protected static final int DEFAULT_PRIORITY = 30000;
+    protected static final IdGenerator ID_GENERATOR = new MockIdGenerator();
+
+    protected IntentExtensionService intentExtensionService;
+    protected ObjectiveTrackerService trackerService;
+    protected TestIntentInstallCoordinator intentInstallCoordinator;
+
+    public void setup() {
+        Intent.unbindIdGenerator(ID_GENERATOR);
+        Intent.bindIdGenerator(ID_GENERATOR);
+        intentExtensionService = createMock(IntentExtensionService.class);
+        trackerService = createMock(ObjectiveTrackerService.class);
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+    }
+
+    public void tearDown() {
+        Intent.unbindIdGenerator(ID_GENERATOR);
+    }
+
+    /**
+     * Creates point to point Intent for test.
+     *
+     * @return the point to point Intent
+     */
+    public PointToPointIntent createP2PIntent() {
+        PointToPointIntent intent;
+        TrafficSelector selector = DefaultTrafficSelector.emptySelector();
+        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
+
+        FilteredConnectPoint ingress = new FilteredConnectPoint(CP1);
+        FilteredConnectPoint egress = new FilteredConnectPoint(CP2);
+
+        intent = PointToPointIntent.builder()
+                .selector(selector)
+                .treatment(treatment)
+                .filteredIngressPoint(ingress)
+                .filteredEgressPoint(egress)
+                .appId(APP_ID)
+                .build();
+
+        return intent;
+    }
+
+    /**
+     * The Intent install coordinator for test.
+     * Records success and fail context.
+     */
+    class TestIntentInstallCoordinator implements IntentInstallCoordinator {
+
+        IntentOperationContext successContext;
+        IntentOperationContext failedContext;
+
+        @Override
+        public void intentInstallSuccess(IntentOperationContext context) {
+            successContext = context;
+        }
+
+        @Override
+        public void intentInstallFailed(IntentOperationContext context) {
+            failedContext = context;
+        }
+    }
+
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/installer/DomainIntentInstallerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/DomainIntentInstallerTest.java
new file mode 100644
index 0000000..2542322
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/DomainIntentInstallerTest.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.installer;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.domain.DomainIntent;
+import org.onosproject.net.domain.DomainIntentOperations;
+import org.onosproject.net.domain.DomainIntentService;
+import org.onosproject.net.domain.DomainPointToPointIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentInstallationContext;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.store.service.WallClockTimestamp;
+
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for domain Intent installer.
+ */
+public class DomainIntentInstallerTest extends AbstractIntentInstallerTest {
+    protected DomainIntentInstaller installer;
+    protected TestDomainIntentService domainIntentService;
+
+    @Before
+    public void setup() {
+        super.setup();
+        domainIntentService = new TestDomainIntentService();
+        installer = new DomainIntentInstaller();
+        installer.domainIntentService = domainIntentService;
+        installer.trackerService = trackerService;
+        installer.intentExtensionService = intentExtensionService;
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+
+        installer.activated();
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+        installer.deactivated();
+    }
+
+    /**
+     * Installs domain Intents.
+     */
+    @Test
+    public void testInstall() {
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = createDomainIntents();
+        IntentData toUninstall = null;
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentOperationContext<DomainIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+        installer.apply(operationContext);
+        assertEquals(intentInstallCoordinator.successContext, operationContext);
+    }
+
+    /**
+     * Uninstall domain Intents.
+     */
+    @Test
+    public void testUninstall() {
+        List<Intent> intentsToUninstall = createDomainIntents();
+        List<Intent> intentsToInstall = Lists.newArrayList();
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                                IntentState.WITHDRAWING,
+                                                new WallClockTimestamp());
+        IntentData toInstall = null;
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+        IntentOperationContext<DomainIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+        installer.apply(operationContext);
+        assertEquals(intentInstallCoordinator.successContext, operationContext);
+    }
+
+    /**
+     * Do both uninstall and install domain Intents.
+     */
+    @Test
+    public void testUninstallAndInstall() {
+        List<Intent> intentsToUninstall = createDomainIntents();
+        List<Intent> intentsToInstall = createAnotherDomainIntents();
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                                IntentState.INSTALLED,
+                                                new WallClockTimestamp());
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentOperationContext<DomainIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+        installer.apply(operationContext);
+        assertEquals(intentInstallCoordinator.successContext, operationContext);
+    }
+
+    /**
+     * Nothing to uninstall or install.
+     */
+    @Test
+    public void testNoAnyIntentToApply() {
+        IntentData toInstall = null;
+        IntentData toUninstall = null;
+        IntentOperationContext<DomainIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext<>(ImmutableList.of(), ImmutableList.of(), context);
+        installer.apply(operationContext);
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+    }
+
+    /**
+     * Test if domain Intent installation operations failed.
+     */
+    @Test
+    public void testInstallFailed() {
+        domainIntentService = new TestFailedDomainIntentService();
+        installer.domainIntentService = domainIntentService;
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = createDomainIntents();
+        IntentData toUninstall = null;
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentOperationContext<DomainIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+        installer.apply(operationContext);
+        assertEquals(intentInstallCoordinator.failedContext, operationContext);
+    }
+
+    /**
+     * Creates domain Intents.
+     *
+     * @return the domain Intents
+     */
+    private List<Intent> createDomainIntents() {
+        FilteredConnectPoint ingress = new FilteredConnectPoint(CP1);
+        FilteredConnectPoint egress = new FilteredConnectPoint(CP2);
+        DomainPointToPointIntent intent = DomainPointToPointIntent.builder()
+                .appId(APP_ID)
+                .key(KEY1)
+                .priority(DEFAULT_PRIORITY)
+                .filteredIngressPoint(ingress)
+                .filteredEgressPoint(egress)
+                .links(ImmutableList.of())
+                .build();
+
+        return ImmutableList.of(intent);
+    }
+
+    /**
+     * Create another domain Intents.
+     *
+     * @return the domain Intents
+     */
+    private List<Intent> createAnotherDomainIntents() {
+        FilteredConnectPoint ingress = new FilteredConnectPoint(CP1);
+        FilteredConnectPoint egress = new FilteredConnectPoint(CP3);
+        DomainPointToPointIntent intent = DomainPointToPointIntent.builder()
+                .appId(APP_ID)
+                .key(KEY1)
+                .priority(DEFAULT_PRIORITY)
+                .filteredIngressPoint(ingress)
+                .filteredEgressPoint(egress)
+                .links(ImmutableList.of())
+                .build();
+
+        return ImmutableList.of(intent);
+    }
+
+    /**
+     * Test domain Intent service; always success for all domain Intent operations.
+     */
+    class TestDomainIntentService implements DomainIntentService {
+        @Override
+        public void sumbit(DomainIntentOperations domainOperations) {
+            domainOperations.callback().onSuccess(domainOperations);
+        }
+    }
+
+    /**
+     * Test domain Intent service; always failed of any domain Intent operation.
+     */
+    class TestFailedDomainIntentService extends TestDomainIntentService {
+
+        @Override
+        public void sumbit(DomainIntentOperations domainOperations) {
+            domainOperations.callback().onError(domainOperations);
+        }
+    }
+
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/installer/FlowObjectiveIntentInstallerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/FlowObjectiveIntentInstallerTest.java
new file mode 100644
index 0000000..99f5db9
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/FlowObjectiveIntentInstallerTest.java
@@ -0,0 +1,521 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.installer;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetworkResource;
+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.flowobjective.DefaultFilteringObjective;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
+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.intent.FlowObjectiveIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentInstallationContext;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.store.service.WallClockTimestamp;
+
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.Assert.*;
+import static org.onosproject.net.flowobjective.ObjectiveError.*;
+
+/**
+ * Tests for flow objective Intent installer.
+ */
+public class FlowObjectiveIntentInstallerTest extends AbstractIntentInstallerTest {
+    private static final int NEXT_ID_1 = 1;
+    protected FlowObjectiveIntentInstaller installer;
+    protected TestFlowObjectiveService flowObjectiveService;
+
+    @Before
+    public void setup() {
+        super.setup();
+        flowObjectiveService = new TestFlowObjectiveService();
+        installer = new FlowObjectiveIntentInstaller();
+        installer.flowObjectiveService = flowObjectiveService;
+        installer.trackerService = trackerService;
+        installer.intentExtensionService = intentExtensionService;
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+
+        installer.activate();
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+        installer.deactivated();
+    }
+
+    /**
+     * Installs flow objective Intents.
+     */
+    @Test
+    public void testInstallIntent() {
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = createFlowObjectiveIntents();
+
+        IntentData toUninstall = null;
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+
+
+        IntentOperationContext<FlowObjectiveIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+    }
+
+    /**
+     * Uninstalls flow objective Intents.
+     */
+    @Test
+    public void testUninstallIntent() {
+        List<Intent> intentsToUninstall = createFlowObjectiveIntents();
+        List<Intent> intentsToInstall = Lists.newArrayList();
+
+
+        IntentData toInstall = null;
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                              IntentState.WITHDRAWING,
+                                              new WallClockTimestamp());
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+        IntentOperationContext<FlowObjectiveIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+    }
+
+    /**
+     * Do both uninstall and install flow objective Intents.
+     */
+    @Test
+    public void testUninstallAndInstallIntent() {
+        List<Intent> intentsToUninstall = createFlowObjectiveIntents();
+        List<Intent> intentsToInstall = createAnotherFlowObjectiveIntents();
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                                IntentState.INSTALLED,
+                                                new WallClockTimestamp());
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+
+        IntentOperationContext<FlowObjectiveIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+    }
+
+    /**
+     * Nothing to uninstall or install.
+     */
+    @Test
+    public void testNoAnyIntentToApply() {
+        IntentData toInstall = null;
+        IntentData toUninstall = null;
+        IntentOperationContext<FlowObjectiveIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext<>(ImmutableList.of(), ImmutableList.of(), context);
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+    }
+
+    /*
+     * Error handling
+     */
+    IntentOperationContext context;
+    IntentOperationContext failedContext;
+    IntentOperationContext successContext;
+    List<ObjectiveError> errors;
+
+    /**
+     * Handles UNSUPPORTED error.
+     */
+    @Test
+    public void testUnsupportedError() {
+        // Unsupported, should just failed
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        installer.flowObjectiveService = new TestFailedFlowObjectiveService();
+        context = createInstallContext();
+        installer.apply(context);
+        assertEquals(intentInstallCoordinator.failedContext, context);
+    }
+
+    /**
+     * Handles FLOWINSTALLATIONFAILED error with touch the threshold.
+     */
+    @Test
+    public void testFlowInstallationFailedError() {
+        // flow install failed, should retry until retry threshold
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        errors = ImmutableList.of(FLOWINSTALLATIONFAILED, FLOWINSTALLATIONFAILED,
+                                  FLOWINSTALLATIONFAILED, FLOWINSTALLATIONFAILED,
+                                  FLOWINSTALLATIONFAILED, FLOWINSTALLATIONFAILED,
+                                  FLOWINSTALLATIONFAILED);
+        installer.flowObjectiveService = new TestFailedFlowObjectiveService(errors);
+        context = createInstallContext();
+        installer.apply(context);
+        failedContext = intentInstallCoordinator.failedContext;
+        assertEquals(failedContext, context);
+    }
+
+    /**
+     * Handles FLOWINSTALLATIONFAILED error without touch the threshold.
+     */
+    @Test
+    public void testFlowInstallationFailedErrorUnderThreshold() {
+        // And retry two times and success
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        errors = ImmutableList.of(FLOWINSTALLATIONFAILED, FLOWINSTALLATIONFAILED);
+        installer.flowObjectiveService = new TestFailedFlowObjectiveService(errors);
+        context = createInstallContext();
+        installer.apply(context);
+        successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, context);
+    }
+
+    /**
+     * Handles GROUPINSTALLATIONFAILED error with touch the threshold.
+     */
+    @Test
+    public void testGroupInstallationFailedError() {
+        // Group install failed, and retry threshold exceed
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        errors = ImmutableList.of(GROUPINSTALLATIONFAILED, GROUPINSTALLATIONFAILED,
+                                  GROUPINSTALLATIONFAILED, GROUPINSTALLATIONFAILED,
+                                  GROUPINSTALLATIONFAILED, GROUPINSTALLATIONFAILED,
+                                  GROUPINSTALLATIONFAILED);
+        installer.flowObjectiveService = new TestFailedFlowObjectiveService(errors);
+        context = createInstallContext();
+        installer.apply(context);
+        failedContext = intentInstallCoordinator.failedContext;
+        assertEquals(failedContext, context);
+
+    }
+
+    /**
+     * Handles GROUPINSTALLATIONFAILED error without touch the threshold.
+     */
+    @Test
+    public void testGroupInstallationFailedErrorUnderThreshold() {
+        // group install failed, and retry two times.
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        errors = ImmutableList.of(GROUPINSTALLATIONFAILED, GROUPINSTALLATIONFAILED);
+        installer.flowObjectiveService = new TestFailedFlowObjectiveService(errors);
+        context = createInstallContext();
+        installer.apply(context);
+        successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, context);
+
+    }
+
+    /**
+     * Handles GROUPEXISTS error.
+     */
+    @Test
+    public void testGroupExistError() {
+        // group exists, retry by using add to exist
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        errors = ImmutableList.of(GROUPEXISTS);
+        installer.flowObjectiveService = new TestFailedFlowObjectiveService(errors);
+        context = createInstallContext();
+        installer.apply(context);
+        successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, context);
+    }
+
+    /**
+     * Handles GROUPMISSING error with ADD_TO_EXIST operation.
+     */
+    @Test
+    public void testGroupMissingError() {
+        // group exist -> group missing -> add group
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        errors = ImmutableList.of(GROUPEXISTS, GROUPMISSING);
+        installer.flowObjectiveService = new TestFailedFlowObjectiveService(errors);
+        context = createInstallContext();
+        installer.apply(context);
+        successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, context);
+    }
+
+    /**
+     * Handles GROUPMISSING error with ADD operation.
+     */
+    @Test
+    public void testGroupChainElementMissingError() {
+        // group chain element missing
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        errors = ImmutableList.of(GROUPMISSING);
+        installer.flowObjectiveService = new TestFailedFlowObjectiveService(errors);
+        context = createInstallContext();
+        installer.apply(context);
+        successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, context);
+    }
+
+    /**
+     * Handles GROUPMISSING error with REMOVE operation.
+     */
+    @Test
+    public void testGroupAlreadyRemoved() {
+        // group already removed
+        intentInstallCoordinator = new TestIntentInstallCoordinator();
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        errors = ImmutableList.of(GROUPMISSING);
+        installer.flowObjectiveService = new TestFailedFlowObjectiveService(errors);
+        context = createUninstallContext();
+        installer.apply(context);
+        successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, context);
+    }
+
+    /**
+     * Creates Intent operation context for uninstall Intents.
+     *
+     * @return the context
+     */
+    private IntentOperationContext createUninstallContext() {
+        List<Intent> intentsToUninstall = createFlowObjectiveIntents();
+        List<Intent> intentsToInstall = Lists.newArrayList();
+        IntentData toInstall = null;
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        return new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+    }
+
+    /**
+     * Creates Intent operation context for install Intents.
+     *
+     * @return the context
+     */
+    private IntentOperationContext createInstallContext() {
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = createFlowObjectiveIntents();
+        IntentData toUninstall = null;
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        return new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+    }
+
+    /**
+     * Creates flow objective Intents.
+     *
+     * @return the flow objective intents
+     */
+    private List<Intent> createFlowObjectiveIntents() {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPort(CP1.port())
+                .build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(CP2.port())
+                .build();
+
+        FilteringObjective filt = DefaultFilteringObjective.builder()
+                .addCondition(selector.getCriterion(Criterion.Type.IN_PORT))
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(APP_ID)
+                .permit()
+                .add();
+
+        NextObjective next = DefaultNextObjective.builder()
+                .withMeta(selector)
+                .addTreatment(treatment)
+                .makePermanent()
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(APP_ID)
+                .withType(NextObjective.Type.SIMPLE)
+                .withId(NEXT_ID_1)
+                .add();
+
+        ForwardingObjective fwd = DefaultForwardingObjective.builder()
+                .withSelector(selector)
+                .fromApp(APP_ID)
+                .withPriority(DEFAULT_PRIORITY)
+                .makePermanent()
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .nextStep(NEXT_ID_1)
+                .add();
+
+        List<Objective> objectives = ImmutableList.of(filt, next, fwd);
+        List<DeviceId> deviceIds = ImmutableList.of(CP1.deviceId(), CP1.deviceId(), CP1.deviceId());
+        List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
+
+        Intent intent = new FlowObjectiveIntent(APP_ID, KEY1, deviceIds, objectives, resources, RG1);
+        return ImmutableList.of(intent);
+    }
+
+    /**
+     * Creates flow objective Intents with different selector.
+     *
+     * @return the flow objective Intents
+     */
+    private List<Intent> createAnotherFlowObjectiveIntents() {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchVlanId(VlanId.vlanId("100"))
+                .matchInPort(CP1.port())
+                .build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(CP2.port())
+                .build();
+
+        FilteringObjective filt = DefaultFilteringObjective.builder()
+                .addCondition(selector.getCriterion(Criterion.Type.IN_PORT))
+                .addCondition(selector.getCriterion(Criterion.Type.VLAN_VID))
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(APP_ID)
+                .permit()
+                .add();
+
+        NextObjective next = DefaultNextObjective.builder()
+                .withMeta(selector)
+                .addTreatment(treatment)
+                .makePermanent()
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(APP_ID)
+                .withType(NextObjective.Type.SIMPLE)
+                .withId(NEXT_ID_1)
+                .add();
+
+        ForwardingObjective fwd = DefaultForwardingObjective.builder()
+                .withSelector(selector)
+                .fromApp(APP_ID)
+                .withPriority(DEFAULT_PRIORITY)
+                .makePermanent()
+                .withFlag(ForwardingObjective.Flag.SPECIFIC)
+                .nextStep(NEXT_ID_1)
+                .add();
+
+        List<Objective> objectives = ImmutableList.of(filt, next, fwd);
+        List<DeviceId> deviceIds = ImmutableList.of(CP1.deviceId(), CP1.deviceId(), CP1.deviceId());
+        List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
+
+        Intent intent = new FlowObjectiveIntent(APP_ID, KEY1, deviceIds, objectives, resources, RG1);
+        return ImmutableList.of(intent);
+    }
+
+    /**
+     * Flow objective service for test; always successful for every flow objectives.
+     */
+    class TestFlowObjectiveService extends FlowObjectiveServiceAdapter {
+        List<DeviceId> devices = Lists.newArrayList();
+        List<Objective> objectives = Lists.newArrayList();
+
+        @Override
+        public void apply(DeviceId deviceId, Objective objective) {
+            devices.add(deviceId);
+            objectives.add(objective);
+            objective.context().ifPresent(context -> context.onSuccess(objective));
+        }
+    }
+
+    /**
+     * Flow objective service for test; contains errors for every flow objective
+     * submission.
+     */
+    class TestFailedFlowObjectiveService extends TestFlowObjectiveService {
+        private final Set<ObjectiveError> groupErrors =
+                ImmutableSet.of(GROUPEXISTS, GROUPINSTALLATIONFAILED,
+                                GROUPMISSING, GROUPREMOVALFAILED);
+
+        /**
+         * Error states to test error handler by given error queue
+         * e.g.
+         * FLOWINSTALLATIONFAILED -> FLOWINSTALLATIONFAILED -> null: should be success
+         * FLOWINSTALLATIONFAILED -> five same error -> ....       : should be failed
+         */
+        List<ObjectiveError> errors;
+
+        public TestFailedFlowObjectiveService() {
+            errors = Lists.newArrayList();
+            errors.add(UNSUPPORTED);
+        }
+
+        public TestFailedFlowObjectiveService(List<ObjectiveError> errors) {
+            this.errors = Lists.newArrayList(errors);
+        }
+
+        @Override
+        public void apply(DeviceId deviceId, Objective objective) {
+            if (errors.size() != 0) {
+                if (groupErrors.contains(errors.get(0)) && objective instanceof NextObjective) {
+                    ObjectiveError error = errors.remove(0);
+                    objective.context().ifPresent(context -> context.onError(objective, error));
+                    return;
+                }
+                if (!groupErrors.contains(errors.get(0)) && !(objective instanceof NextObjective)) {
+                    ObjectiveError error = errors.remove(0);
+                    objective.context().ifPresent(context -> context.onError(objective, error));
+                    return;
+                }
+            }
+            objective.context().ifPresent(context -> context.onSuccess(objective));
+
+        }
+    }
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstallerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstallerTest.java
new file mode 100644
index 0000000..418392b
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/FlowRuleIntentInstallerTest.java
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.installer;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.NetworkResource;
+import org.onosproject.net.flow.DefaultFlowRule;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.FlowRuleOperations;
+import org.onosproject.net.flow.FlowRuleServiceAdapter;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.intent.FlowRuleIntent;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentInstallationContext;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.PathIntent;
+import org.onosproject.store.service.WallClockTimestamp;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.*;
+
+/**
+ * Tests for flow rule Intent installer.
+ */
+public class FlowRuleIntentInstallerTest extends AbstractIntentInstallerTest {
+
+    private TestFlowRuleService flowRuleService;
+    private FlowRuleIntentInstaller installer;
+
+    @Before
+    public void setup() {
+        super.setup();
+        flowRuleService = new TestFlowRuleService();
+        installer = new FlowRuleIntentInstaller();
+        installer.flowRuleService = flowRuleService;
+        installer.intentExtensionService = intentExtensionService;
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        installer.trackerService = trackerService;
+
+        installer.activate();
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+        installer.deactivated();
+    }
+
+    /**
+     * Installs Intents only, no Intents to be uninstall.
+     */
+    @Test
+    public void testInstallOnly() {
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = createFlowRuleIntents();
+
+        IntentData toUninstall = null;
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+
+
+        IntentOperationContext<FlowRuleIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+
+        Set<FlowRule> expectedFlowRules = intentsToInstall.stream()
+                .map(intent -> (FlowRuleIntent) intent)
+                .map(FlowRuleIntent::flowRules)
+                .flatMap(Collection::stream)
+                .collect(Collectors.toSet());
+
+        assertEquals(expectedFlowRules, flowRuleService.flowRulesAdd);
+    }
+
+    /**
+     * Uninstalls Intents only, no Intents to be install.
+     */
+    @Test
+    public void testUninstallOnly() {
+        List<Intent> intentsToInstall = Lists.newArrayList();
+        List<Intent> intentsToUninstall = createFlowRuleIntents();
+
+        IntentData toInstall = null;
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                              IntentState.WITHDRAWING,
+                                              new WallClockTimestamp());
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+
+
+        IntentOperationContext<FlowRuleIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+
+        Set<FlowRule> expectedFlowRules = intentsToUninstall.stream()
+                .map(intent -> (FlowRuleIntent) intent)
+                .map(FlowRuleIntent::flowRules)
+                .flatMap(Collection::stream)
+                .collect(Collectors.toSet());
+
+        assertEquals(expectedFlowRules, flowRuleService.flowRulesRemove);
+    }
+
+    /**
+     * Do both install and uninstall Intents with different flow rules.
+     */
+    @Test
+    public void testUninstallAndInstall() {
+        List<Intent> intentsToInstall = createAnotherFlowRuleIntents();
+        List<Intent> intentsToUninstall = createFlowRuleIntents();
+
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                                IntentState.INSTALLED,
+                                                new WallClockTimestamp());
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+
+        IntentOperationContext<FlowRuleIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+
+        Set<FlowRule> expectedFlowRules = intentsToUninstall.stream()
+                .map(intent -> (FlowRuleIntent) intent)
+                .map(FlowRuleIntent::flowRules)
+                .flatMap(Collection::stream)
+                .collect(Collectors.toSet());
+
+        assertEquals(expectedFlowRules, flowRuleService.flowRulesRemove);
+
+        expectedFlowRules = intentsToInstall.stream()
+                .map(intent -> (FlowRuleIntent) intent)
+                .map(FlowRuleIntent::flowRules)
+                .flatMap(Collection::stream)
+                .collect(Collectors.toSet());
+
+        assertEquals(expectedFlowRules, flowRuleService.flowRulesAdd);
+    }
+
+    /**
+     * Do both install and uninstall Intents with same flow rules.
+     */
+    @Test
+    public void testUninstallAndInstallUnchanged() {
+        List<Intent> intentsToInstall = createFlowRuleIntents();
+        List<Intent> intentsToUninstall = createFlowRuleIntents();
+
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                                IntentState.INSTALLED,
+                                                new WallClockTimestamp());
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+
+        IntentOperationContext<FlowRuleIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+
+        assertEquals(0, flowRuleService.flowRulesRemove.size());
+        assertEquals(0, flowRuleService.flowRulesAdd.size());
+    }
+
+    /**
+     * Do both install and uninstall Intents with same flow rule Intent.
+     */
+    @Test
+    public void testUninstallAndInstallSame() {
+        List<Intent> intentsToInstall = createFlowRuleIntents();
+        List<Intent> intentsToUninstall = intentsToInstall;
+
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                                IntentState.INSTALLED,
+                                                new WallClockTimestamp());
+        toUninstall = new IntentData(toUninstall, intentsToUninstall);
+
+        IntentOperationContext<FlowRuleIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+
+        assertEquals(0, flowRuleService.flowRulesRemove.size());
+        assertEquals(0, flowRuleService.flowRulesAdd.size());
+    }
+
+    /**
+     * Nothing to uninstall or install.
+     */
+    @Test
+    public void testNoAnyIntentToApply() {
+        IntentData toInstall = null;
+        IntentData toUninstall = null;
+        IntentOperationContext<FlowRuleIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext<>(ImmutableList.of(), ImmutableList.of(), context);
+        installer.apply(operationContext);
+
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+
+        assertEquals(0, flowRuleService.flowRulesRemove.size());
+        assertEquals(0, flowRuleService.flowRulesAdd.size());
+    }
+
+    /**
+     * Test if the flow installation failed.
+     */
+    @Test
+    public void testFailed() {
+        installer.flowRuleService = new TestFailedFlowRuleService();
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = createFlowRuleIntents();
+
+        IntentData toUninstall = null;
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+
+
+        IntentOperationContext<FlowRuleIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+
+        installer.apply(operationContext);
+
+        IntentOperationContext failedContext = intentInstallCoordinator.failedContext;
+        assertEquals(failedContext, operationContext);
+    }
+
+    /**
+     * Generates FlowRuleIntents for test.
+     *
+     * @return the FlowRuleIntents for test
+     */
+    public List<Intent> createFlowRuleIntents() {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchInPhyPort(CP1.port())
+                .build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(CP2.port())
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .forDevice(CP1.deviceId())
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .fromApp(APP_ID)
+                .withPriority(DEFAULT_PRIORITY)
+                .makePermanent()
+                .build();
+
+        List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
+
+        FlowRuleIntent intent = new FlowRuleIntent(APP_ID,
+                                                   KEY1,
+                                                   ImmutableList.of(flowRule),
+                                                   resources,
+                                                   PathIntent.ProtectionType.PRIMARY,
+                                                   RG1);
+
+        List<Intent> flowRuleIntents = Lists.newArrayList();
+        flowRuleIntents.add(intent);
+
+        return flowRuleIntents;
+    }
+
+    /**
+     * Generates another different FlowRuleIntents for test.
+     *
+     * @return the FlowRuleIntents for test
+     */
+    public List<Intent> createAnotherFlowRuleIntents() {
+        TrafficSelector selector = DefaultTrafficSelector.builder()
+                .matchVlanId(VlanId.vlanId("100"))
+                .matchInPhyPort(CP1.port())
+                .build();
+        TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                .setOutput(CP2.port())
+                .build();
+
+        FlowRule flowRule = DefaultFlowRule.builder()
+                .forDevice(CP1.deviceId())
+                .withSelector(selector)
+                .withTreatment(treatment)
+                .fromApp(APP_ID)
+                .withPriority(DEFAULT_PRIORITY)
+                .makePermanent()
+                .build();
+
+        List<NetworkResource> resources = ImmutableList.of(CP1.deviceId());
+
+        FlowRuleIntent intent = new FlowRuleIntent(APP_ID,
+                                                   KEY1,
+                                                   ImmutableList.of(flowRule),
+                                                   resources,
+                                                   PathIntent.ProtectionType.PRIMARY,
+                                                   RG1);
+
+        List<Intent> flowRuleIntents = Lists.newArrayList();
+        flowRuleIntents.add(intent);
+
+        return flowRuleIntents;
+    }
+
+    /**
+     * The FlowRuleService for test; always success for any flow rule operations.
+     */
+    class TestFlowRuleService extends FlowRuleServiceAdapter {
+
+        Set<FlowRule> flowRulesAdd = Sets.newHashSet();
+        Set<FlowRule> flowRulesRemove = Sets.newHashSet();
+
+        public void record(FlowRuleOperations ops) {
+            flowRulesAdd.clear();
+            flowRulesRemove.clear();
+            ops.stages().forEach(stage -> {
+                stage.forEach(op -> {
+                    switch (op.type()) {
+                        case ADD:
+                            flowRulesAdd.add(op.rule());
+                            break;
+                        case REMOVE:
+                            flowRulesRemove.add(op.rule());
+                            break;
+                        default:
+                            break;
+                    }
+                });
+            });
+        }
+
+        @Override
+        public void apply(FlowRuleOperations ops) {
+            record(ops);
+            ops.callback().onSuccess(ops);
+        }
+    }
+
+    /**
+     * The FlowRuleService for test; always failed for any flow rule operations.
+     */
+    class TestFailedFlowRuleService extends TestFlowRuleService {
+        @Override
+        public void apply(FlowRuleOperations ops) {
+            record(ops);
+            ops.callback().onError(ops);
+        }
+    }
+
+}
diff --git a/core/net/src/test/java/org/onosproject/net/intent/impl/installer/ProtectionEndpointIntentInstallerTest.java b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/ProtectionEndpointIntentInstallerTest.java
new file mode 100644
index 0000000..53851da
--- /dev/null
+++ b/core/net/src/test/java/org/onosproject/net/intent/impl/installer/ProtectionEndpointIntentInstallerTest.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.net.intent.impl.installer;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onlab.junit.TestUtils;
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.osgi.TestServiceDirectory;
+import org.onosproject.codec.CodecService;
+import org.onosproject.codec.impl.CodecManager;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
+import org.onosproject.net.behaviour.protection.ProtectedTransportEndpointDescription;
+import org.onosproject.net.behaviour.protection.TransportEndpointDescription;
+import org.onosproject.net.config.BaseConfig;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.NetworkConfigServiceAdapter;
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentInstallationContext;
+import org.onosproject.net.intent.IntentOperationContext;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.ProtectionEndpointIntent;
+import org.onosproject.store.service.WallClockTimestamp;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.CompletableFuture;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for protection endpoint Intent installer.
+ */
+public class ProtectionEndpointIntentInstallerTest extends AbstractIntentInstallerTest {
+    private static final String FINGERPRINT = "Test fingerprint";
+    protected ProtectionEndpointIntentInstaller installer;
+    protected NetworkConfigService networkConfigService;
+    private static TestServiceDirectory directory;
+    private static ServiceDirectory original;
+
+    @BeforeClass
+    public static void setUpClass() throws TestUtils.TestUtilsException {
+        directory = new TestServiceDirectory();
+
+        CodecManager codecService = new CodecManager();
+        codecService.activate();
+        directory.add(CodecService.class, codecService);
+
+        // replace service directory used by BaseConfig
+        original = TestUtils.getField(BaseConfig.class, "services");
+        TestUtils.setField(BaseConfig.class, "services", directory);
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws TestUtils.TestUtilsException {
+        TestUtils.setField(BaseConfig.class, "services", original);
+    }
+
+    @Before
+    public void setup() {
+        super.setup();
+        networkConfigService = new TestNetworkConfigService();
+        installer = new ProtectionEndpointIntentInstaller();
+        installer.networkConfigService = networkConfigService;
+        installer.intentExtensionService = intentExtensionService;
+        installer.intentInstallCoordinator = intentInstallCoordinator;
+        installer.trackerService = trackerService;
+
+        installer.activate();
+    }
+
+    @After
+    public void tearDown() {
+        super.tearDown();
+        installer.deactivated();
+    }
+
+    /**
+     * Installs protection endpoint Intents.
+     * framework.
+     */
+    @Test
+    public void testInstallIntents() {
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = createProtectionIntents(CP2);
+        IntentData toUninstall = null;
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentOperationContext<ProtectionEndpointIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+        installer.apply(operationContext);
+        assertEquals(intentInstallCoordinator.successContext, operationContext);
+    }
+
+    /**
+     * Uninstalls protection endpoint Intents.
+     * framework.
+     */
+    @Test
+    public void testUninstallIntents() {
+        List<Intent> intentsToUninstall = createProtectionIntents(CP2);
+        List<Intent> intentsToInstall = Lists.newArrayList();
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                                IntentState.INSTALLING,
+                                                new WallClockTimestamp());
+        IntentData toInstall = null;
+        IntentOperationContext<ProtectionEndpointIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+        installer.apply(operationContext);
+        assertEquals(intentInstallCoordinator.successContext, operationContext);
+    }
+
+    /**
+     * Test both uninstall and install protection endpoint Intents.
+     * framework.
+     */
+    @Test
+    public void testUninstallAndInstallIntents() {
+        List<Intent> intentsToUninstall = createProtectionIntents(CP2);
+        List<Intent> intentsToInstall = createProtectionIntents(CP3);
+        IntentData toUninstall = new IntentData(createP2PIntent(),
+                                                IntentState.INSTALLED,
+                                                new WallClockTimestamp());
+        toUninstall = new IntentData(toUninstall, intentsToInstall);
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentOperationContext<ProtectionEndpointIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+        installer.apply(operationContext);
+        assertEquals(intentInstallCoordinator.successContext, operationContext);
+    }
+
+    /**
+     * Nothing to uninstall or install.
+     */
+    @Test
+    public void testNoAnyIntentToApply() {
+        IntentData toInstall = null;
+        IntentData toUninstall = null;
+        IntentOperationContext<ProtectionEndpointIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext<>(ImmutableList.of(), ImmutableList.of(), context);
+        installer.apply(operationContext);
+        IntentOperationContext successContext = intentInstallCoordinator.successContext;
+        assertEquals(successContext, operationContext);
+    }
+
+    /**
+     * Test if installation failed.
+     * framework.
+     */
+    @Test
+    public void testInstallFailed() {
+        networkConfigService = new TestFailedNetworkConfigService();
+        installer.networkConfigService = networkConfigService;
+        List<Intent> intentsToUninstall = Lists.newArrayList();
+        List<Intent> intentsToInstall = createProtectionIntents(CP2);
+        IntentData toUninstall = null;
+        IntentData toInstall = new IntentData(createP2PIntent(),
+                                              IntentState.INSTALLING,
+                                              new WallClockTimestamp());
+        toInstall = new IntentData(toInstall, intentsToInstall);
+        IntentOperationContext<ProtectionEndpointIntent> operationContext;
+        IntentInstallationContext context = new IntentInstallationContext(toUninstall, toInstall);
+        operationContext = new IntentOperationContext(intentsToUninstall, intentsToInstall, context);
+        installer.apply(operationContext);
+        assertEquals(intentInstallCoordinator.failedContext, operationContext);
+    }
+
+    /**
+     * Creates protection endpoint Intents by givent output point.
+     *
+     * @param output the output point
+     * @return the protection endpoint Intents
+     */
+    private List<Intent> createProtectionIntents(ConnectPoint output) {
+        FilteredConnectPoint filteredOutput = new FilteredConnectPoint(output);
+        TransportEndpointDescription path = TransportEndpointDescription.builder()
+                .withOutput(filteredOutput)
+                .withEnabled(true).build();
+
+        List<TransportEndpointDescription> paths = ImmutableList.of(path);
+        ProtectedTransportEndpointDescription description =
+                ProtectedTransportEndpointDescription.of(paths, CP2.deviceId(), FINGERPRINT);
+        ProtectionEndpointIntent intent = ProtectionEndpointIntent.builder()
+                .appId(APP_ID)
+                .description(description)
+                .deviceId(CP1.deviceId())
+                .key(KEY1)
+                .resourceGroup(RG1)
+                .build();
+
+        return ImmutableList.of(intent);
+    }
+
+    class TestNetworkConfigService extends NetworkConfigServiceAdapter {
+        protected Set<NetworkConfigListener> listeners = Sets.newHashSet();
+
+        @Override
+        public void addListener(NetworkConfigListener listener) {
+            listeners.add(listener);
+        }
+
+        @Override
+        public void removeListener(NetworkConfigListener listener) {
+            listeners.remove(listener);
+        }
+
+        @Override
+        public <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, JsonNode json) {
+            NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
+                                                              subject,
+                                                              configClass);
+            CompletableFuture.runAsync(() -> {
+                listeners.forEach(listener -> listener.event(event));
+            });
+            return null;
+        }
+
+        @Override
+        public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) {
+            NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_REMOVED,
+                                                              subject,
+                                                              configClass);
+            CompletableFuture.runAsync(() -> {
+                listeners.forEach(listener -> listener.event(event));
+            });
+        }
+    }
+
+    /**
+     * Test network config service; will send wrong events to listeners.
+     */
+    class TestFailedNetworkConfigService extends TestNetworkConfigService {
+
+        @Override
+        public <S, C extends Config<S>> C applyConfig(S subject, Class<C> configClass, JsonNode json) {
+            NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_REMOVED,
+                                                              subject,
+                                                              configClass);
+            CompletableFuture.runAsync(() -> {
+                listeners.forEach(listener -> listener.event(event));
+            });
+            return null;
+        }
+
+        @Override
+        public <S, C extends Config<S>> void removeConfig(S subject, Class<C> configClass) {
+            NetworkConfigEvent event = new NetworkConfigEvent(NetworkConfigEvent.Type.CONFIG_ADDED,
+                                                              subject,
+                                                              configClass);
+            CompletableFuture.runAsync(() -> {
+                listeners.forEach(listener -> listener.event(event));
+            });
+        }
+    }
+}
diff --git a/core/store/dist/src/test/java/org/onosproject/store/intent/impl/IntentStoreAdapter.java b/core/store/dist/src/test/java/org/onosproject/store/intent/impl/IntentStoreAdapter.java
new file mode 100644
index 0000000..131a1ed
--- /dev/null
+++ b/core/store/dist/src/test/java/org/onosproject/store/intent/impl/IntentStoreAdapter.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.store.intent.impl;
+
+import org.onosproject.net.intent.Intent;
+import org.onosproject.net.intent.IntentData;
+import org.onosproject.net.intent.IntentState;
+import org.onosproject.net.intent.IntentStore;
+import org.onosproject.net.intent.IntentStoreDelegate;
+import org.onosproject.net.intent.Key;
+
+import java.util.List;
+
+/**
+ * Adapter for IntentStore.
+ */
+public class IntentStoreAdapter implements IntentStore {
+    @Override
+    public long getIntentCount() {
+        return 0;
+    }
+
+    @Override
+    public Iterable<Intent> getIntents() {
+        return null;
+    }
+
+    @Override
+    public Iterable<IntentData> getIntentData(boolean localOnly, long olderThan) {
+        return null;
+    }
+
+    @Override
+    public IntentState getIntentState(Key intentKey) {
+        return null;
+    }
+
+    @Override
+    public List<Intent> getInstallableIntents(Key intentKey) {
+        return null;
+    }
+
+    @Override
+    public void write(IntentData newData) {
+
+    }
+
+    @Override
+    public void batchWrite(Iterable<IntentData> updates) {
+
+    }
+
+    @Override
+    public Intent getIntent(Key key) {
+        return null;
+    }
+
+    @Override
+    public IntentData getIntentData(Key key) {
+        return null;
+    }
+
+    @Override
+    public void addPending(IntentData intent) {
+
+    }
+
+    @Override
+    public boolean isMaster(Key intentKey) {
+        return false;
+    }
+
+    @Override
+    public Iterable<Intent> getPending() {
+        return null;
+    }
+
+    @Override
+    public Iterable<IntentData> getPendingData() {
+        return null;
+    }
+
+    @Override
+    public IntentData getPendingData(Key intentKey) {
+        return null;
+    }
+
+    @Override
+    public Iterable<IntentData> getPendingData(boolean localOnly, long olderThan) {
+        return null;
+    }
+
+    @Override
+    public void setDelegate(IntentStoreDelegate delegate) {
+
+    }
+
+    @Override
+    public void unsetDelegate(IntentStoreDelegate delegate) {
+
+    }
+
+    @Override
+    public boolean hasDelegate() {
+        return false;
+    }
+}
