[ONOS-5264] [ONOS-5242] Intents w/ FilteredConnectPoint

Change-Id: Ibe9062c904ad9a6c3ba001fe57be7cec49eb8a4d
diff --git a/core/api/src/main/java/org/onosproject/net/intent/IntentUtils.java b/core/api/src/main/java/org/onosproject/net/intent/IntentUtils.java
index 322b235..9ddb174 100644
--- a/core/api/src/main/java/org/onosproject/net/intent/IntentUtils.java
+++ b/core/api/src/main/java/org/onosproject/net/intent/IntentUtils.java
@@ -57,19 +57,19 @@
             SinglePointToMultiPointIntent intent2 = (SinglePointToMultiPointIntent) two;
 
             return Objects.equals(intent1.selector(), intent2.selector()) &&
-                    Objects.equals(intent1.treatment(), intent2.treatment()) &&
-                    Objects.equals(intent1.constraints(), intent2.constraints()) &&
-                    Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) &&
-                    Objects.equals(intent1.egressPoints(), intent2.egressPoints());
+                   Objects.equals(intent1.treatment(), intent2.treatment()) &&
+                   Objects.equals(intent1.filteredIngressPoint(), intent2.filteredIngressPoint()) &&
+                   Objects.equals(intent1.filteredEgressPoints(), intent2.filteredEgressPoints()) &&
+                   Objects.equals(intent1.constraints(), intent2.constraints());
         } else if (one instanceof MultiPointToSinglePointIntent) {
             MultiPointToSinglePointIntent intent1 = (MultiPointToSinglePointIntent) one;
             MultiPointToSinglePointIntent intent2 = (MultiPointToSinglePointIntent) two;
 
             return Objects.equals(intent1.selector(), intent2.selector()) &&
-                    Objects.equals(intent1.treatment(), intent2.treatment()) &&
-                    Objects.equals(intent1.constraints(), intent2.constraints()) &&
-                    Objects.equals(intent1.ingressPoints(), intent2.ingressPoints()) &&
-                    Objects.equals(intent1.egressPoint(), intent2.egressPoint());
+                   Objects.equals(intent1.filteredIngressPoints(), intent2.filteredIngressPoints()) &&
+                   Objects.equals(intent1.filteredEgressPoint(), intent2.filteredEgressPoint()) &&
+                   Objects.equals(intent1.treatment(), intent2.treatment()) &&
+                   Objects.equals(intent1.constraints(), intent2.constraints());
         } else if (one instanceof PointToPointIntent) {
             PointToPointIntent intent1 = (PointToPointIntent) one;
             PointToPointIntent intent2 = (PointToPointIntent) two;
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 85bd5df..0893528 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
@@ -17,19 +17,22 @@
 package org.onosproject.net.intent;
 
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import com.google.common.annotations.Beta;
-import com.google.common.collect.ImmutableMap;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.Link;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableSet;
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Abstraction of a connectivity intent that is implemented by a set of path
@@ -40,17 +43,11 @@
 
     private final Set<Link> links;
 
-    private final Set<ConnectPoint> ingressPoints;
-    private final Set<ConnectPoint> egressPoints;
+    private final Set<FilteredConnectPoint> ingressPoints;
+    private final Set<FilteredConnectPoint> egressPoints;
     private final boolean egressTreatmentFlag;
-    /**
-     * To manage multiple selectors use case.
-     */
-    private final Map<ConnectPoint, TrafficSelector> ingressSelectors;
-    /**
-     * To manage multiple treatments use case.
-     */
-    private final Map<ConnectPoint, TrafficTreatment> egressTreatments;
+
+
 
     /**
      * Creates a new actionable intent capable of funneling the selected
@@ -62,13 +59,11 @@
      * @param selector    traffic match
      * @param treatment   action
      * @param links       traversed links
-     * @param ingressPoints ingress points
-     * @param egressPoints egress points
+     * @param ingressPoints filtered ingress points
+     * @param egressPoints filtered egress points
      * @param constraints optional list of constraints
      * @param priority    priority to use for the flows generated by this intent
      * @param egressTreatment true if treatment should be applied by the egress device
-     * @param ingressSelectors map to store the association ingress to selector
-     * @param egressTreatments map to store the association egress to treatment
      * @throws NullPointerException {@code path} is null
      */
     private LinkCollectionIntent(ApplicationId appId,
@@ -76,20 +71,16 @@
                                  TrafficSelector selector,
                                  TrafficTreatment treatment,
                                  Set<Link> links,
-                                 Set<ConnectPoint> ingressPoints,
-                                 Set<ConnectPoint> egressPoints,
+                                 Set<FilteredConnectPoint> ingressPoints,
+                                 Set<FilteredConnectPoint> egressPoints,
                                  List<Constraint> constraints,
                                  int priority,
-                                 boolean egressTreatment,
-                                 Map<ConnectPoint, TrafficSelector> ingressSelectors,
-                                 Map<ConnectPoint, TrafficTreatment> egressTreatments) {
+                                 boolean egressTreatment) {
         super(appId, key, resources(links), selector, treatment, constraints, priority);
         this.links = links;
         this.ingressPoints = ingressPoints;
         this.egressPoints = egressPoints;
         this.egressTreatmentFlag = egressTreatment;
-        this.ingressSelectors = ingressSelectors;
-        this.egressTreatments = egressTreatments;
     }
 
     /**
@@ -101,8 +92,6 @@
         this.ingressPoints = null;
         this.egressPoints = null;
         this.egressTreatmentFlag = false;
-        this.ingressSelectors = null;
-        this.egressTreatments = null;
     }
 
     /**
@@ -121,12 +110,11 @@
      * 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;
-        Map<ConnectPoint, TrafficSelector> ingressSelectors = ImmutableMap.of();
-        Map<ConnectPoint, TrafficTreatment> egressTreatments = ImmutableMap.of();
-        boolean egressTreatmentFlag;
+        private final Logger log = getLogger(getClass());
+        private Set<Link> links;
+        private Set<FilteredConnectPoint> ingressPoints;
+        private Set<FilteredConnectPoint> egressPoints;
+        private boolean egressTreatmentFlag;
 
         private Builder() {
             // Hide constructor
@@ -169,8 +157,15 @@
          * @param ingressPoints ingress connect points
          * @return this builder
          */
+        @Deprecated
         public Builder ingressPoints(Set<ConnectPoint> ingressPoints) {
-            this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
+            if (this.ingressPoints != null) {
+                log.warn("Ingress points are already set, " +
+                                 "this will override original ingress points.");
+            }
+            this.ingressPoints = ingressPoints.stream()
+                    .map(FilteredConnectPoint::new)
+                    .collect(Collectors.toSet());
             return this;
         }
 
@@ -181,34 +176,43 @@
          * @param egressPoints egress connect points
          * @return this builder
          */
+        @Deprecated
         public Builder egressPoints(Set<ConnectPoint> egressPoints) {
+            if (this.egressPoints != null) {
+                log.warn("Egress points are already set, " +
+                                 "this will override original egress points.");
+            }
+            this.egressPoints = egressPoints.stream()
+                    .map(FilteredConnectPoint::new)
+                    .collect(Collectors.toSet());
+            return this;
+        }
+
+        /**
+         * Sets the filtered ingress point of the single point to multi point intent
+         * that will be built.
+         *
+         * @param ingressPoints ingress connect points
+         * @return this builder
+         */
+        public Builder filteredIngressPoints(Set<FilteredConnectPoint> ingressPoints) {
+            this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
+            return this;
+        }
+
+        /**
+         * Sets the filtered egress points of the single point to multi point intent
+         * that will be built.
+         *
+         * @param egressPoints egress connect points
+         * @return this builder
+         */
+        public Builder filteredEgressPoints(Set<FilteredConnectPoint> egressPoints) {
             this.egressPoints = ImmutableSet.copyOf(egressPoints);
             return this;
         }
 
         /**
-         * Sets the map ingress selectors to connection points of the intent.
-         *
-         * @param ingressSelectors maps connection point to traffic selector
-         * @return this builder
-         */
-        public Builder ingressSelectors(Map<ConnectPoint, TrafficSelector> ingressSelectors) {
-            this.ingressSelectors = ImmutableMap.copyOf(ingressSelectors);
-            return this;
-        }
-
-        /**
-         * Sets the map egress treatments to connection points of the intent.
-         *
-         * @param egressTreatments maps connection point to traffic treatment
-         * @return this builder
-         */
-        public Builder egressTreatments(Map<ConnectPoint, TrafficTreatment> egressTreatments) {
-            this.egressTreatments = ImmutableMap.copyOf(egressTreatments);
-            return this;
-        }
-
-        /**
          * Sets the links of the link collection intent
          * that will be built.
          *
@@ -250,9 +254,7 @@
                     egressPoints,
                     constraints,
                     priority,
-                    egressTreatmentFlag,
-                    ingressSelectors,
-                    egressTreatments
+                    egressTreatmentFlag
             );
         }
     }
@@ -273,7 +275,12 @@
      * @return the ingress points
      */
     public Set<ConnectPoint> ingressPoints() {
-        return ingressPoints;
+        if (this.ingressPoints == null) {
+            return null;
+        }
+        return ingressPoints.stream()
+                .map(FilteredConnectPoint::connectPoint)
+                .collect(Collectors.toSet());
     }
 
     /**
@@ -282,26 +289,33 @@
      * @return the egress points
      */
     public Set<ConnectPoint> egressPoints() {
+        if (this.egressPoints == null) {
+            return null;
+        }
+        return egressPoints.stream()
+                .map(FilteredConnectPoint::connectPoint)
+                .collect(Collectors.toSet());
+    }
+
+    /**
+     * Returns the filtered ingress points of the intent.
+     *
+     * @return the ingress points
+     */
+    public Set<FilteredConnectPoint> filteredIngressPoints() {
+        return ingressPoints;
+    }
+
+    /**
+     * Returns the egress points of the intent.
+     *
+     * @return the egress points
+     */
+    public Set<FilteredConnectPoint> filteredEgressPoints() {
         return egressPoints;
     }
 
     /**
-     * Returns the multiple selectors jointly with their connection points.
-     * @return multiple selectors
-     */
-    public Map<ConnectPoint, TrafficSelector> ingressSelectors() {
-        return ingressSelectors;
-    }
-
-    /**
-     * Returns the multiple treatments jointly with their connection points.
-     * @return multiple treatments
-     */
-    public Map<ConnectPoint, TrafficTreatment> egressTreatments() {
-        return egressTreatments;
-    }
-
-    /**
      * Returns whether treatment should be applied on egress.
      *
      * @return the egress treatment flag
@@ -323,8 +337,6 @@
                 .add("links", links())
                 .add("ingress", ingressPoints())
                 .add("egress", egressPoints())
-                .add("selectors", ingressSelectors())
-                .add("treatments", egressTreatments())
                 .add("treatementOnEgress", applyTreatmentOnEgress())
                 .toString();
     }
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 2b8398f..3048aac 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
@@ -17,20 +17,21 @@
 
 import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Sets;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.slf4j.Logger;
 
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Abstraction of multiple source to single destination connectivity intent.
@@ -38,26 +39,21 @@
 @Beta
 public final class MultiPointToSinglePointIntent extends ConnectivityIntent {
 
-    private final Set<ConnectPoint> ingressPoints;
-    private final ConnectPoint egressPoint;
-    /**
-     * To manage multiple selectors use case.
-     */
-    private final Map<ConnectPoint, TrafficSelector> ingressSelectors;
+    private final Set<FilteredConnectPoint> ingressPoints;
+    private final FilteredConnectPoint egressPoint;
 
     /**
      * Creates a new multi-to-single point connectivity intent for the specified
-     * traffic selector and treatment.
+     * traffic selector and treatment with filtered connect point.
      *
      * @param appId         application identifier
      * @param key           intent key
      * @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 ingressPoints set of filtered ports from which ingress traffic originates
+     * @param egressPoint   filtered 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
-     * @param ingressSelectors map to store the association ingress to selector
      * @throws NullPointerException     if {@code ingressPoints} or
      *                                  {@code egressPoint} is null.
      * @throws IllegalArgumentException if the size of {@code ingressPoints} is
@@ -67,24 +63,22 @@
                                           Key key,
                                           TrafficSelector selector,
                                           TrafficTreatment treatment,
-                                          Set<ConnectPoint> ingressPoints,
-                                          ConnectPoint egressPoint,
+                                          Set<FilteredConnectPoint> ingressPoints,
+                                          FilteredConnectPoint egressPoint,
                                           List<Constraint> constraints,
-                                          int priority,
-                                          Map<ConnectPoint, TrafficSelector> ingressSelectors
-                                          ) {
+                                          int priority
+    ) {
         super(appId, key, ImmutableSet.of(), selector, treatment, constraints,
-                priority);
+              priority);
 
         checkNotNull(ingressPoints);
         checkArgument(!ingressPoints.isEmpty(), "Ingress point set cannot be empty");
         checkNotNull(egressPoint);
         checkArgument(!ingressPoints.contains(egressPoint),
-                "Set of ingresses should not contain egress (egress: %s)", egressPoint);
+                      "Set of ingresses should not contain egress (egress: %s)", egressPoint);
 
-        this.ingressPoints = Sets.newHashSet(ingressPoints);
+        this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
         this.egressPoint = egressPoint;
-        this.ingressSelectors = ingressSelectors;
     }
 
     /**
@@ -94,7 +88,6 @@
         super();
         this.ingressPoints = null;
         this.egressPoint = null;
-        this.ingressSelectors = null;
     }
 
     /**
@@ -124,9 +117,9 @@
      * Builder of a multi point to single point intent.
      */
     public static final class Builder extends ConnectivityIntent.Builder {
-        Set<ConnectPoint> ingressPoints;
-        ConnectPoint egressPoint;
-        Map<ConnectPoint, TrafficSelector> ingressSelectors = ImmutableMap.of();
+        private final Logger log = getLogger(getClass());
+        private Set<FilteredConnectPoint> ingressPoints;
+        private FilteredConnectPoint egressPoint;
 
         private Builder() {
             // Hide constructor
@@ -141,8 +134,9 @@
         protected Builder(MultiPointToSinglePointIntent intent) {
             super(intent);
 
-            this.ingressPoints(intent.ingressPoints())
-                    .egressPoint(intent.egressPoint());
+            this.filteredIngressPoints(intent.filteredIngressPoints())
+                    .filteredEgressPoint(intent.filteredEgressPoint());
+
         }
 
         @Override
@@ -182,8 +176,15 @@
          * @param ingressPoints ingress connect points
          * @return this builder
          */
+        @Deprecated
         public Builder ingressPoints(Set<ConnectPoint> ingressPoints) {
-            this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
+            if (this.ingressPoints != null) {
+                log.warn("Ingress points are already set, " +
+                                 "this will override original ingress points.");
+            }
+            this.ingressPoints = ingressPoints.stream()
+                    .map(FilteredConnectPoint::new)
+                    .collect(Collectors.toSet());
             return this;
         }
 
@@ -194,20 +195,37 @@
          * @param egressPoint egress connect point
          * @return this builder
          */
+        @Deprecated
         public Builder egressPoint(ConnectPoint egressPoint) {
-            this.egressPoint = egressPoint;
+            if (this.egressPoint != null) {
+                log.warn("Egress point is already set, " +
+                                 "this will override original egress point.");
+            }
+            this.egressPoint = new FilteredConnectPoint(egressPoint);
             return this;
         }
 
         /**
-         * Sets the selectors of the multi point to single point intent
+         * Sets the filtered ingress point of the single point to multi point intent
          * that will be built.
          *
-         * @param ingressSelectors the multiple selectos
+         * @param ingressPoints filtered ingress connect points
          * @return this builder
          */
-        public Builder selectors(Map<ConnectPoint, TrafficSelector> ingressSelectors) {
-            this.ingressSelectors = ImmutableMap.copyOf(ingressSelectors);
+        public Builder filteredIngressPoints(Set<FilteredConnectPoint> ingressPoints) {
+            this.ingressPoints = ImmutableSet.copyOf(ingressPoints);
+            return this;
+        }
+
+        /**
+         * Sets the filtered egress point of the multi point to single point intent
+         * that will be built.
+         *
+         * @param egressPoint filtered egress connect point
+         * @return this builder
+         */
+        public Builder filteredEgressPoint(FilteredConnectPoint egressPoint) {
+            this.egressPoint = egressPoint;
             return this;
         }
 
@@ -219,11 +237,6 @@
          */
         public MultiPointToSinglePointIntent build() {
 
-            if (selector != null && !selector.criteria().isEmpty() &&
-                    ingressSelectors != null && !ingressSelectors.isEmpty()) {
-                throw new IllegalArgumentException("Selector and Multiple Selectors are both set");
-            }
-
             return new MultiPointToSinglePointIntent(
                     appId,
                     key,
@@ -232,8 +245,7 @@
                     ingressPoints,
                     egressPoint,
                     constraints,
-                    priority,
-                    ingressSelectors
+                    priority
             );
         }
     }
@@ -246,7 +258,9 @@
      * @return set of ingress ports
      */
     public Set<ConnectPoint> ingressPoints() {
-        return ingressPoints;
+        return ingressPoints.stream()
+                .map(FilteredConnectPoint::connectPoint)
+                .collect(Collectors.toSet());
     }
 
     /**
@@ -255,17 +269,29 @@
      * @return egress port
      */
     public ConnectPoint egressPoint() {
-        return egressPoint;
+        return egressPoint.connectPoint();
     }
 
     /**
-     * Returns the multiple selectors jointly with their connection points.
-     * @return multiple selectors
+     * Returns the set of ports on which ingress traffic should be connected to
+     * the egress port.
+     *
+     * @return set of ingress ports
      */
-    public Map<ConnectPoint, TrafficSelector> ingressSelectors() {
-        return ingressSelectors;
+    public Set<FilteredConnectPoint> filteredIngressPoints() {
+        return ingressPoints;
     }
 
+    /**
+     * Returns the port on which the traffic should egress.
+     *
+     * @return egress port
+     */
+    public FilteredConnectPoint filteredEgressPoint() {
+        return egressPoint;
+    }
+
+
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
@@ -278,7 +304,8 @@
                 .add("treatment", treatment())
                 .add("ingress", ingressPoints())
                 .add("egress", egressPoint())
-                .add("selectors", ingressSelectors())
+                .add("filteredIngressCPs", filteredIngressPoints())
+                .add("filteredEgressCP", filteredEgressPoint())
                 .add("constraints", constraints())
                 .toString();
     }
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 4b17c66..8431a0a 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
@@ -18,35 +18,31 @@
 import com.google.common.annotations.Beta;
 import com.google.common.base.MoreObjects;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 
 import com.google.common.collect.Sets;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.FilteredConnectPoint;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.slf4j.Logger;
 
-import java.util.Map;
 import java.util.Set;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Abstraction of single source, multiple destination connectivity intent.
  */
 @Beta
 public final class SinglePointToMultiPointIntent extends ConnectivityIntent {
-
-    private final ConnectPoint ingressPoint;
-    private final Set<ConnectPoint> egressPoints;
-    /**
-     * To manage multiple treatments use case.
-     */
-    private final Map<ConnectPoint, TrafficTreatment> egressTreatments;
+    private final FilteredConnectPoint ingressPoint;
+    private final Set<FilteredConnectPoint> egressPoints;
 
     /**
      * Creates a new single-to-multi point connectivity intent.
@@ -59,7 +55,6 @@
      * @param egressPoints set of ports on which traffic will egress
      * @param constraints constraints to apply to the intent
      * @param priority priority to use for flows generated by this intent
-     * @param egressTreatments map to store the association egress to treatment
      * @throws NullPointerException if {@code ingressPoint} or
      *             {@code egressPoints} is null
      * @throws IllegalArgumentException if the size of {@code egressPoints} is
@@ -69,22 +64,20 @@
                                           Key key,
                                           TrafficSelector selector,
                                           TrafficTreatment treatment,
-                                          ConnectPoint ingressPoint,
-                                          Set<ConnectPoint> egressPoints,
+                                          FilteredConnectPoint ingressPoint,
+                                          Set<FilteredConnectPoint> egressPoints,
                                           List<Constraint> constraints,
-                                          int priority,
-                                          Map<ConnectPoint, TrafficTreatment> egressTreatments) {
+                                          int priority) {
         super(appId, key, ImmutableList.of(), selector, treatment, constraints,
               priority);
         checkNotNull(egressPoints);
         checkNotNull(ingressPoint);
         checkArgument(!egressPoints.isEmpty(), "Egress point set cannot be empty");
         checkArgument(!egressPoints.contains(ingressPoint),
-                "Set of egresses should not contain ingress (ingress: %s)", ingressPoint);
+                      "Set of egresses should not contain ingress (ingress: %s)", ingressPoint);
 
         this.ingressPoint = ingressPoint;
         this.egressPoints = Sets.newHashSet(egressPoints);
-        this.egressTreatments = egressTreatments;
     }
 
     /**
@@ -100,17 +93,42 @@
     }
 
     /**
+     * Creates a new builder pre-populated with the information in the given
+     * intent.
+     *
+     * @param intent initial intent
+     * @return intent builder
+     */
+    public static Builder builder(SinglePointToMultiPointIntent intent) {
+        return new Builder(intent);
+    }
+
+    /**
      * Builder of a single point to multi point intent.
      */
     public static final class Builder extends ConnectivityIntent.Builder {
-        ConnectPoint ingressPoint;
-        Set<ConnectPoint> egressPoints;
-        Map<ConnectPoint, TrafficTreatment> egressTreatments = ImmutableMap.of();
+        private final Logger log = getLogger(getClass());
+        private FilteredConnectPoint ingressPoint;
+        private Set<FilteredConnectPoint> egressPoints;
 
         private Builder() {
             // Hide constructor
         }
 
+        /**
+         * Creates a new builder pre-populated with information from the given
+         * intent.
+         *
+         * @param intent initial intent
+         */
+        protected Builder(SinglePointToMultiPointIntent intent) {
+            super(intent);
+
+            this.filteredEgressPoints(intent.filteredEgressPoints())
+                    .filteredIngressPoint(intent.filteredIngressPoint());
+
+        }
+
         @Override
         public Builder appId(ApplicationId appId) {
             return (Builder) super.appId(appId);
@@ -148,8 +166,13 @@
          * @param ingressPoint ingress connect point
          * @return this builder
          */
+        @Deprecated
         public Builder ingressPoint(ConnectPoint ingressPoint) {
-            this.ingressPoint = ingressPoint;
+            if (this.ingressPoint != null) {
+                log.warn("Ingress point is already set, " +
+                "this will override original ingress point.");
+            }
+            this.ingressPoint = new FilteredConnectPoint(ingressPoint);
             return this;
         }
 
@@ -160,24 +183,46 @@
          * @param egressPoints egress connect points
          * @return this builder
          */
+        @Deprecated
         public Builder egressPoints(Set<ConnectPoint> egressPoints) {
-            this.egressPoints = ImmutableSet.copyOf(egressPoints);
+            if (this.egressPoints != null) {
+                log.warn("Egress points are already set, " +
+                                 "this will override original egress points.");
+            }
+            Set<FilteredConnectPoint> filteredConnectPoints =
+                    egressPoints.stream()
+                            .map(FilteredConnectPoint::new)
+                            .collect(Collectors.toSet());
+            this.egressPoints = ImmutableSet.copyOf(filteredConnectPoints);
             return this;
         }
 
         /**
-         * Sets the treatments of the single point to multi point intent
-         * that will be built.
+         * Sets the filtered ingress point of the single point to
+         * multi point intent that will be built.
          *
-         * @param egressTreatments the multiple treatments
+         * @param ingressPoint ingress connect point
          * @return this builder
          */
-        public Builder treatments(Map<ConnectPoint, TrafficTreatment> egressTreatments) {
-            this.egressTreatments = ImmutableMap.copyOf(egressTreatments);
+        public Builder filteredIngressPoint(FilteredConnectPoint ingressPoint) {
+            this.ingressPoint = ingressPoint;
             return this;
         }
 
         /**
+         * Sets the filtered egress points of the single point to
+         * multi point intent that will be built.
+         *
+         * @param egressPoints egress connect points
+         * @return this builder
+         */
+        public Builder filteredEgressPoints(Set<FilteredConnectPoint> egressPoints) {
+            this.egressPoints = ImmutableSet.copyOf(egressPoints);
+            return this;
+        }
+
+
+        /**
          * Builds a single point to multi point intent from the
          * accumulated parameters.
          *
@@ -185,12 +230,6 @@
          */
         public SinglePointToMultiPointIntent build() {
 
-            if (treatment != null && !treatment.allInstructions().isEmpty() &&
-                    !treatment.equals(DefaultTrafficTreatment.emptyTreatment()) &&
-                    egressTreatments != null && !egressTreatments.isEmpty()) {
-                throw new IllegalArgumentException("Treatment and Multiple Treatments are both set");
-            }
-
             return new SinglePointToMultiPointIntent(
                     appId,
                     key,
@@ -199,8 +238,7 @@
                     ingressPoint,
                     egressPoints,
                     constraints,
-                    priority,
-                    egressTreatments
+                    priority
             );
         }
     }
@@ -212,7 +250,6 @@
         super();
         this.ingressPoint = null;
         this.egressPoints = null;
-        this.egressTreatments = null;
     }
 
     /**
@@ -222,7 +259,7 @@
      * @return ingress port
      */
     public ConnectPoint ingressPoint() {
-        return ingressPoint;
+        return ingressPoint.connectPoint();
     }
 
     /**
@@ -231,17 +268,31 @@
      * @return set of egress ports
      */
     public Set<ConnectPoint> egressPoints() {
-        return egressPoints;
+        return egressPoints.stream()
+                .map(FilteredConnectPoint::connectPoint)
+                .collect(Collectors.toSet());
     }
 
     /**
-     * Returns the multiple treatments jointly with their connection points.
-     * @return multiple treatments
+     * Returns the filtered port on which the ingress traffic should be connected to the
+     * egress.
+     *
+     * @return ingress port
      */
-    public Map<ConnectPoint, TrafficTreatment> egressTreatments() {
-        return egressTreatments;
+    public FilteredConnectPoint filteredIngressPoint() {
+        return ingressPoint;
     }
 
+    /**
+     * Returns the set of filtered ports on which the traffic should egress.
+     *
+     * @return set of egress ports
+     */
+    public Set<FilteredConnectPoint> filteredEgressPoints() {
+        return egressPoints;
+    }
+
+
     @Override
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
@@ -254,7 +305,8 @@
                 .add("treatment", treatment())
                 .add("ingress", ingressPoint)
                 .add("egress", egressPoints)
-                .add("treatments", egressTreatments)
+                .add("filteredIngressCPs", filteredIngressPoint())
+                .add("filteredEgressCP", filteredEgressPoints())
                 .add("constraints", constraints())
                 .toString();
     }