Refactor connectivity intent creation to use builders

- Each connectivity intent now has only one constructor
- Intent constructors are now private for leaf classes and
  protected for classes that can be derived from
- Each intent class has a Builder class that accumulates
  parameters for intent creation
- Each intent class has a public static builder() method
  to create a builder
- Each Builder class has a build() method to create the
  intent from the accumulated parameters
- Added keys to a few intent types that were missing them
- Tightened up usage of checkNotNull(), taking advantage of
  the return value to save some lines of code
- Modified callers to use the builders instead of directly
  calling the constructors

Change-Id: I713185d5ecbadbf51f87ef7f68fec41102106c78
diff --git a/core/api/src/main/java/org/onosproject/net/intent/ConnectivityIntent.java b/core/api/src/main/java/org/onosproject/net/intent/ConnectivityIntent.java
index 9d0a228..94e3b1a 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/ConnectivityIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/ConnectivityIntent.java
@@ -77,34 +77,6 @@
     }
 
     /**
-     * Creates a connectivity intent that matches on the specified selector
-     * and applies the specified treatment.
-     * <p>
-     * Path will be optimized based on the first constraint if one is given.
-     * </p>
-     *
-     * @param appId       application identifier
-     * @param resources   required network resources (optional)
-     * @param selector    traffic selector
-     * @param treatment   treatment
-     * @param constraints optional prioritized list of constraints
-     * @param priority    priority to use for flows generated by this intent
-     * @throws NullPointerException if the selector or treatment is null
-     */
-
-    protected ConnectivityIntent(ApplicationId appId,
-                                 Collection<NetworkResource> resources,
-                                 TrafficSelector selector,
-                                 TrafficTreatment treatment,
-                                 List<Constraint> constraints,
-                                 int priority) {
-        super(appId, null, resources, priority);
-        this.selector = checkNotNull(selector);
-        this.treatment = checkNotNull(treatment);
-        this.constraints = checkNotNull(constraints);
-    }
-
-    /**
      * Constructor for serializer.
      */
     protected ConnectivityIntent() {
diff --git a/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java b/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java
index 9b00512..157397a 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/HostToHostIntent.java
@@ -15,20 +15,16 @@
  */
 package org.onosproject.net.intent;
 
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableList;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.HostId;
-import org.onosproject.net.Link;
-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.constraint.LinkTypeConstraint;
-
 import java.util.Collections;
 import java.util.List;
 
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+
+import com.google.common.base.MoreObjects;
+
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
@@ -40,59 +36,98 @@
     private final HostId two;
 
     /**
-     * Creates a new host-to-host intent with the supplied host pair and no
-     * other traffic selection or treatment criteria.
+     * Returns a new host to host intent builder.
      *
-     * @param appId     application identifier
-     * @param one       first host
-     * @param two       second host
-     * @throws NullPointerException if {@code one} or {@code two} is null.
+     * @return host to host intent builder
      */
-    public HostToHostIntent(ApplicationId appId, HostId one, HostId two) {
-        this(appId, one, two,
-             DefaultTrafficSelector.emptySelector(),
-             DefaultTrafficTreatment.emptyTreatment(),
-             ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)),
-             DEFAULT_INTENT_PRIORITY);
+    public static Builder builder() {
+        return new Builder();
     }
 
     /**
-     * Creates a new host-to-host intent with the supplied host pair.
-     *
-     * @param appId     application identifier
-     * @param one       first host
-     * @param two       second host
-     * @param selector  action
-     * @param treatment ingress port
-     * @throws NullPointerException if {@code one} or {@code two} is null.
+     * Builder of a host to host intent.
      */
-    public HostToHostIntent(ApplicationId appId, HostId one, HostId two,
-                            TrafficSelector selector,
-                            TrafficTreatment treatment) {
-        this(appId, one, two, selector, treatment,
-             ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)),
-             DEFAULT_INTENT_PRIORITY);
+    public static final class Builder extends ConnectivityIntent.Builder {
+        HostId one;
+        HostId two;
+
+        private Builder() {
+            // Hide constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        /**
+         * Sets the first host of the intent that will be built.
+         *
+         * @param one first host
+         * @return this builder
+         */
+        public Builder one(HostId one) {
+            this.one = one;
+            return this;
+        }
+
+        /**
+         * Sets the second host of the intent that will be built.
+         *
+         * @param two second host
+         * @return this builder
+         */
+        public Builder two(HostId two) {
+            this.two = two;
+            return this;
+        }
+
+        /**
+         * Builds a host to host intent from the accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public HostToHostIntent build() {
+
+            return new HostToHostIntent(
+                    appId,
+                    key,
+                    one,
+                    two,
+                    selector,
+                    treatment,
+                    constraints,
+                    priority
+            );
+        }
     }
 
-    /**
-     * Creates a new host-to-host intent with the supplied host pair.
-     *
-     * @param appId       application identifier
-     * @param one         first host
-     * @param two         second host
-     * @param selector    action
-     * @param treatment   ingress port
-     * @param constraints optional prioritized list of path selection constraints
-     * @param priority    priority to use for flows generated by this intent
-     * @throws NullPointerException if {@code one} or {@code two} is null.
-     */
-    public HostToHostIntent(ApplicationId appId, HostId one, HostId two,
-                            TrafficSelector selector,
-                            TrafficTreatment treatment,
-                            List<Constraint> constraints,
-                            int priority) {
-        this(appId, null, one, two, selector, treatment, constraints, priority);
-    }
+
     /**
      * Creates a new host-to-host intent with the supplied host pair.
      *
@@ -106,7 +141,7 @@
      * @param priority    priority to use for flows generated by this intent
      * @throws NullPointerException if {@code one} or {@code two} is null.
      */
-    public HostToHostIntent(ApplicationId appId, Key key,
+    private HostToHostIntent(ApplicationId appId, Key key,
                             HostId one, HostId two,
                             TrafficSelector selector,
                             TrafficTreatment treatment,
@@ -121,14 +156,6 @@
 
     }
 
-    private static HostId min(HostId one, HostId two) {
-        return one.hashCode() < two.hashCode() ? one : two;
-    }
-
-    private static HostId max(HostId one, HostId two) {
-        return one.hashCode() >= two.hashCode() ? one : two;
-    }
-
     /**
      * Returns identifier of the first host.
      *
diff --git a/core/api/src/main/java/org/onosproject/net/intent/Intent.java b/core/api/src/main/java/org/onosproject/net/intent/Intent.java
index 725fac4..59378f7 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/Intent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/Intent.java
@@ -63,17 +63,6 @@
      * Creates a new intent.
      *
      * @param appId     application identifier
-     * @param resources required network resources (optional)
-     */
-    protected Intent(ApplicationId appId,
-                     Collection<NetworkResource> resources) {
-        this(appId, null, resources, DEFAULT_INTENT_PRIORITY);
-    }
-
-    /**
-     * Creates a new intent.
-     *
-     * @param appId     application identifier
      * @param key       optional key
      * @param resources required network resources (optional)
      * @param priority  flow rule priority
diff --git a/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java b/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
index 17451cb..8cea253 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/LinkCollectionIntent.java
@@ -15,8 +15,8 @@
  */
 package org.onosproject.net.intent;
 
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableSet;
+import java.util.List;
+import java.util.Set;
 
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
@@ -24,9 +24,8 @@
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
 
 /**
  * Abstraction of a connectivity intent that is implemented by a set of path
@@ -42,71 +41,21 @@
     /**
      * Creates a new actionable intent capable of funneling the selected
      * traffic along the specified convergent tree and out the given egress
-     * point.
-     *
-     * @param appId       application identifier
-     * @param selector    traffic match
-     * @param treatment   action
-     * @param links       traversed links
-     * @param ingressPoint ingress point
-     * @param egressPoint egress point
-     * @throws NullPointerException {@code path} is null
-     */
-    public LinkCollectionIntent(ApplicationId appId,
-                                TrafficSelector selector,
-                                TrafficTreatment treatment,
-                                Set<Link> links,
-                                ConnectPoint ingressPoint,
-                                ConnectPoint egressPoint) {
-        this(appId, selector, treatment, links, ingressPoint, egressPoint,
-             Collections.emptyList(), DEFAULT_INTENT_PRIORITY);
-    }
-
-    /**
-     * Creates a new actionable intent capable of funneling the selected
-     * traffic along the specified convergent tree and out the given egress
      * point satisfying the specified constraints.
      *
      * @param appId       application identifier
+     * @param key         key to use for the intent
      * @param selector    traffic match
      * @param treatment   action
      * @param links       traversed links
-     * @param ingressPoint ingress point
-     * @param egressPoint egress point
+     * @param ingressPoints ingress points
+     * @param egressPoints egress points
      * @param constraints optional list of constraints
      * @param priority    priority to use for the flows generated by this intent
      * @throws NullPointerException {@code path} is null
      */
-    public LinkCollectionIntent(ApplicationId appId,
-                                TrafficSelector selector,
-                                TrafficTreatment treatment,
-                                Set<Link> links,
-                                ConnectPoint ingressPoint,
-                                ConnectPoint egressPoint,
-                                List<Constraint> constraints,
-                                int priority) {
-        super(appId, resources(links), selector, treatment, constraints, priority);
-        this.links = links;
-        this.ingressPoints = ImmutableSet.of(ingressPoint);
-        this.egressPoints = ImmutableSet.of(egressPoint);
-    }
-
-    /**
-     * Creates a new actionable intent capable of funneling the selected
-     * traffic along the specified convergent tree and out the given egress
-     * point.
-     *
-     * @param appId        application identifier
-     * @param selector     traffic match
-     * @param treatment    action
-     * @param links        traversed links
-     * @param ingressPoints Set of ingress points
-     * @param egressPoints Set of egress points
-     * @param constraints  the constraints
-     * @param priority     priority to use for the flows generated by this intent
-     * @throws NullPointerException {@code path} is null
-     */
-    public LinkCollectionIntent(ApplicationId appId,
+    private LinkCollectionIntent(ApplicationId appId,
+                                Key key,
                                 TrafficSelector selector,
                                 TrafficTreatment treatment,
                                 Set<Link> links,
@@ -114,11 +63,10 @@
                                 Set<ConnectPoint> egressPoints,
                                 List<Constraint> constraints,
                                 int priority) {
-        super(appId, resources(links), selector, treatment, constraints, priority);
-
+        super(appId, key, resources(links), selector, treatment, constraints, priority);
         this.links = links;
-        this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
-        this.egressPoints = ImmutableSet.copyOf(egressPoints);
+        this.ingressPoints = ingressPoints;
+        this.egressPoints = egressPoints;
     }
 
     /**
@@ -132,6 +80,120 @@
     }
 
     /**
+     * Returns a new link collection intent builder. The application id,
+     * ingress point and egress points are required fields.  If they are
+     * not set by calls to the appropriate methods, an exception will
+     * be thrown.
+     *
+     * @return single point to multi point builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of a single point to multi point intent.
+     */
+    public static final class Builder extends ConnectivityIntent.Builder {
+        Set<Link> links;
+        Set<ConnectPoint> ingressPoints;
+        Set<ConnectPoint> egressPoints;
+
+        private Builder() {
+            // Hide constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        /**
+         * Sets the ingress point of the single point to multi point intent
+         * that will be built.
+         *
+         * @param ingressPoints ingress connect points
+         * @return this builder
+         */
+        public Builder ingressPoints(Set<ConnectPoint> ingressPoints) {
+            this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
+            return this;
+        }
+
+        /**
+         * Sets the egress points of the single point to multi point intent
+         * that will be built.
+         *
+         * @param egressPoints egress connect points
+         * @return this builder
+         */
+        public Builder egressPoints(Set<ConnectPoint> egressPoints) {
+            this.egressPoints = ImmutableSet.copyOf(egressPoints);
+            return this;
+        }
+
+        /**
+         * Sets the links of the link collection intent
+         * that will be built.
+         *
+         * @param links links for the intent
+         * @return this builder
+         */
+        public Builder links(Set<Link> links) {
+            this.links = ImmutableSet.copyOf(links);
+            return this;
+        }
+
+
+        /**
+         * Builds a single point to multi point intent from the
+         * accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public LinkCollectionIntent build() {
+
+            return new LinkCollectionIntent(
+                    appId,
+                    key,
+                    selector,
+                    treatment,
+                    links,
+                    ingressPoints,
+                    egressPoints,
+                    constraints,
+                    priority
+            );
+        }
+    }
+
+
+    /**
      * Returns the set of links that represent the network connections needed
      * by this intent.
      *
diff --git a/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java b/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java
index 524b231..1625f58 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/MplsIntent.java
@@ -1,8 +1,5 @@
 package org.onosproject.net.intent;
 
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
@@ -10,13 +7,13 @@
 import org.onlab.packet.MplsLabel;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.Link;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.intent.constraint.LinkTypeConstraint;
 
 import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableList;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
 
 
 /**
@@ -30,30 +27,6 @@
     private final Optional<MplsLabel> egressLabel;
 
     /**
-     * Creates a new MPLS intent with the supplied ingress/egress
-     * ports and labels and with built-in link type constraint to avoid optical links.
-     *
-     * @param appId        application identifier
-     * @param selector     traffic selector
-     * @param treatment    treatment
-     * @param ingressPoint ingress port
-     * @param ingressLabel ingress MPLS label
-     * @param egressPoint  egress port
-     * @param egressLabel  egress MPLS label
-     * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
-     */
-    public MplsIntent(ApplicationId appId, TrafficSelector selector,
-                              TrafficTreatment treatment,
-                              ConnectPoint ingressPoint,
-                              Optional<MplsLabel> ingressLabel,
-                              ConnectPoint egressPoint,
-                              Optional<MplsLabel> egressLabel) {
-        this(appId, selector, treatment, ingressPoint, ingressLabel, egressPoint, egressLabel,
-             ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)),
-             DEFAULT_INTENT_PRIORITY);
-    }
-
-    /**
      * Creates a new point-to-point intent with the supplied ingress/egress
      * ports, labels and constraints.
      *
@@ -68,32 +41,154 @@
      * @param priority    priority to use for flows generated by this intent
      * @throws NullPointerException if {@code ingressPoint} or {@code egressPoints} is null.
      */
-    public MplsIntent(ApplicationId appId, TrafficSelector selector,
-                              TrafficTreatment treatment,
-                              ConnectPoint ingressPoint,
-                              Optional<MplsLabel> ingressLabel,
-                              ConnectPoint egressPoint,
-                              Optional<MplsLabel> egressLabel,
-                              List<Constraint> constraints,
-                              int priority) {
+    private MplsIntent(ApplicationId appId,
+                      Key key,
+                      TrafficSelector selector,
+                      TrafficTreatment treatment,
+                      ConnectPoint ingressPoint,
+                      Optional<MplsLabel> ingressLabel,
+                      ConnectPoint egressPoint,
+                      Optional<MplsLabel> egressLabel,
+                      List<Constraint> constraints,
+                      int priority) {
 
-        super(appId, Collections.emptyList(), selector, treatment, constraints,
+        super(appId, key, Collections.emptyList(), selector, treatment, constraints,
               priority);
 
-        checkNotNull(ingressPoint);
-        checkNotNull(egressPoint);
-        checkArgument(!ingressPoint.equals(egressPoint),
-                "ingress and egress should be different (ingress: %s, egress: %s)", ingressPoint, egressPoint);
-        checkNotNull(ingressLabel);
-        checkNotNull(egressLabel);
-        this.ingressPoint = ingressPoint;
-        this.ingressLabel = ingressLabel;
-        this.egressPoint = egressPoint;
-        this.egressLabel = egressLabel;
+        this.ingressPoint = checkNotNull(ingressPoint);
+        this.ingressLabel = checkNotNull(ingressLabel);
+        this.egressPoint = checkNotNull(egressPoint);
+        this.egressLabel = checkNotNull(egressLabel);
 
+        checkArgument(!ingressPoint.equals(egressPoint),
+                "ingress and egress should be different (ingress: %s, egress: %s)",
+                ingressPoint, egressPoint);
     }
 
     /**
+     * Returns a new MPLS intent builder. The application id,
+     * ingress point, egress point, ingress label and egress label are
+     * required fields.  If they are not set by calls to the appropriate
+     * methods, an exception will be thrown.
+     *
+     * @return point to point builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of an MPLS intent.
+     */
+    public static final class Builder extends ConnectivityIntent.Builder {
+        ConnectPoint ingressPoint;
+        ConnectPoint egressPoint;
+        Optional<MplsLabel> ingressLabel;
+        Optional<MplsLabel> egressLabel;
+
+        private Builder() {
+            // Hide constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        /**
+         * Sets the ingress point of the point to point intent that will be built.
+         *
+         * @param ingressPoint ingress connect point
+         * @return this builder
+         */
+        public Builder ingressPoint(ConnectPoint ingressPoint) {
+            this.ingressPoint = ingressPoint;
+            return this;
+        }
+
+        /**
+         * Sets the egress point of the point to point intent that will be built.
+         *
+         * @param egressPoint egress connect point
+         * @return this builder
+         */
+        public Builder egressPoint(ConnectPoint egressPoint) {
+            this.egressPoint = egressPoint;
+            return this;
+        }
+
+        /**
+         * Sets the ingress label of the intent that will be built.
+         *
+         * @param ingressLabel ingress label
+         * @return this builder
+         */
+        public Builder ingressLabel(Optional<MplsLabel> ingressLabel) {
+            this.ingressLabel = ingressLabel;
+            return this;
+        }
+
+        /**
+         * Sets the ingress label of the intent that will be built.
+         *
+         * @param egressLabel ingress label
+         * @return this builder
+         */
+        public Builder egressLabel(Optional<MplsLabel> egressLabel) {
+            this.egressLabel = egressLabel;
+            return this;
+        }
+
+        /**
+         * Builds a point to point intent from the accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public MplsIntent build() {
+
+            return new MplsIntent(
+                    appId,
+                    key,
+                    selector,
+                    treatment,
+                    ingressPoint,
+                    ingressLabel,
+                    egressPoint,
+                    egressLabel,
+                    constraints,
+                    priority
+            );
+        }
+    }
+
+
+
+    /**
      * Constructor for serializer.
      */
     protected MplsIntent() {
@@ -147,6 +242,7 @@
         return MoreObjects.toStringHelper(getClass())
                 .add("id", id())
                 .add("appId", appId())
+                .add("key", key())
                 .add("priority", priority())
                 .add("selector", selector())
                 .add("treatment", treatment())
diff --git a/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java b/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java
index 83e9218..1ea5829 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/MplsPathIntent.java
@@ -1,18 +1,16 @@
 package org.onosproject.net.intent;
 
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
 
-
 import org.onlab.packet.MplsLabel;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.Path;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 
 /**
  * Abstraction of explicit MPLS label-switched path.
@@ -33,44 +31,121 @@
      * @param path traversed links
      * @param ingressLabel MPLS egress label
      * @param egressLabel MPLS ingress label
-     * @throws NullPointerException {@code path} is null
-     */
-    public MplsPathIntent(ApplicationId appId, TrafficSelector selector,
-            TrafficTreatment treatment, Path path, Optional<MplsLabel> ingressLabel,
-            Optional<MplsLabel> egressLabel) {
-        this(appId, selector, treatment, path, ingressLabel, egressLabel,
-             Collections.emptyList(), DEFAULT_INTENT_PRIORITY);
-
-    }
-
-    /**
-     * Creates a new point-to-point intent with the supplied ingress/egress
-     * ports and using the specified explicit path.
-     *
-     * @param appId application identifier
-     * @param selector traffic selector
-     * @param treatment treatment
-     * @param path traversed links
-     * @param ingressLabel MPLS egress label
-     * @param egressLabel MPLS ingress label
      * @param constraints optional list of constraints
      * @param priority    priority to use for flows generated by this intent
      * @throws NullPointerException {@code path} is null
      */
-    public MplsPathIntent(ApplicationId appId, TrafficSelector selector,
+    private MplsPathIntent(ApplicationId appId, TrafficSelector selector,
             TrafficTreatment treatment, Path path, Optional<MplsLabel> ingressLabel,
             Optional<MplsLabel> egressLabel, List<Constraint> constraints,
             int priority) {
         super(appId, selector, treatment, path, constraints,
               priority);
 
-        checkNotNull(ingressLabel);
-        checkNotNull(egressLabel);
-        this.ingressLabel = ingressLabel;
-        this.egressLabel = egressLabel;
+        this.ingressLabel = checkNotNull(ingressLabel);
+        this.egressLabel = checkNotNull(egressLabel);
     }
 
     /**
+     * Returns a new host to host intent builder.
+     *
+     * @return host to host intent builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of a host to host intent.
+     */
+    public static final class Builder extends PathIntent.Builder {
+        private Optional<MplsLabel> ingressLabel = Optional.empty();
+        private Optional<MplsLabel> egressLabel = Optional.empty();
+
+        private Builder() {
+            // Hide constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        @Override
+        public Builder path(Path path) {
+            return (Builder) super.path(path);
+        }
+
+        /**
+         * Sets the ingress label of the intent that will be built.
+         *
+         * @param ingressLabel ingress label
+         * @return this builder
+         */
+        public Builder ingressLabel(Optional<MplsLabel> ingressLabel) {
+            this.ingressLabel = ingressLabel;
+            return this;
+        }
+
+        /**
+         * Sets the ingress label of the intent that will be built.
+         *
+         * @param egressLabel ingress label
+         * @return this builder
+         */
+        public Builder egressLabel(Optional<MplsLabel> egressLabel) {
+            this.egressLabel = egressLabel;
+            return this;
+        }
+
+
+        /**
+         * Builds a host to host intent from the accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public MplsPathIntent build() {
+
+            return new MplsPathIntent(
+                    appId,
+                    selector,
+                    treatment,
+                    path,
+                    ingressLabel,
+                    egressLabel,
+                    constraints,
+                    priority
+            );
+        }
+    }
+
+
+    /**
      * Returns the MPLS label which the ingress traffic should tagged.
      *
      * @return ingress MPLS label
diff --git a/core/api/src/main/java/org/onosproject/net/intent/MultiPointToSinglePointIntent.java b/core/api/src/main/java/org/onosproject/net/intent/MultiPointToSinglePointIntent.java
index 721ff17..c92898e 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/MultiPointToSinglePointIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/MultiPointToSinglePointIntent.java
@@ -16,6 +16,7 @@
 package org.onosproject.net.intent;
 
 import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
@@ -42,29 +43,6 @@
      * traffic selector and treatment.
      *
      * @param appId         application identifier
-     * @param selector      traffic selector
-     * @param treatment     treatment
-     * @param ingressPoints set of ports from which ingress traffic originates
-     * @param egressPoint   port to which traffic will egress
-     * @throws NullPointerException     if {@code ingressPoints} or
-     *                                  {@code egressPoint} is null.
-     * @throws IllegalArgumentException if the size of {@code ingressPoints} is
-     *                                  not more than 1
-     */
-    public MultiPointToSinglePointIntent(ApplicationId appId,
-                                         TrafficSelector selector,
-                                         TrafficTreatment treatment,
-                                         Set<ConnectPoint> ingressPoints,
-                                         ConnectPoint egressPoint) {
-        this(appId, selector, treatment, ingressPoints, egressPoint,
-                Collections.emptyList(), DEFAULT_INTENT_PRIORITY);
-    }
-
-    /**
-     * Creates a new multi-to-single point connectivity intent for the specified
-     * traffic selector and treatment.
-     *
-     * @param appId         application identifier
      * @param key           intent key
      * @param selector      traffic selector
      * @param treatment     treatment
@@ -77,7 +55,7 @@
      * @throws IllegalArgumentException if the size of {@code ingressPoints} is
      *                                  not more than 1
      */
-    public MultiPointToSinglePointIntent(ApplicationId appId,
+    private MultiPointToSinglePointIntent(ApplicationId appId,
                                          Key key,
                                          TrafficSelector selector,
                                          TrafficTreatment treatment,
@@ -99,33 +77,6 @@
     }
 
     /**
-     * Creates a new multi-to-single point connectivity intent for the specified
-     * traffic selector and treatment.
-     *
-     * @param appId         application identifier
-     * @param selector      traffic selector
-     * @param treatment     treatment
-     * @param ingressPoints set of ports from which ingress traffic originates
-     * @param egressPoint   port to which traffic will egress
-     * @param constraints   constraints to apply to the intent
-     * @param priority      priority to use for flows generated by this intent
-     * @throws NullPointerException     if {@code ingressPoints} or
-     *                                  {@code egressPoint} is null.
-     * @throws IllegalArgumentException if the size of {@code ingressPoints} is
-     *                                  not more than 1
-     */
-    public MultiPointToSinglePointIntent(ApplicationId appId,
-                                         TrafficSelector selector,
-                                         TrafficTreatment treatment,
-                                         Set<ConnectPoint> ingressPoints,
-                                         ConnectPoint egressPoint,
-                                         List<Constraint> constraints,
-                                         int priority) {
-        this(appId, null, selector, treatment, ingressPoints, egressPoint,
-                constraints, priority);
-    }
-
-    /**
      * Constructor for serializer.
      */
     protected MultiPointToSinglePointIntent() {
@@ -135,6 +86,105 @@
     }
 
     /**
+     * Returns a new multi point to single point intent builder. The application id,
+     * ingress points and egress point are required fields.  If they are
+     * not set by calls to the appropriate methods, an exception will
+     * be thrown.
+     *
+     * @return single point to multi point builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of a multi point to single point intent.
+     */
+    public static final class Builder extends ConnectivityIntent.Builder {
+        Set<ConnectPoint> ingressPoints;
+        ConnectPoint egressPoint;
+
+        private Builder() {
+            // Hide constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        /**
+         * Sets the ingress point of the single point to multi point intent
+         * that will be built.
+         *
+         * @param ingressPoints ingress connect points
+         * @return this builder
+         */
+        public Builder ingressPoints(Set<ConnectPoint> ingressPoints) {
+            this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
+            return this;
+        }
+
+        /**
+         * Sets the egress point of the multi point to single point intent
+         * that will be built.
+         *
+         * @param egressPoint egress connect point
+         * @return this builder
+         */
+        public Builder egressPoint(ConnectPoint egressPoint) {
+            this.egressPoint = egressPoint;
+            return this;
+        }
+
+        /**
+         * Builds a multi point to single point intent from the
+         * accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public MultiPointToSinglePointIntent build() {
+
+            return new MultiPointToSinglePointIntent(
+                    appId,
+                    key,
+                    selector,
+                    treatment,
+                    ingressPoints,
+                    egressPoint,
+                    constraints,
+                    priority
+            );
+        }
+    }
+
+
+    /**
      * Returns the set of ports on which ingress traffic should be connected to
      * the egress port.
      *
diff --git a/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java b/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java
index 6804c86..4843877 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/OpticalPathIntent.java
@@ -24,6 +24,8 @@
 
 import java.util.Collection;
 
+import static com.google.common.base.Preconditions.checkNotNull;
+
 public final class OpticalPathIntent extends Intent {
 
     private final ConnectPoint src;
@@ -35,10 +37,11 @@
             ConnectPoint src,
             ConnectPoint dst,
             Path path) {
-        super(appId, ImmutableSet.copyOf(path.links()));
-        this.src = src;
-        this.dst = dst;
-        this.path = path;
+        super(appId, null, ImmutableSet.copyOf(path.links()),
+                Intent.DEFAULT_INTENT_PRIORITY);
+        this.src = checkNotNull(src);
+        this.dst = checkNotNull(dst);
+        this.path = checkNotNull(path);
     }
 
     protected OpticalPathIntent() {
@@ -69,6 +72,7 @@
         return MoreObjects.toStringHelper(getClass())
                 .add("id", id())
                 .add("appId", appId())
+                .add("key", key())
                 .add("resources", resources())
                 .add("ingressPort", src)
                 .add("egressPort", dst)
diff --git a/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java b/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java
index 13fa61e..1cb960f 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/PathIntent.java
@@ -15,17 +15,17 @@
  */
 package org.onosproject.net.intent;
 
-import com.google.common.base.MoreObjects;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
+import java.util.List;
+
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.Link;
 import org.onosproject.net.Path;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 
-import java.util.Collections;
-import java.util.List;
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
 
 import static com.google.common.base.Preconditions.checkArgument;
 
@@ -44,30 +44,17 @@
      * @param selector  traffic selector
      * @param treatment treatment
      * @param path      traversed links
-     * @throws NullPointerException {@code path} is null
-     */
-    public PathIntent(ApplicationId appId, TrafficSelector selector,
-                      TrafficTreatment treatment, Path path) {
-        this(appId, selector, treatment, path, Collections.emptyList(),
-                DEFAULT_INTENT_PRIORITY);
-    }
-
-    /**
-     * Creates a new point-to-point intent with the supplied ingress/egress
-     * ports and using the specified explicit path.
-     *
-     * @param appId     application identifier
-     * @param selector  traffic selector
-     * @param treatment treatment
-     * @param path      traversed links
      * @param constraints  optional list of constraints
      * @param priority  priority to use for the generated flows
      * @throws NullPointerException {@code path} is null
      */
-    public PathIntent(ApplicationId appId, TrafficSelector selector,
-                      TrafficTreatment treatment, Path path, List<Constraint> constraints,
-                      int priority) {
-        super(appId, resources(path.links()), selector, treatment, constraints,
+    protected PathIntent(ApplicationId appId,
+                         TrafficSelector selector,
+                         TrafficTreatment treatment,
+                         Path path,
+                         List<Constraint> constraints,
+                         int priority) {
+        super(appId, null, resources(path.links()), selector, treatment, constraints,
                 priority);
         PathIntent.validate(path.links());
         this.path = path;
@@ -81,6 +68,86 @@
         this.path = null;
     }
 
+    /**
+     * Returns a new host to host intent builder.
+     *
+     * @return host to host intent builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of a host to host intent.
+     */
+    public static class Builder extends ConnectivityIntent.Builder {
+        Path path;
+
+        protected Builder() {
+            // Hide default constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        /**
+         * Sets the path of the intent that will be built.
+         *
+         * @param path path for the intent
+         * @return this builder
+         */
+        public Builder path(Path path) {
+            this.path = path;
+            return this;
+        }
+
+        /**
+         * Builds a path intent from the accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public PathIntent build() {
+
+            return new PathIntent(
+                    appId,
+                    selector,
+                    treatment,
+                    path,
+                    constraints,
+                    priority
+            );
+        }
+    }
+
+
+
     // NOTE: This methods takes linear time with the number of links.
     /**
      * Validates that source element ID and destination element ID of a link are
diff --git a/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java b/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java
index 5f80d9a..5439121 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/PointToPointIntent.java
@@ -159,13 +159,11 @@
         super(appId, key, Collections.emptyList(), selector, treatment, constraints,
                 priority);
 
-        checkNotNull(ingressPoint);
-        checkNotNull(egressPoint);
         checkArgument(!ingressPoint.equals(egressPoint),
                 "ingress and egress should be different (ingress: %s, egress: %s)", ingressPoint, egressPoint);
 
-        this.ingressPoint = ingressPoint;
-        this.egressPoint = egressPoint;
+        this.ingressPoint = checkNotNull(ingressPoint);
+        this.egressPoint = checkNotNull(egressPoint);
     }
 
     /**
diff --git a/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java b/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java
index 129c4a6..a58d3af 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/SinglePointToMultiPointIntent.java
@@ -16,7 +16,7 @@
 package org.onosproject.net.intent;
 
 import com.google.common.base.MoreObjects;
-import com.google.common.collect.Sets;
+import com.google.common.collect.ImmutableSet;
 
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
@@ -42,27 +42,6 @@
      * Creates a new single-to-multi point connectivity intent.
      *
      * @param appId application identifier
-     * @param selector traffic selector
-     * @param treatment treatment
-     * @param ingressPoint port on which traffic will ingress
-     * @param egressPoints set of ports on which traffic will egress
-     * @throws NullPointerException if {@code ingressPoint} or
-     *             {@code egressPoints} is null
-     * @throws IllegalArgumentException if the size of {@code egressPoints} is
-     *             not more than 1
-     */
-    public SinglePointToMultiPointIntent(ApplicationId appId,
-            TrafficSelector selector, TrafficTreatment treatment,
-            ConnectPoint ingressPoint, Set<ConnectPoint> egressPoints) {
-        this(appId, null, selector, treatment, ingressPoint, egressPoints,
-                Collections.emptyList(),
-                DEFAULT_INTENT_PRIORITY);
-    }
-
-    /**
-     * Creates a new single-to-multi point connectivity intent.
-     *
-     * @param appId application identifier
      * @param key intent key
      * @param selector traffic selector
      * @param treatment treatment
@@ -75,7 +54,7 @@
      * @throws IllegalArgumentException if the size of {@code egressPoints} is
      *             not more than 1
      */
-    public SinglePointToMultiPointIntent(ApplicationId appId,
+    private SinglePointToMultiPointIntent(ApplicationId appId,
             Key key,
             TrafficSelector selector, TrafficTreatment treatment,
             ConnectPoint ingressPoint, Set<ConnectPoint> egressPoints,
@@ -90,7 +69,105 @@
                 "Set of egresses should not contain ingress (ingress: %s)", ingressPoint);
 
         this.ingressPoint = checkNotNull(ingressPoint);
-        this.egressPoints = Sets.newHashSet(egressPoints);
+        this.egressPoints = egressPoints;
+    }
+
+    /**
+     * Returns a new single point to multi point intent builder. The application id,
+     * ingress point and egress points are required fields.  If they are
+     * not set by calls to the appropriate methods, an exception will
+     * be thrown.
+     *
+     * @return single point to multi point builder
+     */
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder of a single point to multi point intent.
+     */
+    public static final class Builder extends ConnectivityIntent.Builder {
+        ConnectPoint ingressPoint;
+        Set<ConnectPoint> egressPoints;
+
+        private Builder() {
+            // Hide constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        /**
+         * Sets the ingress point of the single point to multi point intent
+         * that will be built.
+         *
+         * @param ingressPoint ingress connect point
+         * @return this builder
+         */
+        public Builder ingressPoint(ConnectPoint ingressPoint) {
+            this.ingressPoint = ingressPoint;
+            return this;
+        }
+
+        /**
+         * Sets the egress points of the single point to multi point intent
+         * that will be built.
+         *
+         * @param egressPoints egress connect points
+         * @return this builder
+         */
+        public Builder egressPoints(Set<ConnectPoint> egressPoints) {
+            this.egressPoints = ImmutableSet.copyOf(egressPoints);
+            return this;
+        }
+
+        /**
+         * Builds a single point to multi point intent from the
+         * accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public SinglePointToMultiPointIntent build() {
+
+            return new SinglePointToMultiPointIntent(
+                    appId,
+                    key,
+                    selector,
+                    treatment,
+                    ingressPoint,
+                    egressPoints,
+                    constraints,
+                    priority
+            );
+        }
     }
 
     /**
diff --git a/core/api/src/main/java/org/onosproject/net/intent/TwoWayP2PIntent.java b/core/api/src/main/java/org/onosproject/net/intent/TwoWayP2PIntent.java
index ee95255..a995758 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/TwoWayP2PIntent.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/TwoWayP2PIntent.java
@@ -15,21 +15,16 @@
  */
 package org.onosproject.net.intent;
 
-import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableList;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.HostId;
-import org.onosproject.net.Link;
-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.constraint.LinkTypeConstraint;
-
 import java.util.Collections;
 import java.util.List;
 
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+
+import com.google.common.base.MoreObjects;
+
 import static com.google.common.base.Preconditions.checkNotNull;
 
 /**
@@ -40,45 +35,12 @@
     private final ConnectPoint one;
     private final ConnectPoint two;
 
-    /**
-     * Creates a new two way host-to-host intent with the supplied host pair and no
-     * other traffic selection or treatment criteria.
-     *
-     * @param appId     application identifier
-     * @param one       first host
-     * @param two       second host
-     * @throws NullPointerException if {@code one} or {@code two} is null.
-     */
-    public TwoWayP2PIntent(ApplicationId appId, ConnectPoint one, ConnectPoint two) {
-        this(appId, one, two,
-             DefaultTrafficSelector.emptySelector(),
-             DefaultTrafficTreatment.emptyTreatment(),
-             ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)),
-             DEFAULT_INTENT_PRIORITY);
-    }
-
-    /**
-     * Creates a new host-to-host intent with the supplied host pair.
-     *
-     * @param appId     application identifier
-     * @param one       first host
-     * @param two       second host
-     * @param selector  action
-     * @param treatment ingress port
-     * @throws NullPointerException if {@code one} or {@code two} is null.
-     */
-    public TwoWayP2PIntent(ApplicationId appId, ConnectPoint one, ConnectPoint two,
-                           TrafficSelector selector,
-                           TrafficTreatment treatment) {
-        this(appId, one, two, selector, treatment,
-             ImmutableList.of(new LinkTypeConstraint(false, Link.Type.OPTICAL)),
-             DEFAULT_INTENT_PRIORITY);
-    }
 
     /**
      * Creates a new host-to-host intent with the supplied host pair.
      *
      * @param appId       application identifier
+     * @param key         intent key
      * @param one         first host
      * @param two         second host
      * @param selector    action
@@ -87,27 +49,7 @@
      * @param priority    priority to use for flows generated by this intent
      * @throws NullPointerException if {@code one} or {@code two} is null.
      */
-    public TwoWayP2PIntent(ApplicationId appId, ConnectPoint one, ConnectPoint two,
-                           TrafficSelector selector,
-                           TrafficTreatment treatment,
-                           List<Constraint> constraints,
-                           int priority) {
-        this(appId, null, one, two, selector, treatment, constraints, priority);
-    }
-    /**
-     * Creates a new host-to-host intent with the supplied host pair.
-     *
-     * @param appId       application identifier
-     * @param key       intent key
-     * @param one         first host
-     * @param two         second host
-     * @param selector    action
-     * @param treatment   ingress port
-     * @param constraints optional prioritized list of path selection constraints
-     * @param priority    priority to use for flows generated by this intent
-     * @throws NullPointerException if {@code one} or {@code two} is null.
-     */
-    public TwoWayP2PIntent(ApplicationId appId, Key key,
+    private TwoWayP2PIntent(ApplicationId appId, Key key,
                            ConnectPoint one, ConnectPoint two,
                            TrafficSelector selector,
                            TrafficTreatment treatment,
@@ -122,12 +64,96 @@
 
     }
 
-    private static HostId min(HostId one, HostId two) {
-        return one.hashCode() < two.hashCode() ? one : two;
+    /**
+     * Returns a new two way intent builder.
+     *
+     * @return two way intent builder
+     */
+    public static Builder builder() {
+        return new Builder();
     }
 
-    private static HostId max(HostId one, HostId two) {
-        return one.hashCode() >= two.hashCode() ? one : two;
+    /**
+     * Builder of a point to point intent.
+     */
+    public static final class Builder extends ConnectivityIntent.Builder {
+        ConnectPoint one;
+        ConnectPoint two;
+
+        private Builder() {
+            // Hide constructor
+        }
+
+        @Override
+        public Builder appId(ApplicationId appId) {
+            return (Builder) super.appId(appId);
+        }
+
+        @Override
+        public Builder key(Key key) {
+            return (Builder) super.key(key);
+        }
+
+        @Override
+        public Builder selector(TrafficSelector selector) {
+            return (Builder) super.selector(selector);
+        }
+
+        @Override
+        public Builder treatment(TrafficTreatment treatment) {
+            return (Builder) super.treatment(treatment);
+        }
+
+        @Override
+        public Builder constraints(List<Constraint> constraints) {
+            return (Builder) super.constraints(constraints);
+        }
+
+        @Override
+        public Builder priority(int priority) {
+            return (Builder) super.priority(priority);
+        }
+
+        /**
+         * Sets the first connection point of the two way intent that will be built.
+         *
+         * @param one first connect point
+         * @return this builder
+         */
+        public Builder one(ConnectPoint one) {
+            this.one = one;
+            return this;
+        }
+
+        /**
+         * Sets the second connection point of the two way intent that will be built.
+         *
+         * @param two second connect point
+         * @return this builder
+         */
+        public Builder two(ConnectPoint two) {
+            this.two = two;
+            return this;
+        }
+
+        /**
+         * Builds a point to point intent from the accumulated parameters.
+         *
+         * @return point to point intent
+         */
+        public TwoWayP2PIntent build() {
+
+            return new TwoWayP2PIntent(
+                    appId,
+                    key,
+                    one,
+                    two,
+                    selector,
+                    treatment,
+                    constraints,
+                    priority
+            );
+        }
     }
 
     /**