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/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();
+    }
+
 }