diff --git a/app/src/main/java/org/opencord/igmpproxy/impl/SingleStateMachine.java b/app/src/main/java/org/opencord/igmpproxy/impl/SingleStateMachine.java
new file mode 100644
index 0000000..c4d73a8
--- /dev/null
+++ b/app/src/main/java/org/opencord/igmpproxy/impl/SingleStateMachine.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.opencord.igmpproxy.impl;
+
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.Ip4Address;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * State machine for single IGMP group member. The state machine is implemented on
+ * RFC 2236 "6. Host State Diagram".
+ */
+public class SingleStateMachine {
+    // Only for tests purposes
+    static boolean sendQuery = true;
+
+    static final int STATE_NON = 0;
+    static final int STATE_DELAY = 1;
+    static final int STATE_IDLE = 2;
+    static final int TRANSITION_JOIN = 0;
+    static final int TRANSITION_LEAVE = 1;
+    static final int TRANSITION_QUERY = 2;
+    static final int TRANSITION_TIMEOUT = 3;
+    static final int DEFAULT_MAX_RESP = 0xfffffff;
+    static final int DEFAULT_COUNT = 1;
+    private DeviceId devId;
+    private Ip4Address groupIp;
+    private Ip4Address srcIp;
+    private PortNumber upLinkPort;
+
+    private AtomicInteger count = new AtomicInteger(DEFAULT_COUNT);
+    private int timerId = IgmpTimer.INVALID_TIMER_ID;
+    private int timeOut = DEFAULT_MAX_RESP;
+    private State[] states =
+            {
+                    new NonMember(), new DelayMember(), new IdleMember()
+            };
+    private int[] nonTransition =
+            {STATE_DELAY, STATE_NON, STATE_NON, STATE_NON};
+    private int[] delayTransition =
+            {STATE_DELAY, STATE_NON, STATE_DELAY, STATE_IDLE};
+    private int[] idleTransition =
+            {STATE_IDLE, STATE_NON, STATE_DELAY, STATE_IDLE};
+    //THE TRANSITION TABLE
+    private int[][] transition =
+            {nonTransition, delayTransition, idleTransition};
+    private int currentState = STATE_NON;
+
+    public SingleStateMachine(DeviceId devId, Ip4Address groupIp, Ip4Address src, PortNumber upLinkPort) {
+        this.devId = devId;
+        this.groupIp = groupIp;
+        this.srcIp = src;
+        this.upLinkPort = upLinkPort;
+    }
+
+    public Ip4Address getGroupIp() {
+        return groupIp;
+    }
+
+    public DeviceId getDeviceId() {
+        return devId;
+    }
+    public boolean increaseCounter() {
+        count.incrementAndGet();
+        return true;
+    }
+
+    public boolean decreaseCounter() {
+        if (count.get() > 0) {
+            count.decrementAndGet();
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public int getCounter() {
+        return count.get();
+    }
+    public int currentState() {
+        return currentState;
+    }
+
+    private void next(int msg) {
+        currentState = transition[currentState][msg];
+    }
+
+    public void join(boolean messageOutAllowed) {
+        states[currentState].join(messageOutAllowed);
+        next(TRANSITION_JOIN);
+    }
+
+    public void leave(boolean messageOutAllowed) {
+        states[currentState].leave(messageOutAllowed);
+        next(TRANSITION_LEAVE);
+    }
+
+    public void query(int maxResp) {
+        states[currentState].query(maxResp);
+        next(TRANSITION_QUERY);
+    }
+
+    public void timeOut() {
+        states[currentState].timeOut();
+        next(TRANSITION_TIMEOUT);
+    }
+
+    int getTimeOut(int maxTimeOut) {
+        Random random = new Random();
+        return Math.abs(random.nextInt()) % maxTimeOut;
+    }
+
+    protected void cancelTimer() {
+        if (IgmpTimer.INVALID_TIMER_ID != timerId) {
+            IgmpTimer.cancel(timerId);
+        }
+    }
+
+    class State {
+        public void join(boolean messageOutAllowed) {
+        }
+
+        public void leave(boolean messageOutAllowed) {
+            if (messageOutAllowed) {
+                Ethernet eth = IgmpSender.getInstance().buildIgmpV3Leave(groupIp, srcIp);
+                IgmpSender.getInstance().sendIgmpPacketUplink(eth, devId, upLinkPort);
+            }
+        }
+
+        public void query(int maxResp) {
+        }
+
+        public void timeOut() {
+        }
+
+    }
+
+    class NonMember extends State {
+        public void join(boolean messageOutAllowed) {
+            if (messageOutAllowed) {
+                Ethernet eth = IgmpSender.getInstance().buildIgmpV3Join(groupIp, srcIp);
+                IgmpSender.getInstance().sendIgmpPacketUplink(eth, devId, upLinkPort);
+                timeOut = getTimeOut(IgmpManager.getUnsolicitedTimeout());
+                timerId = IgmpTimer.start(SingleStateMachine.this, timeOut);
+            }
+        }
+    }
+
+    class DelayMember extends State {
+        public void query(int maxResp) {
+            if (maxResp < timeOut) {
+                timeOut = getTimeOut(maxResp);
+                timerId = IgmpTimer.reset(timerId, SingleStateMachine.this, timeOut);
+            }
+        }
+
+        public void timeOut() {
+            if (sendQuery) {
+                Ethernet eth = IgmpSender.getInstance().buildIgmpV3ResponseQuery(groupIp, srcIp);
+                IgmpSender.getInstance().sendIgmpPacketUplink(eth, devId, upLinkPort);
+                timeOut = DEFAULT_MAX_RESP;
+            }
+        }
+
+    }
+
+    class IdleMember extends State {
+        public void query(int maxResp) {
+            timeOut = getTimeOut(maxResp);
+            timerId = IgmpTimer.start(SingleStateMachine.this, timeOut);
+        }
+    }
+}
