Refactored Mfwd to use new mcastroutemanager

Change-Id: I7aca7f118221ed505aeb7fcace0ef9dccb468a34
diff --git a/apps/mfwd/pom.xml b/apps/mfwd/pom.xml
index 2dc3a66..835de83 100644
--- a/apps/mfwd/pom.xml
+++ b/apps/mfwd/pom.xml
@@ -22,7 +22,7 @@
     <parent>
         <groupId>org.onosproject</groupId>
         <artifactId>onos-apps</artifactId>
-        <version>1.5.0-SNAPSHOT</version>
+        <version>1.4.0-SNAPSHOT</version>
         <relativePath>../pom.xml</relativePath>
     </parent>
 
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastDeleteCommand.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastDeleteCommand.java
index c794c80..5ef4dce 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastDeleteCommand.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastDeleteCommand.java
@@ -15,10 +15,15 @@
  */
 package org.onosproject.mfwd.cli;
 
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.karaf.shell.commands.Argument;
 import org.apache.karaf.shell.commands.Command;
 import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.mfwd.impl.McastRouteTable;
+import org.onosproject.mfwd.impl.McastForwarding;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.mcast.McastRoute;
+import org.onosproject.net.mcast.MulticastRouteService;
 
 /**
  * Deletes a multicast route.
@@ -27,6 +32,9 @@
         description = "Delete a multicast route flow")
 public class McastDeleteCommand extends AbstractShellCommand {
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    MulticastRouteService mcastRouteManager = AbstractShellCommand.get(MulticastRouteService.class);
+
     @Argument(index = 0, name = "sAddr",
             description = "IP Address of the multicast source. '*' can be used for any source (*, G) entry",
             required = true, multiValued = false)
@@ -46,23 +54,16 @@
     @Override
     protected void execute() {
 
-        boolean deleted = false;
-        McastRouteTable mrib = McastRouteTable.getInstance();
+        McastRoute mRoute = McastForwarding.createStaticRoute(sAddr, gAddr);
 
         if (egressList == null) {
-            mrib.removeRoute(sAddr, gAddr);
-            deleted = true;
+            mcastRouteManager.remove(mRoute);
         } else {
             // check list for validity before we begin to delete.
             for (String egress : egressList) {
-                deleted = mrib.removeEgress(sAddr, gAddr, egress);
+                ConnectPoint eCp = ConnectPoint.deviceConnectPoint(egress);
+                mcastRouteManager.removeSink(mRoute, eCp);
             }
         }
-
-        if (deleted) {
-            print("Successful delete");
-        } else {
-            print("Failed to delete");
-        }
     }
 }
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastJoinCommand.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastJoinCommand.java
index 7260fde..3f22e7a 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastJoinCommand.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastJoinCommand.java
@@ -15,13 +15,15 @@
  */

 package org.onosproject.mfwd.cli;

 

+import org.apache.felix.scr.annotations.Reference;

+import org.apache.felix.scr.annotations.ReferenceCardinality;

 import org.apache.karaf.shell.commands.Argument;

 import org.apache.karaf.shell.commands.Command;

 import org.onosproject.cli.AbstractShellCommand;

-

-import org.onosproject.mfwd.impl.McastConnectPoint;

-import org.onosproject.mfwd.impl.McastRouteBase;

-import org.onosproject.mfwd.impl.McastRouteTable;

+import org.onosproject.mfwd.impl.McastForwarding;

+import org.onosproject.net.ConnectPoint;

+import org.onosproject.net.mcast.McastRoute;

+import org.onosproject.net.mcast.MulticastRouteService;

 

 /**

  * Installs a source, multicast group flow.

@@ -30,6 +32,9 @@
          description = "Installs a source, multicast group flow")

 public class McastJoinCommand extends AbstractShellCommand {

 

+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)

+    MulticastRouteService mcastRouteManager = AbstractShellCommand.get(MulticastRouteService.class);

+

     @Argument(index = 0, name = "sAddr",

               description = "IP Address of the multicast source. '*' can be used for any source (*, G) entry",

               required = true, multiValued = false)

@@ -41,31 +46,29 @@
     String gAddr = null;

 

     @Argument(index = 2, name = "ingressPort",

-            description = "Ingress port and Egress ports",

+            description = "Ingress port of:XXXXXXXXXX/XX",

             required = false, multiValued = false)

     String ingressPort = null;

 

     @Argument(index = 3, name = "ports",

-              description = "Ingress port and Egress ports",

+              description = "Egress ports of:XXXXXXXXXX/XX...",

               required = false, multiValued = true)

     String[] ports = null;

 

     @Override

     protected void execute() {

-        McastRouteTable mrib = McastRouteTable.getInstance();

-        McastRouteBase mr = mrib.addRoute(sAddr, gAddr);

 

-        // Port format "of:0000000000000023/4"

-        if (ingressPort != null) {

-            String inCP = ingressPort;

-            log.debug("Ingress port provided: " + inCP);

-            mr.addIngressPoint(inCP);

-        }

+        McastRoute mRoute = McastForwarding.createStaticRoute(sAddr, gAddr);

+        mcastRouteManager.add(mRoute);

 

-        for (int i = 0; i < ports.length; i++) {

-            String egCP = ports[i];

+        ConnectPoint ingress = ConnectPoint.deviceConnectPoint(ingressPort);

+        mcastRouteManager.addSource(mRoute, ingress);

+

+        for (String egCP : ports) {

             log.debug("Egress port provided: " + egCP);

-            mr.addEgressPoint(egCP, McastConnectPoint.JoinSource.STATIC);

+            ConnectPoint egress = ConnectPoint.deviceConnectPoint(egCP);

+            mcastRouteManager.addSink(mRoute, egress);

+

         }

         print("Added the mcast route");

     }

diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastShowCommand.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastShowCommand.java
index 7fa3a13..1d3f850 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastShowCommand.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/cli/McastShowCommand.java
@@ -15,15 +15,13 @@
  */
 package org.onosproject.mfwd.cli;
 
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.karaf.shell.commands.Command;
 
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.databind.JsonNode;
-
 import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.mfwd.impl.McastRouteTable;
-import org.onosproject.mfwd.impl.MRibCodec;
 
+import org.onosproject.net.mcast.MulticastRouteService;
 import org.slf4j.Logger;
 import static org.slf4j.LoggerFactory.getLogger;
 
@@ -33,30 +31,15 @@
 @Command(scope = "onos", name = "mcast-show", description = "Displays the source, multicast group flows")
 public class McastShowCommand extends AbstractShellCommand {
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    MulticastRouteService mcastRouteManager = AbstractShellCommand.get(MulticastRouteService.class);
+
     private final Logger log = getLogger(getClass());
     private static final String MCAST_GROUP = "mcastgroup";
 
     @Override
     protected void execute() {
-        McastRouteTable mrt = McastRouteTable.getInstance();
-        if (outputJson()) {
-            print("%s", json(mrt));
-        } else {
-            printMrib4(mrt);
-        }
+        //TODO
     }
 
-    public JsonNode json(McastRouteTable mrt) {
-        ObjectNode pushContent = new MRibCodec().encode(mrt , this);
-        return pushContent;
-    }
-
-    /**
-     * Displays multicast route table entries.
-     *
-     * @param mrt Mutlicast Route Table
-     */
-    protected void printMrib4(McastRouteTable mrt) {
-        print(mrt.printMcastRouteTable());
-    }
 }
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/MRibCodec.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/MRibCodec.java
deleted file mode 100644
index c4f1852..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/MRibCodec.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.mfwd.impl;
-
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-
-import org.onlab.packet.IpPrefix;
-
-import java.util.Set;
-import java.util.Map;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Optional;
-
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.node.JsonNodeFactory;
-
-import org.slf4j.Logger;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Encode and Decode the Multicast Route Table in JSON for CLI and REST commands.
- */
-public class MRibCodec extends JsonCodec<McastRouteTable> {
-
-    private final Logger log = getLogger(getClass());
-    private static final String SOURCE_ADDRESS = "sourceAddress";
-    private static final String GROUP_ADDRESS = "groupAddress";
-    private static final String INGRESS_POINT = "ingressPoint";
-    private static final String EGRESS_POINT = "egressPoint";
-    private static final String MCASTCONNECTPOINT = "McastConnectPoint";
-    private static final String ELEMENTID = "elementId";
-    private static final String PORTNUMBER = "portNumber";
-    private static final String MCAST_GROUP = "mcastGroup";
-
-    /**
-     * Encode the MRIB into json format.
-     *
-     * @param mcastRouteTable McastRouteTable
-     * @param context CodecContext
-     * @return result ObjectNode
-     */
-    @Override
-    public ObjectNode encode(McastRouteTable mcastRouteTable, CodecContext context) {
-
-        final JsonNodeFactory nodeFactory = JsonNodeFactory.instance;
-        final ObjectNode macastRouteTabNode = nodeFactory.objectNode();
-        ArrayNode mcastGroupNode = context.mapper().createArrayNode();
-        Optional<McastRouteTable> mcastRouteTabOpt = Optional.ofNullable(mcastRouteTable);
-
-        //checking whether the McastRouteTable is present.
-        if (mcastRouteTabOpt.isPresent()) {
-            Map<IpPrefix, McastRouteGroup> mrib4 = mcastRouteTabOpt.get().getMrib4();
-            Optional<Map<IpPrefix, McastRouteGroup>> mrib4Opt = Optional.ofNullable(mrib4);
-
-            //checking whether the mrib4 is present.
-            if (mrib4Opt.isPresent()) {
-
-                for (McastRouteGroup mg : mrib4Opt.get().values()) {
-                    Collection<McastRouteSource> mcastRoute = mg.getSources().values();
-                    Optional<Collection<McastRouteSource>> mcastRouteOpt = Optional.ofNullable(mcastRoute);
-
-                    //checking whether the McastRouteSource List is present.
-                    if (mcastRouteOpt.isPresent()) {
-                        for (McastRouteSource mcastRouteSource : mcastRouteOpt.get()) {
-                            mcastGroupNode.add(createMcastGroupNode(mcastRouteSource, context));
-                        }
-                        macastRouteTabNode.put(MCAST_GROUP, mcastGroupNode);
-                    }
-                }
-            }
-        }
-        return macastRouteTabNode;
-    }
-    /**
-     * Method for creating the McastGroup object node.
-     *
-     * @param mcastRouteSource McastRouteSource
-     */
-    private ObjectNode createMcastGroupNode(McastRouteSource mcastRouteSource, CodecContext context) {
-
-        final ObjectNode mcastGroupNode = context.mapper().createObjectNode();
-        final ObjectNode ingressNode = context.mapper().createObjectNode();
-        final ObjectNode egressNode = context.mapper().createObjectNode();
-        final ArrayNode jsonLabelIds = context.mapper().createArrayNode();
-        final String sAddr = mcastRouteSource.getSaddr().toString();
-        final String gAddr = mcastRouteSource.getGaddr().toString();
-
-        Optional<String> saddrOpt = Optional.ofNullable(sAddr);
-        Optional<String> gaddrOpt = Optional.ofNullable(gAddr);
-
-        //checking source address and group address are present.
-        if (saddrOpt.isPresent() && gaddrOpt.isPresent()) {
-            mcastGroupNode.put(SOURCE_ADDRESS, saddrOpt.get().toString());
-            mcastGroupNode.put(GROUP_ADDRESS, gaddrOpt.get().toString());
-            McastConnectPoint mcastIngCP = mcastRouteSource.getIngressPoint();
-            Optional<McastConnectPoint> mcastIngCPOpt = Optional.ofNullable(mcastIngCP);
-
-            //checking whether the ingress connection point is present.
-            if (mcastIngCPOpt.isPresent()) {
-                ingressNode.put(MCASTCONNECTPOINT, mcastConnectPoint(mcastIngCPOpt.get(), context));
-            }
-
-            mcastGroupNode.put(INGRESS_POINT , ingressNode);
-            Set<McastConnectPoint> mcastEgCPSet = mcastRouteSource.getEgressPoints();
-            Optional<Set<McastConnectPoint>> mcastEgCPOpt = Optional.ofNullable(mcastEgCPSet);
-
-            //checking whether the egress connection points are present.
-            if (mcastEgCPOpt.isPresent()) {
-                for (final McastConnectPoint mcastConnectPoint : mcastEgCPOpt.get()) {
-                    jsonLabelIds.add(mcastConnectPoint(mcastConnectPoint, context));
-                }
-            }
-
-            egressNode.put(MCASTCONNECTPOINT , jsonLabelIds);
-            mcastGroupNode.put(EGRESS_POINT , egressNode);
-        }
-        return mcastGroupNode;
-    }
-
-    /**
-     * Method for creating the McastConnectPoint object node.
-     *
-     * @param mcastConnectPoint McastConnectPoint
-     * @param context CodecContext
-     * @return mcastCpNode ObjectNode
-     */
-    private ObjectNode mcastConnectPoint(McastConnectPoint mcastConnectPoint, CodecContext context) {
-        final ObjectNode mcastCpNode = context.mapper().createObjectNode();
-        mcastCpNode.put(ELEMENTID , mcastConnectPoint.getConnectPoint().elementId().toString());
-        mcastCpNode.put(PORTNUMBER , mcastConnectPoint.getConnectPoint().port().toLong());
-        return mcastCpNode;
-    }
-
-    /**
-     * Decode json format and insert into the flow table.
-     *
-     * @param json ObjectNode
-     * @param context CodecContext
-     * @return mr McastRouteBase
-     */
-    @Override
-    public McastRouteTable decode(ObjectNode json, CodecContext context) {
-
-        String macAddr = null;
-        String portNo = null;
-        String sAddr = json.path(SOURCE_ADDRESS).asText();
-        String gAddr = json.path(GROUP_ADDRESS).asText();
-        JsonNode inPntObjNode = (JsonNode) json.path(INGRESS_POINT);
-        JsonNode egPntArrNode = (JsonNode) json.path(EGRESS_POINT);
-
-        log.debug("sAddr :" + sAddr + " gAddr :" + gAddr + " inPntObjNode :" + inPntObjNode);
-        log.debug("egPntArrNode :" + egPntArrNode.toString());
-
-        McastRouteTable mrib = McastRouteTable.getInstance();
-        McastRouteBase mr = mrib.addRoute(sAddr, gAddr);
-        Optional<JsonNode> inPntOpt = Optional.ofNullable(inPntObjNode);
-
-        if (inPntOpt.isPresent()) {
-
-            JsonNode inMcastCP = inPntOpt.get().path(MCASTCONNECTPOINT);
-            Optional<JsonNode> inCpOpt = Optional.ofNullable(inMcastCP);
-
-            if (inCpOpt.isPresent()) {
-                macAddr = inCpOpt.get().path(ELEMENTID).asText();
-                portNo = inCpOpt.get().path(PORTNUMBER).asText();
-                mr.addIngressPoint(macAddr + "/" + Long.parseLong(portNo));
-            }
-        }
-
-        Optional<JsonNode> egPntOpt = Optional.ofNullable(egPntArrNode);
-
-        if (egPntOpt.isPresent()) {
-            JsonNode egMcastCP = egPntOpt.get().path(MCASTCONNECTPOINT);
-            Optional<JsonNode> egMcCpOpt = Optional.ofNullable(egMcastCP);
-
-            if (egMcCpOpt.isPresent()) {
-                Iterator<JsonNode> egCpIt = egMcCpOpt.get().elements();
-
-                while (egCpIt.hasNext()) {
-
-                    JsonNode egMcastCPObj = egCpIt.next();
-                    Optional<JsonNode> egMcCpObOpt = Optional.ofNullable(egMcastCPObj);
-                    if (egMcCpObOpt.isPresent()) {
-                        macAddr = egMcCpObOpt.get().path(ELEMENTID).asText();
-                        portNo = egMcCpObOpt.get().path(PORTNUMBER).asText();
-                        log.debug("macAddr egPort : " + macAddr + " portNo egPort :" + portNo);
-                        mr.addEgressPoint(macAddr + "/" + Long.parseLong(portNo), McastConnectPoint.JoinSource.STATIC);
-                    }
-                }
-            }
-        }
-       return mrib;
-    }
-}
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastConnectPoint.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastConnectPoint.java
deleted file mode 100644
index e2a6ff0..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastConnectPoint.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.mfwd.impl;
-
-import org.onosproject.net.ConnectPoint;
-import java.util.EnumSet;
-import java.util.Set;
-
-/**
- * Mulitcast ConnectPoint adds a variable to track the usage
- * of these multicast endpoints.
- */
-public class McastConnectPoint {
-
-    private ConnectPoint connectPoint;
-
-    public enum JoinSource {
-        STATIC, IGMP, PIM;
-    }
-
-    public EnumSet<JoinSource> interest = EnumSet.noneOf(JoinSource.class);
-
-    public McastConnectPoint(ConnectPoint cp) {
-        this.connectPoint = cp;
-    }
-
-    public McastConnectPoint(ConnectPoint cp, JoinSource src) {
-        this.connectPoint = cp;
-        interest.add(src);
-    }
-
-    public McastConnectPoint(String connectPoint, JoinSource src) {
-        ConnectPoint cp = ConnectPoint.deviceConnectPoint(connectPoint);
-        this.connectPoint = cp;
-        this.interest.add(src);
-    }
-
-    /**
-     * Get the connect point.
-     *
-     * @return connectPoint
-     */
-    public ConnectPoint getConnectPoint() {
-        return connectPoint;
-    }
-
-    /**
-     * Get the sources of interest for this egressPoint.
-     *
-     * @return interest flags
-     */
-    public Set<JoinSource> getInterest() {
-        return interest;
-    }
-}
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java
index 2b9a2a5..f46d77b 100644
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java
+++ b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastForwarding.java
@@ -15,6 +15,7 @@
  */
 package org.onosproject.mfwd.impl;
 
+import static com.google.common.base.Preconditions.checkNotNull;
 import static org.slf4j.LoggerFactory.getLogger;
 
 import org.apache.felix.scr.annotations.Activate;
@@ -35,6 +36,8 @@
 import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.mcast.MulticastRouteService;
+import org.onosproject.net.mcast.McastRoute;
 import org.onosproject.net.packet.DefaultOutboundPacket;
 import org.onosproject.net.packet.InboundPacket;
 import org.onosproject.net.packet.OutboundPacket;
@@ -44,8 +47,12 @@
 import org.onosproject.net.packet.PacketService;
 import org.slf4j.Logger;
 
+import java.util.ArrayList;
+
 /**
- * WORK-IN-PROGRESS: The multicast forwarding application using intent framework.
+ * The multicast forwarding component.  This component is responsible for
+ * handling live multicast traffic by modifying multicast state and forwarding
+ * packets that do not yet have state installed.
  */
 @Component(immediate = true)
 public class McastForwarding {
@@ -59,8 +66,12 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected CoreService coreService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MulticastRouteService mcastRouteManager;
+
+
+
     private ReactivePacketProcessor processor = new ReactivePacketProcessor();
-    private McastRouteTable mrib;
     private static ApplicationId appId;
 
     /**
@@ -76,9 +87,9 @@
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         selector.matchEthType(Ethernet.TYPE_IPV4);
         selector.matchIPDst(mcast);
+
         packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
 
-        mrib = McastRouteTable.getInstance();
         log.info("Started");
     }
 
@@ -137,8 +148,8 @@
             }
 
             IPv4 ip = (IPv4) ethPkt.getPayload();
-            IpAddress gaddr = IpAddress.valueOf(ip.getDestinationAddress());
             IpAddress saddr = Ip4Address.valueOf(ip.getSourceAddress());
+            IpAddress gaddr = IpAddress.valueOf(ip.getDestinationAddress());
 
             log.debug("Packet ({}, {}) has been punted\n" +
                             "\tingress port: {}\n",
@@ -146,70 +157,37 @@
                     gaddr.toString(),
                     context.inPacket().receivedFrom().toString());
 
-            if (!mcast.contains(gaddr)) {
-                // Yikes, this is a bad group address
-                return;
-            }
-
-            if (mcast.contains(saddr)) {
-                // Yikes, the source address is multicast
+            // Don't allow PIM/IGMP packets to be handled here.
+            byte proto = ip.getProtocol();
+            if (proto == IPv4.PROTOCOL_PIM || proto == IPv4.PROTOCOL_IGMP) {
                 return;
             }
 
             IpPrefix spfx = IpPrefix.valueOf(saddr, 32);
             IpPrefix gpfx = IpPrefix.valueOf(gaddr, 32);
 
-            /*
-             * Do a best match lookup on the (s, g) of the packet. If an entry does
-             * not exist create one and store it's incoming connect point.
-             *
-             * The connect point is deviceId / portId that the packet entered
-             * the SDN network.  This differs from traditional mcast where the
-             * ingress port would be a specific device.
-             */
-            McastRoute entry = mrib.findBestMatch(spfx, gpfx);
-            if (entry == null || entry.getSaddr().address().isZero()) {
+            // TODO do we want to add a type for Mcast?
+            McastRoute mRoute = new McastRoute(spfx, gpfx, McastRoute.Type.STATIC);
 
-                /*
-                 * Create an entry that we can fast drop.
-                 */
-                entry = mrib.addRoute(spfx, gpfx);
-                entry.addIngressPoint(context.inPacket().receivedFrom());
+            ConnectPoint ingress = mcastRouteManager.fetchSource(mRoute);
+
+            // An ingress port already exists. Log error.
+            if (ingress != null) {
+                log.error(McastForwarding.class.getSimpleName() + " received packet which already has a route.");
+                return;
+            } else {
+                //add ingress port
+                mcastRouteManager.addSource(mRoute, pkt.receivedFrom());
             }
 
-            /*
-             * TODO: If we do not have an ingress or any egress connect points we
-             * should set up a fast drop entry.
-             */
-            if (entry.getIngressPoint() == null) {
+            ArrayList<ConnectPoint> egressList = (ArrayList<ConnectPoint>) mcastRouteManager.fetchSinks(mRoute);
+            //If there are no egress ports set return, otherwise forward the packets to their expected port.
+            if (egressList.size() == 0) {
                 return;
             }
 
-            if (entry.getEgressPoints().isEmpty()) {
-                return;
-            }
-
-            /*
-             * This is odd, we should not have received a punted packet if an
-             * intent was installed unless the intent was not installed
-             * correctly.  However, we are seeing packets get punted after
-             * the intent has been installed.
-             *
-             * Therefore we are going to forward the packets even if they
-             * should have already been forwarded by the intent fabric.
-             */
-            if (entry.getIntentKey() != null) {
-                return;
-            }
-
-            entry.setIntent();
-            McastIntentManager im = McastIntentManager.getInstance();
-            im.setIntent(entry);
-
-            entry.incrementPuntCount();
-
             // Send the pack out each of the egress devices & port
-            forwardPacketToDst(context, entry);
+            forwardPacketToDst(context, egressList);
         }
     }
 
@@ -217,12 +195,12 @@
      * Forward the packet to it's multicast destinations.
      *
      * @param context The packet context
-     * @param entry The multicast route entry matching this packet
+     * @param egressList The list of egress ports which the multicast packet is intended for.
      */
-    private void forwardPacketToDst(PacketContext context, McastRoute entry) {
+    private void forwardPacketToDst(PacketContext context, ArrayList<ConnectPoint> egressList) {
 
         // Send the pack out each of the respective egress ports
-        for (ConnectPoint egress : entry.getEgressConnectPoints()) {
+        for (ConnectPoint egress : egressList) {
             TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                     .setOutput(egress.port()).build();
 
@@ -234,4 +212,19 @@
             packetService.emit(packet);
         }
     }
+
+    public static McastRoute createStaticRoute(String source, String group) {
+        checkNotNull(source, "Must provide a source");
+        checkNotNull(group, "Must provide a group");
+        IpPrefix ipSource = IpPrefix.valueOf(source);
+        IpPrefix ipGroup = IpPrefix.valueOf(group);
+        return createStaticcreateRoute(ipSource, ipGroup);
+    }
+
+    public static McastRoute createStaticcreateRoute(IpPrefix source, IpPrefix group) {
+        checkNotNull(source, "Must provide a source");
+        checkNotNull(group, "Must provide a group");
+        McastRoute.Type type = McastRoute.Type.STATIC;
+        return new McastRoute(source, group, type);
+    }
 }
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastIntentManager.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastIntentManager.java
deleted file mode 100644
index b7f1f3c..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastIntentManager.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.mfwd.impl;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onlab.packet.Ethernet;
-import org.onosproject.net.intent.Intent;
-import org.onosproject.net.intent.SinglePointToMultiPointIntent;
-import org.onosproject.net.intent.IntentService;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-
-@Component(immediate = true)
-@Service(value = org.onosproject.mfwd.impl.McastIntentManager.class)
-public class McastIntentManager {
-
-    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
-    protected IntentService intentService;
-
-    private static McastIntentManager instance;
-
-    public McastIntentManager() {
-        instance = this;
-    }
-
-    /**
-     * Active this component.
-     */
-    @Activate
-    public void activate() { }
-
-    /**
-     * Deactivate this component.
-     */
-    @Deactivate
-    public void deactivate() {
-        withdrawAllIntents();
-    }
-
-    /**
-     * Get instance of this intentManager.
-     *
-     * @return the instance of this intent manager.
-     */
-    public static McastIntentManager getInstance() {
-        if (instance == null) {
-            instance = new McastIntentManager();
-        }
-        return instance;
-    }
-
-    /**
-     * Install the PointToMultipoint forwarding intent.
-     *
-     * @param mroute multicast route entry
-     * @return the intent that has been set or null otherwise
-     */
-    public SinglePointToMultiPointIntent setIntent(McastRoute mroute) {
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
-        TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
-
-        if (mroute.getIngressPoint() == null) {
-            return null;
-        }
-
-        /*
-         * Match the group AND source addresses.  We will also check ether type to
-         * determine if we are doing ipv4 or ipv6.
-         *
-         * If we really wanted to be pendantic we could put in a
-         * condition to make sure the ethernet MAC address was also
-         * mcast.
-         */
-        selector.matchEthType(Ethernet.TYPE_IPV4)
-                .matchIPDst(mroute.getGaddr())
-                .matchIPSrc(mroute.getSaddr());
-
-
-        SinglePointToMultiPointIntent.Builder builder =  SinglePointToMultiPointIntent.builder()
-                        .appId(McastForwarding.getAppId())
-                        .selector(selector.build())
-                        .treatment(treatment)
-                        .ingressPoint(mroute.getIngressPoint().getConnectPoint());
-
-        // allowing intent to be pushed without egress points means we can drop packets.
-        if (!mroute.getEgressPoints().isEmpty()) {
-            builder.egressPoints(mroute.getEgressConnectPoints());
-        }
-
-        SinglePointToMultiPointIntent intent = builder.build();
-        intentService.submit(intent);
-        mroute.setDirty(false);
-
-        return intent;
-    }
-
-    /**
-     * Withdraw the intent represented by this route.
-     *
-     * @param mroute the mcast route whose intent we want to remove
-     */
-    public void withdrawIntent(McastRoute mroute) {
-        Intent intent = intentService.getIntent(mroute.getIntentKey());
-        intentService.withdraw(intent);
-        mroute.setDirty(false);
-    }
-
-    /**
-     * Withdraw all intents.
-     *
-     * This will be called from the deactivate method so we don't leave
-     * a mess behind us after we leave.
-     */
-    public void withdrawAllIntents() {
-        for (Intent intent : intentService.getIntents()) {
-            intentService.withdraw(intent);
-        }
-    }
-}
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java
deleted file mode 100644
index a67725d..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRoute.java
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.mfwd.impl;
-
-import org.onlab.packet.IpPrefix;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.intent.Key;
-import org.onosproject.net.intent.SinglePointToMultiPointIntent;
-
-import java.util.Set;
-
-/**
- * This McastRouteBase interface is implemented by the McastRouteBase class which
- * in turn acts as the base class for both the McastRouteGroup and McastRouteSource.
- */
-interface McastRoute {
-
-    /**
-     * Gets the group addresses.
-     *
-     * @return group address
-     */
-    public IpPrefix getGaddr();
-
-    /**
-     * Gets the source address.
-     *
-     * @return the source address
-     */
-    public IpPrefix getSaddr();
-
-    /**
-     * Determines if this is an IPv4 multicast route.
-     *
-     * @return true if it is an IPv4 route
-     */
-    public boolean isIp4();
-
-    /**
-     * Determines if this is an IPv6 multicast route.
-     *
-     * @return true if it is an IPv6 route
-     */
-    public boolean isIp6();
-
-    /**
-     * Get the dirty state.
-     *
-     * @return whether this route is dirty or not.
-     */
-    public boolean getDirty();
-
-    /**
-     * Set the dirty state to indicate that something changed.
-     * This may require an update to the flow tables (intents).
-     *
-     * @param dirty set the dirty bit
-     */
-    public void setDirty(boolean dirty);
-
-    /**
-     * Add the ingress ConnectPoint.
-     *
-     * @param cpstr string representing a ConnectPoint
-     * @return whether ingress has been added, only add if ingressPoint is null
-     */
-    public boolean addIngressPoint(String cpstr);
-
-    /**
-     * Add the ingress ConnectPoint.
-     *
-     * @param cp the ConnectPoint of incoming traffic.
-     * @return whether ingress has been added, only add if ingressPoint is null
-     */
-    public boolean addIngressPoint(ConnectPoint cp);
-
-    /**
-     * Get the ingress connect point.
-     *
-     * @return the ingress connect point
-     */
-    public McastConnectPoint getIngressPoint();
-
-    /**
-     * Add an egress connect point.
-     *
-     * @param cp the egress McastConnectPoint to be added
-     * @return return the McastConnectPoint
-     */
-    public McastConnectPoint addEgressPoint(ConnectPoint cp);
-
-    /**
-     * Add an egress connect point.
-     *
-     * @param connectPoint deviceId/portNum
-     * @return return the McastConnectPoint
-     */
-    public McastConnectPoint addEgressPoint(String connectPoint);
-
-    /**
-     * Add an egress connect point.
-     *
-     * @param cp the egress McastConnectPoint to be added
-     * @param interest the protocol that has shown interest in this route
-     * @return return the McastConnectPoint
-     */
-    public McastConnectPoint addEgressPoint(ConnectPoint cp, McastConnectPoint.JoinSource interest);
-
-    /**
-     * Add an egress connect point.
-     *
-     * @param connectPoint deviceId/portNum
-     * @param interest the protocol that has shown interest in this route
-     * @return return the McastConnectPoint
-     */
-    public McastConnectPoint addEgressPoint(String connectPoint, McastConnectPoint.JoinSource interest);
-
-    /**
-     * Get the egress connect points.
-     *
-     * @return a set of egress connect points
-     */
-    public Set<McastConnectPoint> getEgressPoints();
-
-    /**
-     * Get the egress connect points.
-     *
-     * @return a set of egress connect points
-     */
-    public Set<ConnectPoint> getEgressConnectPoints();
-
-    /**
-     * Find the egress connect point if it exists.
-     *
-     * @param cp ConnectPoint to search for
-     * @return the connect point when found, null otherwise.
-     */
-    public McastConnectPoint findEgressConnectPoint(ConnectPoint cp);
-
-    /**
-     * remove Interest from a McastConnectPoint.
-     *
-     * @param mcp connect point.
-     * @param interest the protocol interested in this multicast stream
-     * @return whether or not interest was removed
-     */
-    public boolean removeInterest(McastConnectPoint mcp, McastConnectPoint.JoinSource interest);
-
-    /**
-     * Increment the punt count.
-     */
-    public void incrementPuntCount();
-
-    /**
-     * Get the punt count.
-     *
-     * @return the punt count
-     */
-    public int getPuntCount();
-
-    /**
-     * Have the McastIntentManager create an intent, attempt to
-     * install the intent and then save the key.
-     */
-    public void setIntent();
-
-    /**
-     * Set the Intent key.
-     *
-     * @param intent intent
-     */
-    public void setIntent(SinglePointToMultiPointIntent intent);
-
-    /**
-     * Withdraw the intent if it has been installed.
-     */
-    public void withdrawIntent();
-
-    /**
-     * Get the intent key.
-     *
-     * @return the intentKey
-     */
-    public Key getIntentKey();
-
-    /**
-     * Pretty print the the route.
-     *
-     * @return a pretty string
-     */
-    public String toString();
-}
\ No newline at end of file
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java
deleted file mode 100644
index 4da1f33..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteBase.java
+++ /dev/null
@@ -1,457 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.mfwd.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import org.onlab.packet.IpPrefix;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.intent.SinglePointToMultiPointIntent;
-import org.onosproject.net.intent.Key;
-
-import java.util.Set;
-import java.util.HashSet;
-
-/**
- * McastRouteBase base class for McastRouteGroup and McastRouteSource.
- */
-public class McastRouteBase implements McastRoute {
-    protected final IpPrefix gaddr;
-    protected final IpPrefix saddr;
-
-    protected McastConnectPoint ingressPoint;
-    protected Set<McastConnectPoint> egressPoints;
-
-    protected boolean isGroup = false;
-
-    protected boolean dirty = false;
-
-    /**
-     * How may times has this packet been punted.
-     */
-    private int puntCount = 0;
-
-    /**
-     * If the intentKey is null that means no intent has
-     * been installed.
-     */
-    protected Key intentKey = null;
-
-    /**
-     * Create a multicast route. This is the parent class for both the Group
-     * and the source.
-     *
-     * @param saddr source address
-     * @param gaddr multicast group address
-     */
-    public McastRouteBase(String saddr, String gaddr) {
-        this.gaddr = IpPrefix.valueOf(checkNotNull(gaddr));
-        if (saddr == null || saddr.equals("*")) {
-            this.saddr = IpPrefix.valueOf(0, 0);
-        } else {
-            this.saddr = IpPrefix.valueOf(checkNotNull(gaddr));
-        }
-        this.init();
-    }
-
-    /**
-     * Create a multicast group table entry.
-     * @param gaddr multicast group address
-     */
-    public McastRouteBase(String gaddr) {
-        this("*", gaddr);
-    }
-
-    /**
-     * Set the source and group address value of a (*, G) group.
-     *
-     * @param gpfx the group prefix address
-     */
-    public McastRouteBase(IpPrefix gpfx) {
-        this(IpPrefix.valueOf(0, 0), gpfx);
-    }
-
-    /**
-     * Create a multicast route constructor.
-     *
-     * @param saddr source address
-     * @param gaddr group address
-     */
-    public McastRouteBase(IpPrefix saddr, IpPrefix gaddr) {
-        this.saddr = checkNotNull(saddr);
-        this.gaddr = checkNotNull(gaddr);
-
-        this.init();
-    }
-
-    private void init() {
-        this.isGroup = (this.saddr.prefixLength() == 0);
-        this.ingressPoint = null;
-        this.egressPoints = new HashSet();
-    }
-
-    /**
-     * Get the multicast group address.
-     *
-     * @return the multicast group address
-     */
-    @Override
-    public IpPrefix getGaddr() {
-        return gaddr;
-    }
-
-    /**
-     * Get the multicast source address.
-     *
-     * @return the multicast source address
-     */
-    @Override
-    public IpPrefix getSaddr() {
-        return saddr;
-    }
-
-    /**
-     * Is this an IPv4 multicast route.
-     *
-     * @return true if it is an IPv4 route
-     */
-    @Override
-    public boolean isIp4() {
-        return gaddr.isIp4();
-    }
-
-    /**
-     * Is this an IPv6 multicast route.
-     *
-     * @return true if it is an IPv6 route
-     */
-    @Override
-    public boolean isIp6() {
-        return gaddr.isIp6();
-    }
-
-    /**
-     * Is this a multicast group route?
-     *
-     * @return true if it is a multicast group route.
-     */
-    public boolean isGroup() {
-        return isGroup;
-    }
-
-    /**
-     * @return true if this is (S, G) false if it (*, G).
-     */
-    public boolean isSource() {
-        return (!isGroup);
-    }
-
-    /**
-     * Get the dirty state.
-     *
-     * @return whether this route is dirty or not.
-     */
-    public boolean getDirty() {
-        return this.dirty;
-    }
-
-    /**
-     * Set the dirty state to indicate that something changed.
-     * This may require an update to the flow tables (intents).
-     *
-     * @param dirty set the dirty bit
-     */
-    public void setDirty(boolean dirty) {
-        this.dirty = dirty;
-    }
-
-    /**
-     * Add an ingress point to this route.
-     *
-     * @param ingress incoming connect point
-     * @return whether ingress has been added, only add if ingressPoint is null
-     */
-    public boolean addIngressPoint(ConnectPoint ingress) {
-
-        // Do NOT add the ingressPoint if it is not null.
-        if (this.ingressPoint != null) {
-            // TODO: Log an warning.
-            return false;
-        }
-        this.ingressPoint = new McastConnectPoint(checkNotNull(ingress));
-        setDirty(true);
-        return true;
-    }
-
-    /**
-     * Add or modify the ingress connect point.
-     *
-     * @param connectPoint string switch device Id
-     * @return whether ingress has been added, only add if ingressPoint is null
-     */
-    public boolean addIngressPoint(String connectPoint) {
-
-        if (this.ingressPoint != null) {
-            // TODO: log a warning.
-            return false;
-        }
-        ConnectPoint cp = ConnectPoint.deviceConnectPoint(checkNotNull(connectPoint));
-        return this.addIngressPoint(cp);
-    }
-
-    /**
-     * Get the ingress McastConnectPoint.
-     *
-     * @return the ingress McastConnectPoint
-     */
-    public McastConnectPoint getIngressPoint() {
-        return this.ingressPoint;
-    }
-
-    /**
-     * Add an egress McastConnectPoint.
-     *
-     * @param cp egress connect point
-     * @return return the McastConnectPoint
-     */
-    public McastConnectPoint addEgressPoint(ConnectPoint cp) {
-        McastConnectPoint mcp = this.findEgressConnectPoint(cp);
-        if (mcp == null) {
-            mcp = new McastConnectPoint(checkNotNull(cp));
-            egressPoints.add(mcp);
-            setDirty(true);
-        }
-        return mcp;
-    }
-
-    /**
-     * Add an egress connect point from a string.
-     *
-     * @param connectPoint string representing a connect point
-     * @return the MulticastConnectPoint
-     */
-    public McastConnectPoint addEgressPoint(String connectPoint) {
-        checkNotNull(connectPoint);
-        return this.addEgressPoint(ConnectPoint.deviceConnectPoint(connectPoint));
-    }
-
-    /**
-     * Add an egress McastConnectPoint.
-     *
-     * @param cp the egress connect point
-     * @param interest the source of interest for mcast traffic
-     */
-    public McastConnectPoint addEgressPoint(ConnectPoint cp, McastConnectPoint.JoinSource interest) {
-        checkNotNull(cp);
-        checkNotNull(interest);
-        McastConnectPoint mcp = this.addEgressPoint(cp);
-        if (mcp != null) {
-            mcp.interest.add(interest);
-            setDirty(true);
-        }
-        return mcp;
-    }
-
-    /**
-     * Remove an egress from McastConnectPoint.
-     *
-     * @param connectPoint the egress connect point
-     * @return boolean result of removal
-     */
-    public boolean removeEgressPoint(String connectPoint) {
-        checkNotNull(connectPoint);
-        return this.removeEgressPoint(ConnectPoint.deviceConnectPoint(connectPoint));
-    }
-
-    /**
-     * Remove an egress from McastConnectPoint.
-     *
-     * @param cp the egress connect point
-     * @return boolean result of removal
-     */
-    public boolean removeEgressPoint(ConnectPoint cp) {
-        boolean removed = false;
-        McastConnectPoint mcp = this.findEgressConnectPoint(checkNotNull(cp));
-        if (mcp != null) {
-            removed = egressPoints.remove(mcp);
-            setDirty(true);
-        }
-        return removed;
-    }
-
-    /**
-     * Add an egress McastConnectPoint.
-     *
-     * @param cpstr deviceId/port of the connect point
-     */
-    public McastConnectPoint addEgressPoint(String cpstr, McastConnectPoint.JoinSource interest) {
-        checkNotNull(cpstr);
-        checkNotNull(interest);
-        return this.addEgressPoint(ConnectPoint.deviceConnectPoint(cpstr), interest);
-    }
-
-    /**
-     * Get egress connect points for the route.
-     *
-     * @return Set of egress connect points
-     */
-    public Set<McastConnectPoint> getEgressPoints() {
-        return egressPoints;
-    }
-
-    /**
-     * Get egress McastConnectPoints points as ConnectPoints for intent system.
-     *
-     * @return Set of egress ConnectPoints
-     */
-    public Set<ConnectPoint> getEgressConnectPoints() {
-        Set<ConnectPoint> cps = new HashSet<ConnectPoint>();
-
-        for (McastConnectPoint mcp : egressPoints) {
-            cps.add(mcp.getConnectPoint());
-        }
-        return cps;
-    }
-
-    /**
-     * Find the Multicast Connect Point that contains the ConnectPoint.
-     *
-     * @param cp the regular ConnectPoint to match
-     * @return the McastConnectPoint that contains cp or null if not found.
-     */
-    public McastConnectPoint findEgressConnectPoint(ConnectPoint cp) {
-        for (McastConnectPoint mcp : this.egressPoints) {
-            if (mcp.getConnectPoint().equals(cp)) {
-                return mcp;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Remove specified interest from the given ConnectPoint.
-     *
-     * @param mcp connect point.
-     * @param interest the protocol interested in this multicast stream
-     * @return true if removed, false otherwise
-     */
-    public boolean removeInterest(McastConnectPoint mcp, McastConnectPoint.JoinSource interest) {
-        checkNotNull(mcp);
-        if (mcp.interest.contains(interest)) {
-            mcp.interest.remove(interest);
-            setDirty(true);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Get the number of times the packet has been punted.
-     *
-     * @return the punt count
-     */
-    @Override
-    public int getPuntCount() {
-        return puntCount;
-    }
-
-    /**
-     * Increment the punt count.
-     *
-     * TODO: we need to handle wrapping.
-     */
-    @Override
-    public void incrementPuntCount() {
-        puntCount++;
-    }
-
-    /**
-     * Have the McastIntentManager create and set the intent, then save the intent key.
-     *
-     * If we already have an intent, we will first withdraw the existing intent and
-     * replace it with a new one.  This will support the case where the ingress connectPoint
-     * or group of egress connectPoints change.
-     */
-    @Override
-    public void setIntent() {
-        if (this.intentKey != null) {
-            this.withdrawIntent();
-        }
-        McastIntentManager im = McastIntentManager.getInstance();
-        SinglePointToMultiPointIntent intent = im.setIntent(this);
-        this.intentKey = intent.key();
-    }
-
-    /**
-     * Set the Intent key.
-     *
-     * @param intent the multicast intent
-     */
-    @Override
-    public void setIntent(SinglePointToMultiPointIntent intent) {
-        intentKey = intent.key();
-    }
-
-    /**
-     * Get the intent key represented by this route.
-     *
-     * @return intentKey
-     */
-    @Override
-    public Key getIntentKey() {
-        return this.intentKey;
-    }
-
-
-    /**
-     * Withdraw the intent and set the key to null.
-     */
-    @Override
-    public void withdrawIntent() {
-        if (intentKey == null) {
-            // nothing to withdraw
-            return;
-        }
-        McastIntentManager im = McastIntentManager.getInstance();
-        im.withdrawIntent(this);
-        this.intentKey = null;
-    }
-
-    /**
-     * Pretty Print this Multicast Route.  Works for McastRouteSource and McastRouteGroup.
-     *
-     * @return pretty string of the multicast route
-     */
-    @Override
-    public String toString() {
-        String out = String.format("(%s, %s)\n\t",
-                saddr.toString(), gaddr.toString());
-
-        out += "intent: ";
-        out += (intentKey == null) ? "not installed" : this.intentKey.toString();
-        out += "\n\tingress: ";
-        out += (ingressPoint == null) ? "NULL" : ingressPoint.getConnectPoint().toString();
-        out += "\n\tegress: {\n";
-        if (egressPoints != null && !egressPoints.isEmpty()) {
-            for (McastConnectPoint eg : egressPoints) {
-                out += "\t\t" + eg.getConnectPoint().toString() + "\n";
-            }
-        }
-        out += ("\t}\n");
-        out += ("\tpunted: " + this.getPuntCount() + "\n");
-        return out;
-    }
-}
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteGroup.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteGroup.java
deleted file mode 100644
index 4a58e1b..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteGroup.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.mfwd.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import java.util.HashMap;
-import org.onlab.packet.IpPrefix;
-
-/**
- * The McastRouteGroup extends the McastRouteBase class and serves two purposes:
- * first it represents a (*, G) multicast route entry.  Second it serves
- * as a container for all (S, G) multicast route entries that belong
- * to the same group address.
- */
-public class McastRouteGroup extends McastRouteBase {
-    private HashMap<IpPrefix, McastRouteSource> sources;
-
-    /**
-     * Class constructor.
-     *
-     * @param gaddr - String representation of group address.
-     */
-    public McastRouteGroup(String gaddr) {
-        super(checkNotNull(gaddr));
-        this.init();
-    }
-
-    /**
-     * Create a multicast group.
-     *
-     * @param gpfx - Group address
-     */
-    public McastRouteGroup(IpPrefix gpfx) {
-        super(checkNotNull(gpfx));
-        this.init();
-    }
-
-    /**
-     * Common initialization used by constructors.
-     */
-    private void init() {
-        this.sources = new HashMap();
-        super.isGroup = true;
-    }
-
-    /**
-     * Find a specific multicast source address for this group.
-     *
-     * @param saddr the source address
-     * @return the multicast source route or null if it does not exist
-     */
-    public McastRouteSource findSource(IpPrefix saddr) {
-        return this.sources.get(checkNotNull(saddr));
-    }
-
-    /**
-     * Return the entire set of multicast sources for this group.
-     *
-     * @return the set of multicast sources
-     */
-    public HashMap<IpPrefix, McastRouteSource> getSources() {
-        return this.sources;
-    }
-
-    /**
-     * Add a new McastRouteSource to this group.
-     *
-     * @param src the multicast source
-     */
-    public void addSource(McastRouteSource src) {
-        checkNotNull(src);
-        this.sources.put(src.getSaddr(), src);
-    }
-
-    /**
-     * Remove the source with this specific IpPrefix from this group entry.
-     *
-     * @param spfx IP Prefix of the source to be removed
-     * @return the source route that was just removed
-     */
-    public McastRouteSource removeSource(IpPrefix spfx) {
-        McastRouteSource src = this.sources.remove(spfx);
-        src.withdrawIntent();
-        return src;
-    }
-
-    /**
-     * Remove all sources from this.
-     */
-    public void removeSources() {
-        for (McastRouteSource src : this.sources.values()) {
-            src.withdrawIntent();
-            this.sources.remove(src.getSaddr());
-        }
-    }
-
-}
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteSource.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteSource.java
deleted file mode 100644
index 68edc2e..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteSource.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.mfwd.impl;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import org.onlab.packet.IpPrefix;
-
-/**
- * This class represents and specific multicast senders source address.  Objects from
- * this class will belong to the sources collection of the multicast group.
- */
-public class McastRouteSource extends McastRouteBase {
-
-    // A reference to our parent group
-    private McastRouteGroup group;
-
-    /**
-     * Create a multicast source with IpPrefixes.
-     *
-     * @param source the source address
-     * @param group the group address
-     */
-    public McastRouteSource(IpPrefix source, IpPrefix group) {
-        super(checkNotNull(source), checkNotNull(group));
-    }
-
-    /**
-     * Set our parent multicast group.
-     *
-     * @param group the group this source belongs to
-     */
-    public void setGroup(McastRouteGroup group) {
-        this.group = group;
-    }
-}
\ No newline at end of file
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteTable.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteTable.java
deleted file mode 100644
index 1140c3a..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/impl/McastRouteTable.java
+++ /dev/null
@@ -1,363 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.mfwd.impl;
-
-import org.apache.felix.scr.annotations.Service;
-import org.onlab.packet.IpPrefix;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * The Mcast Route Table holds all multicast state for the controller.
- *
- * State for IPv4 and IPv6 are maintained.  The tables are sets of McastRouteGroup
- * structures that represent (*, G) state with a series of egress ConnectPoints.
- * Each (*, G) may also have a set of (S, G) that may have there own set of
- * ingress and egress ConnectPoints.
- *
- * TODO: perhaps should probably create two separate singleton for IPv4 and IPv6 respectively.
- */
-@Service(value = org.onosproject.mfwd.impl.McastRouteTable.class)
-public final class McastRouteTable {
-
-    /*
-     * Create a map of the McastGroups indexed by the multicast group prefix.
-     * We may choose to change the map data structure in to some form a radix trie
-     * depending on the type of real world usage we see.
-     */
-    private final Map<IpPrefix, McastRouteGroup> mrib4;
-    private final Map<IpPrefix, McastRouteGroup> mrib6;
-    private static McastRouteTable instance = null;
-
-    private Boolean ipv6Enabled = false;
-
-    /**
-     * Create the two v4 & v6 tables.
-     */
-    private McastRouteTable() {
-        mrib4 = new ConcurrentHashMap<IpPrefix, McastRouteGroup>();
-        if (ipv6Enabled) {
-            mrib6 = new ConcurrentHashMap<IpPrefix, McastRouteGroup>();
-        } else {
-            mrib6 = null;
-        }
-    }
-
-    /**
-     * Get the single instance of this multicast group address.
-     *
-     * @return the multicast route table
-     */
-    public static McastRouteTable getInstance() {
-        if (instance == null) {
-            instance = new McastRouteTable();
-        }
-        return instance;
-    }
-
-    /**
-     * Get the IPv4 MRIB.
-     *
-     * @return the IPv4 MRIB
-     */
-    public Map<IpPrefix, McastRouteGroup> getMrib4() {
-        return mrib4;
-    }
-
-    /**
-     * Get the IPv6 MRIB.
-     *
-     * @return Return the set of prefix keyed McastGroups
-     */
-    public Map<IpPrefix, McastRouteGroup> getMrib6() {
-        return mrib6;
-    }
-
-    /**
-     * Save the McastRouteGroup in the address family appropriate mrib.
-     *
-     * @param group The McastRouteGroup to save
-     */
-    private void storeGroup(McastRouteGroup group) {
-        if (group.isIp4()) {
-            mrib4.put(group.getGaddr(), group);
-        } else if (group.isIp6() && ipv6Enabled) {
-            mrib6.put(group.getGaddr(), group);
-        }
-    }
-
-    /**
-     * Remove the group.
-     *
-     * @param group the group to be removed
-     */
-    private void removeGroup(McastRouteGroup group) {
-        IpPrefix gpfx = group.getGaddr();
-        if (gpfx.isIp4()) {
-            mrib4.remove(gpfx);
-        } else if (gpfx.isIp6() && ipv6Enabled) {
-            mrib6.remove(gpfx);
-        }
-    }
-
-    /**
-     * Add a multicast route to the MRIB.  This function will.
-     *
-     * @param saddr source address * or x.x.x.x or x.x.x.x/y
-     * @param gaddr group address x.x.x.x or x.x.x.x/y
-     * @return the multicast route
-     */
-    public McastRouteBase addRoute(String saddr, String gaddr) {
-        IpPrefix gpfx = IpPrefix.valueOf(gaddr);
-        IpPrefix spfx = IpPrefix.valueOf(0, 0);
-        if (saddr != null && !saddr.equals("*")) {
-            spfx = IpPrefix.valueOf(saddr);
-        }
-        return addRoute(spfx, gpfx);
-    }
-
-    /**
-     * Add a multicast route to the MRIB.  This function will store either
-     * (S, G) or (*, G) in the mrib if an entry does not already exist. If
-     * an entry does exist it is returned to the caller.
-     *
-     * Every (S, G) is stored as part of it's parent group entry which also represents
-     * (*, G) routes.  In the case of a (S, G) we will also create the (*, G) entry if needed
-     * then save the (S, G) to the (*, G).
-     *
-     * @param spfx the source prefix
-     * @param gpfx the group prefix
-     * @return the resulting McastRouteSource or McastRouteGroup accordingly.
-     */
-    public McastRouteBase addRoute(IpPrefix spfx, IpPrefix gpfx) {
-
-        /**
-         * If a group route (*, g) does not exist we will need to make so we
-         * can start attaching our sources to the group entry.
-         */
-        McastRouteGroup group = findMcastGroup(gpfx);
-        if (group == null) {
-            group = new McastRouteGroup(gpfx);
-
-            // Save it for later
-            if (gpfx.isIp4()) {
-                this.mrib4.put(gpfx, group);
-            } else if (gpfx.isIp6() && ipv6Enabled) {
-                this.mrib6.put(gpfx, group);
-            }
-        }
-
-        /**
-         * If the source prefix length is 0 then we have our (*, g) entry, we can
-         * just return now.
-         */
-        if (spfx.prefixLength() == 0) {
-            return group;
-        }
-
-        // See if the source already exists.  If so just return it.
-        McastRouteSource source = group.findSource(spfx);
-        if (source != null) {
-            return source;
-        }
-
-        /**
-         * We have the group but no source.  We need to create the source then add it
-         * to the group.
-         */
-        source = new McastRouteSource(spfx, gpfx);
-
-        // Have the source save it's parent
-        source.setGroup(group);
-
-        // Save this source as part of this group
-        group.addSource(source);
-
-        return source;
-    }
-
-    /**
-     * Delete a specific egress from the MRIB.
-     *
-     * @param saddr source address * or x.x.x.x or x.x.x.x/y
-     * @param gaddr group address x.x.x.x or x.x.x.x/y
-     * @param egress group address x.x.x.x or x.x.x.x/y
-     * @return boolean if egress was deleted
-     */
-    public boolean removeEgress(String saddr, String gaddr, String egress) {
-
-        IpPrefix gpfx = IpPrefix.valueOf(gaddr);
-        IpPrefix spfx = IpPrefix.valueOf(0, 0);
-        if (saddr != null && !saddr.equals("*")) {
-            spfx = IpPrefix.valueOf(saddr);
-        }
-
-        McastRouteSource src = (McastRouteSource) findBestMatch(spfx, gpfx);
-        boolean removed = src.removeEgressPoint(egress);
-        if (removed) {
-            src.setIntent();
-        }
-        return removed;
-    }
-
-    /**
-     * Delete a multicast route from the MRIB.
-     *
-     * @param saddr source address * or x.x.x.x or x.x.x.x/y
-     * @param gaddr group address x.x.x.x or x.x.x.x/y
-     */
-    public void removeRoute(String saddr, String gaddr) {
-        IpPrefix gpfx = IpPrefix.valueOf(gaddr);
-        IpPrefix spfx = IpPrefix.valueOf(0, 0);
-        if (saddr != null && !saddr.equals("*")) {
-            spfx = IpPrefix.valueOf(saddr);
-        }
-        removeRoute(spfx, gpfx);
-    }
-
-    /**
-     * Remove a multicast route.
-     *
-     * @param spfx the source prefix
-     * @param gpfx the group prefix
-     */
-    public void removeRoute(IpPrefix spfx, IpPrefix gpfx) {
-
-        /**
-         * If a group route (*, g) does not exist we will need to make so we
-         * can start attaching our sources to the group entry.
-         */
-        McastRouteGroup group = findMcastGroup(gpfx);
-        if (group == null) {
-            // The group does not exist, we can't remove it.
-            return;
-        }
-
-        /**
-         * If the source prefix length is 0 then we have a (*, g) entry, which
-         * means we will remove this group and all of it's sources. We will
-         * also withdraw it's intent if need be.
-         */
-        if (spfx.prefixLength() > 0) {
-            group.removeSource(spfx);
-
-            /*
-             * Now a little house keeping. If this group has no more sources
-             * nor egress connectPoints git rid of it.
-             */
-            if (group.getSources().size() == 0 &&
-                    group.getEgressPoints().size() == 0) {
-                removeGroup(group);
-            }
-
-        } else {
-            // Group remove has been explicitly requested.
-            group.removeSources();
-            group.withdrawIntent();
-            removeGroup(group);
-        }
-    }
-
-    /**
-     * Find the specific multicast group entry.
-     *
-     * @param group the group address
-     * @return McastRouteGroup the multicast (*, G) group route
-     */
-    public McastRouteGroup findMcastGroup(IpPrefix group) {
-        McastRouteGroup g = null;
-        if (group.isIp4()) {
-            g = mrib4.get(group);
-        } else if (group.isIp6() && ipv6Enabled) {
-            g = mrib6.get(group);
-        }
-        return g;
-    }
-
-    /**
-     * Find the multicast (S, G) entry if it exists.
-     *
-     * @param saddr the source address
-     * @param gaddr the group address
-     * @return The multicast source route entry if it exists, null if it does not.
-     */
-    public McastRouteSource findMcastSource(IpPrefix saddr, IpPrefix gaddr) {
-        McastRouteGroup grp = findMcastGroup(checkNotNull(gaddr));
-        if (grp == null) {
-            return null;
-        }
-        return grp.findSource(saddr);
-    }
-
-    /**
-     * This will first look up a Group entry. If no group entry was found null will
-     * be returned. If the group entry has been found we will then look up the (s, g) entry.
-     * If the (s, g) entry has been found, that will be returned.  If no (s, g) was found
-     * the (*, g) group entry will be returned.
-     *
-     * @param saddr the source address
-     * @param gaddr the group address
-     * @return return the best matching McastRouteSource or McastRouteGroup
-     */
-    public McastRoute findBestMatch(IpPrefix saddr, IpPrefix gaddr) {
-        McastRouteGroup grp = this.findMcastGroup(checkNotNull(gaddr));
-        if (grp == null) {
-            return null;
-        }
-
-        // Found a group now look for a source
-        McastRouteSource src = grp.findSource(checkNotNull(saddr));
-        if (src == null) {
-            return grp;
-        }
-
-        return src;
-    }
-
-    /**
-     * Print out the multicast route table in it's entirety.
-     *
-     * TODO: Eventually we will have to implement paging and how to handle large tables.
-     * @return String
-     */
-    public String printMcastRouteTable() {
-        String out = this.toString() + "\n";
-
-        for (McastRouteGroup grp : mrib4.values()) {
-            out += grp.toString() + "\n";
-            for (McastRouteSource src : grp.getSources().values()) {
-                out += src.toString() + "\n";
-            }
-        }
-        return out;
-    }
-
-    /**
-     * Print out a summary of groups in the MRIB.
-     *
-     * @return String
-     */
-    public String toString() {
-        String out = "Mcast Route Table: ";
-        out += mrib4.size() + " IPv4 Multicast Groups\n";
-        if (ipv6Enabled) {
-            out += mrib6.size() + " IPv6 Multicast Groups\n";
-        }
-        return out;
-    }
-}
diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/McastResource.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/McastResource.java
deleted file mode 100644
index 608e044..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/McastResource.java
+++ /dev/null
@@ -1,149 +0,0 @@
-/*

- * Copyright 2015 Open Networking Laboratory

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *     http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-package org.onosproject.mfwd.rest;

-

-import java.io.IOException;

-import com.fasterxml.jackson.databind.ObjectMapper;

-import com.fasterxml.jackson.databind.node.ObjectNode;

-

-import javax.ws.rs.DefaultValue;

-import javax.ws.rs.QueryParam;

-import javax.ws.rs.Consumes;

-import javax.ws.rs.GET;

-import javax.ws.rs.POST;

-import javax.ws.rs.DELETE;

-import javax.ws.rs.Path;

-import javax.ws.rs.Produces;

-import javax.ws.rs.core.MediaType;

-import javax.ws.rs.core.Response;

-

-import org.onosproject.mfwd.impl.McastConnectPoint;

-import org.onosproject.mfwd.impl.McastRouteTable;

-import org.onosproject.mfwd.impl.McastRouteBase;

-import org.onosproject.mfwd.impl.MRibCodec;

-import org.onosproject.rest.AbstractWebResource;

-

-import org.slf4j.Logger;

-import static org.slf4j.LoggerFactory.getLogger;

-

-/**

- * Rest API for Multicast Forwarding.

- */

-@Path("mcast")

-public class McastResource extends AbstractWebResource  {

-

-    private final Logger log = getLogger(getClass());

-    private static final String SOURCE_ADDRESS = "sourceAddress";

-    private static final String GROUP_ADDRESS = "groupAddress";

-    private static final String INGRESS_POINT = "ingressPoint";

-    private static final String EGRESS_POINT = "egressPoint";

-    private static final String MCAST_GROUP = "mcastGroup";

-

-    /**

-     * Retrieve the multicast route table.

-     *

-     * @return the multicast route table.

-     * @throws IOException if an error occurs

-     */

-    @Path("show")

-    @GET

-    @Produces(MediaType.APPLICATION_JSON)

-    public Response showAll() throws IOException {

-        McastRouteTable mrt = McastRouteTable.getInstance();

-        ObjectNode pushContent = new MRibCodec().encode(mrt , this);

-        return ok(pushContent.toString()).build();

-    }

-

-    /**

-     * Static join a multicast flow.

-     *

-     * @param sAddr source address to join

-     * @param gAddr group address to join

-     * @param ports ingress and egress ConnectPoints to join

-     * @return the Result of the join

-     * @throws IOException if something failed with the join command

-     */

-    @Path("/join")

-    @POST

-    @Consumes(MediaType.APPLICATION_JSON)

-    @Produces(MediaType.TEXT_PLAIN)

-    public Response join(@QueryParam("src") String sAddr,

-                    @QueryParam("grp") String gAddr,

-                    @DefaultValue("") @QueryParam("ports") String ports)

-                    throws IOException {

-

-        ObjectMapper mapper = new ObjectMapper();

-        log.debug("Source IP Address: " + sAddr);

-        log.debug("Destination IP Address: " + gAddr);

-        log.debug("Ingress and Egress ports: " + ports);

-

-        String output = "Insertion Faild";

-        if (sAddr != null && gAddr != null && ports != null) {

-

-            String[] portArr = ports.split(",");

-            log.debug("Port Array Length: " + portArr.length);

-            McastRouteTable mrt = McastRouteTable.getInstance();

-            McastRouteBase mr = mrt.addRoute(sAddr, gAddr);

-

-            // Port format "of:0000000000000023/4"

-            log.debug("checking inside outer if: " + portArr.length);

-

-            if (mr != null && portArr != null && portArr.length > 0) {

-

-                String inCP = portArr[0];

-                log.debug("Ingress port provided: " + inCP);

-                mr.addIngressPoint(inCP);

-

-                for (int i = 1; i < portArr.length; i++) {

-                    String egCP = portArr[i];

-                    log.debug("Egress port provided: " + egCP);

-                    mr.addEgressPoint(egCP, McastConnectPoint.JoinSource.STATIC);

-                }

-                mrt.printMcastRouteTable();

-                output = "Successfully Inserted";

-            }

-        } else {

-            output = "Please Insert the rest uri correctly";

-        }

-        return Response.ok(output).build();

-    }

-

-    /**

-     * Delete multicast state.

-     *

-     * @param src address to be deleted

-     * @param grp address to be deleted

-     * @return status of delete if successful

-     */

-    @Path("/delete")

-    @DELETE

-    @Consumes(MediaType.TEXT_PLAIN)

-    @Produces(MediaType.TEXT_PLAIN)

-    public Response removeMcastFlow(@QueryParam("src") String src,

-                    @QueryParam("grp") String grp) {

-

-        String resp = "Failed to delete";

-        log.info("Source IP Address to delete: " + src);

-        log.info("Destination IP Address to delete: " + grp);

-        McastRouteTable mrt = McastRouteTable.getInstance();

-        if (src != null && grp != null) {

-            mrt.removeRoute(src, grp);

-            resp = "Deleted flow for src " + src + " and grp " + grp;

-        }

-

-        return Response.ok(resp).build();

-    }

-}

diff --git a/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/package-info.java b/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/package-info.java
deleted file mode 100644
index b42586f..0000000
--- a/apps/mfwd/src/main/java/org/onosproject/mfwd/rest/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * REST API for multicase forwarding.
- */
-package org.onosproject.mfwd.rest;