Support [ONOS-4593] and implement [ONOS-4594]

Changes:
- Adds extension to sp2mp intents;
- Adds extension to linkcollection intents;
- Adds extension to sp2mp compiler;
- Adds extension to linkcollection compiler;
- Adds re-ordering of the actions;
- Adds unit tests for both sp2mp intents and linkcollection intents;

Change-Id: Ib925e9066682e077a0bb4bbfd20a4382623b7541
diff --git a/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
index 6e9d68c..9cbe99f 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/ConnectivityIntentTest.java
@@ -43,6 +43,7 @@
     public static final TrafficSelector MATCH = DefaultTrafficSelector.emptySelector();
     public static final TrafficTreatment NOP = DefaultTrafficTreatment.emptyTreatment();
     public static final Map<ConnectPoint, TrafficSelector> MATCHES = Collections.emptyMap();
+    public static final Map<ConnectPoint, TrafficTreatment> TREATMENTS = Collections.emptyMap();
 
     public static final ConnectPoint P1 = new ConnectPoint(DeviceId.deviceId("111"), PortNumber.portNumber(0x1));
     public static final ConnectPoint P2 = new ConnectPoint(DeviceId.deviceId("222"), PortNumber.portNumber(0x2));
@@ -64,4 +65,17 @@
         VLANMATCHES.put(P2, VLANMATCH2);
     }
 
+    public static final TrafficTreatment VLANACTION1 = DefaultTrafficTreatment.builder()
+            .setVlanId(VlanId.vlanId("2"))
+            .build();
+    public static final TrafficTreatment VLANACTION2 = DefaultTrafficTreatment.builder()
+            .setVlanId(VlanId.vlanId("3"))
+            .build();
+
+    public static final Map<ConnectPoint, TrafficTreatment> VLANACTIONS = Maps.newHashMap();
+    static {
+        VLANACTIONS.put(P1, VLANACTION1);
+        VLANACTIONS.put(P2, VLANACTION2);
+    }
+
 }
diff --git a/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java b/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java
index b4c5952..f3db2fb 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/SinglePointToMultiPointIntentTest.java
@@ -15,7 +15,9 @@
  */
 package org.onosproject.net.intent;
 
+import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.ExpectedException;
 
 import static org.junit.Assert.assertEquals;
 import static org.onlab.junit.ImmutableClassChecker.assertThatClassIsImmutable;
@@ -42,6 +44,41 @@
         assertEquals("incorrect egress", PS2, intent.egressPoints());
     }
 
+    @Rule
+    public ExpectedException wrongMultiple = ExpectedException.none();
+
+    @Test
+    public void multipleTreatments() {
+
+        SinglePointToMultiPointIntent intent = createFirstMultiple();
+        assertEquals("incorrect id", APPID, intent.appId());
+        assertEquals("incorrect match", MATCH, intent.selector());
+        assertEquals("incorrect ingress", P1, intent.ingressPoint());
+        assertEquals("incorrect egress", PS2, intent.egressPoints());
+        assertEquals("incorrect treatment", NOP, intent.treatment());
+        assertEquals("incorrect treatments", TREATMENTS, intent.egressTreatments());
+
+        intent = createSecondMultiple();
+        assertEquals("incorrect id", APPID, intent.appId());
+        assertEquals("incorrect match", MATCH, intent.selector());
+        assertEquals("incorrect ingress", P1, intent.ingressPoint());
+        assertEquals("incorrect egress", PS2, intent.egressPoints());
+        assertEquals("incorrect treatment", VLANACTION1, intent.treatment());
+        assertEquals("incorrect selectors", TREATMENTS, intent.egressTreatments());
+
+        intent = createThirdMultiple();
+        assertEquals("incorrect id", APPID, intent.appId());
+        assertEquals("incorrect match", MATCH, intent.selector());
+        assertEquals("incorrect ingress", P1, intent.ingressPoint());
+        assertEquals("incorrect egress", PS2, intent.egressPoints());
+        assertEquals("incorrect treatment", NOP, intent.treatment());
+        assertEquals("incorrect selectors", VLANACTIONS, intent.egressTreatments());
+
+        wrongMultiple.expect(IllegalArgumentException.class);
+        wrongMultiple.expectMessage("Treatment and Multiple Treatments are both set");
+        intent = createWrongMultiple();
+    }
+
     @Override
     protected SinglePointToMultiPointIntent createOne() {
         return SinglePointToMultiPointIntent.builder()
@@ -63,4 +100,50 @@
                 .egressPoints(PS1)
                 .build();
     }
+
+
+    protected SinglePointToMultiPointIntent createFirstMultiple() {
+        return SinglePointToMultiPointIntent.builder()
+                .appId(APPID)
+                .selector(MATCH)
+                .treatment(NOP)
+                .ingressPoint(P1)
+                .egressPoints(PS2)
+                .treatments(TREATMENTS)
+                .build();
+    }
+
+    protected SinglePointToMultiPointIntent createSecondMultiple() {
+        return SinglePointToMultiPointIntent.builder()
+                .appId(APPID)
+                .selector(MATCH)
+                .treatment(VLANACTION1)
+                .ingressPoint(P1)
+                .egressPoints(PS2)
+                .treatments(TREATMENTS)
+                .build();
+    }
+
+    protected SinglePointToMultiPointIntent createThirdMultiple() {
+        return SinglePointToMultiPointIntent.builder()
+                .appId(APPID)
+                .selector(MATCH)
+                .treatment(NOP)
+                .ingressPoint(P1)
+                .egressPoints(PS2)
+                .treatments(VLANACTIONS)
+                .build();
+    }
+
+    protected SinglePointToMultiPointIntent createWrongMultiple() {
+        return SinglePointToMultiPointIntent.builder()
+                .appId(APPID)
+                .selector(MATCH)
+                .treatment(VLANACTION1)
+                .ingressPoint(P1)
+                .egressPoints(PS2)
+                .treatments(VLANACTIONS)
+                .build();
+    }
+
 }