Support multi-instance for avoid policy, after resolving a minor conflict.
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/PolicyNotification.java b/src/main/java/net/onrc/onos/apps/segmentrouting/PolicyNotification.java
index 4bcf1bc..ebb750c 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/PolicyNotification.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/PolicyNotification.java
@@ -1,9 +1,13 @@
 package net.onrc.onos.apps.segmentrouting;
 
 import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
 
 import net.onrc.onos.apps.segmentrouting.SegmentRoutingPolicy.PolicyType;
 import net.onrc.onos.core.matchaction.match.PacketMatch;
+import net.onrc.onos.core.topology.Link;
+import net.onrc.onos.core.topology.LinkData;
 
 public class PolicyNotification implements Serializable {
 
@@ -11,8 +15,18 @@
     private String policyType;
     private int priority;
     private PacketMatch match;
-    private String tunnelId;  // XXX need to define PolicyTunnelNotification
     private boolean isSetId;
+
+    // Tunnel policy
+    private String tunnelId;
+
+    // Avoid policy
+    private String srcDpid;
+    private String dstDpid;
+    private List<String> dpidListToAvoid;
+    private List<LinkData> linkListToAvoid;
+    private List<TunnelNotification> tunnels;
+
     /**
      *
      */
@@ -32,11 +46,27 @@
         this.priority = srPolicy.getPriority();
         this.match = srPolicy.getMatch();
 
-        // XXX need to be processed in PolicyTunnelNotification
         if (PolicyType.valueOf(policyType) == PolicyType.TUNNEL_FLOW) {
             this.tunnelId = ((SegmentRoutingPolicyTunnel)srPolicy).getTunnelId();
             this.isSetId = ((SegmentRoutingPolicyTunnel)srPolicy).isTunnelsetId();
         }
+        else if (PolicyType.valueOf(policyType) == PolicyType.AVOID) {
+            SegmentRoutingPolicyAvoid avoidPolicy =
+                    (SegmentRoutingPolicyAvoid)srPolicy;
+            this.srcDpid = avoidPolicy.getSource();
+            this.dstDpid = avoidPolicy.getDestination();
+            this.dpidListToAvoid = avoidPolicy.getDpidListToAvoid();
+            this.linkListToAvoid = new ArrayList<LinkData>();
+            for (Link link: avoidPolicy.getLinkListToAvoid()) {
+                LinkData linkData = new LinkData(link);
+                linkListToAvoid.add(linkData);
+            }
+            this.tunnels = new ArrayList<TunnelNotification>();
+            for (SegmentRoutingTunnel tunnel: avoidPolicy.getTunnels()) {
+                TunnelNotification tn = new TunnelNotification(tunnel);
+                tunnels.add(tn);
+            }
+        }
     }
 
 
@@ -74,9 +104,29 @@
     public String getTunnelId() {
         return tunnelId;
     }
-    
+
     public boolean isTunnelsetId() {
     	return this.isSetId;
     }
 
+    public String getSource() {
+        return this.srcDpid;
+    }
+
+    public String getDestination() {
+        return this.dstDpid;
+    }
+
+    public List<String> getDpidListToAvoid() {
+        return this.dpidListToAvoid;
+    }
+
+    public List<LinkData> getLinkListToAvoid() {
+        return this.linkListToAvoid;
+    }
+
+    public List<TunnelNotification> getTunnels() {
+        return this.tunnels;
+    }
+
 }
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
index 9a5aaea..921fd35 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingManager.java
@@ -280,7 +280,7 @@
         });
 
         //testMode = TEST_MODE.POLICY_AVOID;
-        //testTask.reschedule(30, TimeUnit.SECONDS);
+        //testTask.reschedule(40, TimeUnit.SECONDS);
     }
 
     @Override
@@ -310,13 +310,24 @@
 
         @Override
         public void entryAdded(PolicyNotification policyNotication) {
-            log.debug("Policy entry {} was added", policyNotication);
+            SegmentRoutingPolicy srPolicy = null;
             if (PolicyType.valueOf(policyNotication.getPolicyType()) ==
                     PolicyType.TUNNEL_FLOW) {
-                SegmentRoutingPolicyTunnel srPolicy =
-                        new SegmentRoutingPolicyTunnel(srManager, policyNotication);
+                srPolicy = new SegmentRoutingPolicyTunnel(srManager,
+                        policyNotication);
+            }
+            else if (PolicyType.valueOf(policyNotication.getPolicyType()) ==
+                    PolicyType.AVOID) {
+                srPolicy = new SegmentRoutingPolicyAvoid(srManager,
+                        policyNotication);
                 policyTable.put(srPolicy.getPolicyId(), srPolicy);
             }
+            else {
+                log.warn("Other policy is not supported yet");
+                return;
+            }
+            policyTable.put(srPolicy.getPolicyId(), srPolicy);
+            log.debug("Policy entry {} was added", policyNotication);
         }
 
         @Override
@@ -389,6 +400,9 @@
             processMastershipAdded(topologyEvents.getAddedMastershipDataEntries());
         }
 
+        if (discoveryTask == null)
+            return;
+
         if (operationMode == 0) {
             discoveryTask.reschedule(20, TimeUnit.SECONDS);
             operationMode = 1; // Wait until all switches are up ..
@@ -1464,15 +1478,14 @@
         }
 
         SegmentRoutingPolicy avoidPolicy = new SegmentRoutingPolicyAvoid(this,
-                pid, policyMatch, priority, srcSwitch, dstSwitch,
-                dpidListToAvoid, linksToAvoid);
+                pid, policyMatch, priority, srcSwitch.getDpid().toString(),
+                dstSwitch.getDpid().toString(), dpidListToAvoid, linksToAvoid);
         if (avoidPolicy.createPolicy()) {
             policyTable.put(pid, avoidPolicy);
-            // TODO: handle multi-instance
-            //PolicyNotification policyNotification =
-            //        new PolicyNotification(avoidPolicy);
-            //policyEventChannel.addEntry(pid,
-            //        policyNotification);
+            PolicyNotification policyNotification =
+                    new PolicyNotification(avoidPolicy);
+            policyEventChannel.addEntry(pid,
+                    policyNotification);
             return true;
         }
         else {
@@ -2303,8 +2316,8 @@
             createPolicy(pid, srcMac, dstMac, etherType, srcIp, dstIp, ipProto,
                     srcPort, dstPort, priority, srcNode, dstNode, nodesToAvoid, linksToAvoid);
 
-            //testMode = TEST_MODE.POLICY_REMOVE3;
-            //testTask.reschedule(10, TimeUnit.SECONDS);
+            testMode = TEST_MODE.POLICY_REMOVE3;
+            testTask.reschedule(20, TimeUnit.SECONDS);
 
         }
         else if (testMode == TEST_MODE.POLICY_REMOVE3) {
diff --git a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicyAvoid.java b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicyAvoid.java
index ff3d18c..835c770 100644
--- a/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicyAvoid.java
+++ b/src/main/java/net/onrc/onos/apps/segmentrouting/SegmentRoutingPolicyAvoid.java
@@ -18,8 +18,8 @@
     private static final Logger log = LoggerFactory
             .getLogger(SegmentRoutingPolicyTunnel.class);
 
-    private Switch srcSwitch;
-    private Switch dstSwitch;
+    private String srcDpid;
+    private String dstDpid;
     private List<String> dpidListToAvoid;
     private List<Link> linkListToAvoid;
     private List<SegmentRoutingTunnel> tunnels;
@@ -30,20 +30,43 @@
     }
 
     public SegmentRoutingPolicyAvoid(SegmentRoutingManager srm, String pid,
-            PacketMatch match, int priority, Switch from, Switch to,
-            List<String> dpidList, List<net.onrc.onos.core.topology.Link> linksToAvoid) {
+            PacketMatch match, int priority, String from, String to,
+            List<String> dpidList, List<Link> linksToAvoid) {
         super(srm, pid, PolicyType.AVOID, match, priority);
-        this.srcSwitch = from;
-        this.dstSwitch = to;
+        this.srcDpid = from;
+        this.dstDpid = to;
         this.dpidListToAvoid = dpidList;
         this.linkListToAvoid = linksToAvoid;
         this.tunnels = new ArrayList<SegmentRoutingTunnel>();
     }
 
+    public SegmentRoutingPolicyAvoid(SegmentRoutingManager srm,
+            PolicyNotification pn) {
+        super(srm, pn.getPolicyId(), PolicyType.AVOID, pn.getPacketMatch(),
+                pn.getPriority());
+        this.srcDpid = pn.getSource();
+        this.srcDpid     = pn.getDestination();
+        this.dpidListToAvoid = pn.getDpidListToAvoid();
+        this.linkListToAvoid = new ArrayList<Link>();
+        for (LinkData linkData: pn.getLinkListToAvoid()) {
+            Switch sw =
+                    srManager.getSwitch(linkData.getSrc().getDpid().toString());
+            Link link = sw.getLinkToNeighbor(linkData.getDst().getDpid());
+            linkListToAvoid.add(link);
+        }
+        this.tunnels = new ArrayList<SegmentRoutingTunnel>();
+        for (TunnelNotification tn: pn.getTunnels()) {
+            SegmentRoutingTunnel srTunnel = new SegmentRoutingTunnel(srm, tn);
+            tunnels.add(srTunnel);
+        }
+    }
+
     @Override
     public boolean createPolicy() {
 
         //Create a tunnel from srcSwitch to dstSwitch avoiding swToAvoid;
+        Switch srcSwitch = srManager.getSwitch(srcDpid);
+        Switch dstSwitch = srManager.getSwitch(dstDpid);
         ECMPShortestPathGraph graph = new ECMPShortestPathGraph(srcSwitch,
                 dpidListToAvoid, linkListToAvoid);
         List<Path> ecmpPaths = graph.getECMPPaths(dstSwitch);
@@ -63,10 +86,6 @@
                     srManager, "avoid-0", labelStack);
             tunnels.add(tunnel);
             if (tunnel.createTunnel()) {
-                //tunnelTable.put(tunnelId, srTunnel);
-                //TunnelNotification tunnelNotification =
-                //        new TunnelNotification(srTunnel);
-                //tunnelEventChannel.addEntry(tunnelId, tunnelNotification);
                 populateAclRule(tunnel.getRoutes());
             }
             else {
@@ -96,6 +115,8 @@
 
     @Override
     public void updatePolicy() {
+        Switch srcSwitch = srManager.getSwitch(srcDpid);
+        Switch dstSwitch = srManager.getSwitch(dstDpid);
         ECMPShortestPathGraph graph = new ECMPShortestPathGraph(srcSwitch,
                 dpidListToAvoid, linkListToAvoid);
         List<Path> ecmpPaths = graph.getECMPPaths(dstSwitch);
@@ -228,4 +249,24 @@
 
         return false;
     }
+
+    public String getSource() {
+        return this.srcDpid;
+    }
+
+    public String getDestination() {
+        return this.dstDpid;
+    }
+
+    public List<String> getDpidListToAvoid() {
+        return this.dpidListToAvoid;
+    }
+
+    public List<Link> getLinkListToAvoid() {
+        return this.linkListToAvoid;
+    }
+
+    public List<SegmentRoutingTunnel> getTunnels() {
+        return this.tunnels;
+    }
 }
diff --git a/src/main/java/net/onrc/onos/core/util/serializers/KryoFactory.java b/src/main/java/net/onrc/onos/core/util/serializers/KryoFactory.java
index a634bea..c169791 100644
--- a/src/main/java/net/onrc/onos/core/util/serializers/KryoFactory.java
+++ b/src/main/java/net/onrc/onos/core/util/serializers/KryoFactory.java
@@ -347,8 +347,6 @@
         kryo.register(TunnelRouteInfo.class);
         kryo.register(NeighborSet.class);
         kryo.register(groupPktType.class);
-
-
         return kryo;
     }