diff --git a/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py b/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py
new file mode 100644
index 0000000..7f0ca7c
--- /dev/null
+++ b/TestON/tests/CHOTestMonkey/dependencies/events/AppEvent.py
@@ -0,0 +1,246 @@
+"""
+This file contains classes for CHOTestMonkey that are related to application event
+Author: you@onlab.us
+"""
+from tests.CHOTestMonkey.dependencies.events.Event import EventType, EventStates, Event
+from tests.CHOTestMonkey.dependencies.elements.ONOSElement import HostIntent, PointIntent
+
+class IntentEvent( Event ):
+    def __init__( self ):
+        Event.__init__( self )
+        # The index of the ONOS CLI that is going to run the command
+        self.CLIIndex = 0
+
+class HostIntentEvent( IntentEvent ):
+    def __init__( self ):
+        IntentEvent.__init__( self )
+        self.hostA = None
+        self.hostB = None
+
+    def startHostIntentEvent( self ):
+        return EventStates().PASS
+
+    def startEvent( self, args ):
+        with self.eventLock:
+            main.log.info( "%s - starting event" % ( self.typeString ) )
+            if self.typeIndex == EventType().APP_INTENT_HOST_ADD or self.typeIndex == EventType().APP_INTENT_HOST_DEL:
+                if len( args ) < 3:
+                    main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
+                    return EventStates().ABORT
+                elif len( args ) > 3:
+                    main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
+                    return EventStates().ABORT
+                else:
+                    if args[ 0 ] == args[ 1 ]:
+                        main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
+                        return EventStates().ABORT
+                    for host in main.hosts:
+                        if host.name == args[ 0 ]:
+                            self.hostA = host
+                        elif host.name == args[ 1 ]:
+                            self.hostB = host
+                        if self.hostA != None and self.hostB != None:
+                            break
+                    if self.hostA == None:
+                        main.log.warn( "Host %s does not exist: " % ( args[ 0 ] ) )
+                        return EventStates().ABORT
+                    if self.hostB == None:
+                        main.log.warn( "Host %s does not exist: " % ( args[ 1 ] ) )
+                        return EventStates().ABORT
+                    index = int( args[ 2 ] )
+                    if index < 1 or index > int( main.numCtrls ):
+                        main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
+                        return EventStates().ABORT
+                    if not main.controllers[ index - 1 ].isUp():
+                        main.log.warn( self.typeString + " - invalid argument: onos %s is down" % ( controller.index ) )
+                        return EventStates().ABORT
+                    self.CLIIndex = index
+                    return self.startHostIntentEvent()
+
+class AddHostIntent( HostIntentEvent ):
+    """
+    Add a host-to-host intent (bidirectional)
+    """
+    def __init__( self ):
+        HostIntentEvent.__init__( self )
+        self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+        self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+    def startHostIntentEvent( self ):
+        assert self.hostA != None and self.hostB != None
+        # Check whether there already exists some intent for the host pair
+        # For now we should avoid installing overlapping intents
+        for intent in main.intents:
+            if not intent.type == 'INTENT_HOST':
+                continue
+            if intent.hostA == self.hostA and intent.hostB == self.hostB or\
+            intent.hostB == self.hostA and intent.hostA == self.hostB:
+                main.log.warn( self.typeString + " - find an exiting intent for the host pair, abort installation" )
+                return EventStates().ABORT
+        controller = main.controllers[ self.CLIIndex - 1 ]
+        with controller.CLILock:
+            id = controller.CLI.addHostIntent( self.hostA.id, self.hostB.id )
+        if id == None:
+            main.log.warn( self.typeString + " - add host intent failed" )
+            return EventStates().FAIL
+        with main.variableLock:
+            newHostIntent = HostIntent( id, self.hostA, self.hostB )
+            main.intents.append( newHostIntent )
+            # Update host connectivity status
+            # TODO: should we check whether hostA and hostB are already correspondents?
+            self.hostB.correspondents.append( self.hostA )
+            self.hostA.correspondents.append( self.hostB )
+        return EventStates().PASS
+
+class DelHostIntent( HostIntentEvent ):
+    """
+    Delete a host-to-host intent (bidirectional)
+    """
+    def __init__( self ):
+        HostIntentEvent.__init__( self )
+        self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+        self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+    def startHostIntentEvent( self ):
+        assert self.hostA != None and self.hostB != None
+        targetIntent = None
+        for intent in main.intents:
+            if not intent.type == 'INTENT_HOST':
+                continue
+            if intent.hostA == self.hostA and intent.hostB == self.hostB or\
+            intent.hostB == self.hostA and intent.hostA == self.hostB:
+                targetIntent = intent
+                break
+        if targetIntent == None:
+            main.log.warn( self.typeString + " - intent does not exist" )
+            return EventStates().FAIL
+        controller = main.controllers[ self.CLIIndex - 1 ]
+        with controller.CLILock:
+            result = controller.CLI.removeIntent( targetIntent.id, purge=True )
+        if result == None or result == main.FALSE:
+            main.log.warn( self.typeString + " - delete host intent failed" )
+            return EventStates().FAIL
+        with main.variableLock:
+            main.intents.remove( targetIntent )
+            # Update host connectivity status
+            self.hostB.correspondents.remove( self.hostA )
+            self.hostA.correspondents.remove( self.hostB )
+        return EventStates().PASS
+
+class PointIntentEvent( IntentEvent ):
+    def __init__( self ):
+        IntentEvent.__init__( self )
+        self.deviceA = None
+        self.deviceB = None
+
+    def startPointIntentEvent( self ):
+        return EventStates().PASS
+
+    def startEvent( self, args ):
+        with self.eventLock:
+            main.log.info( "%s - starting event" % ( self.typeString ) )
+            if self.typeIndex == EventType().APP_INTENT_POINT_ADD or self.typeIndex == EventType().APP_INTENT_POINT_DEL:
+                if len( args ) < 3:
+                    main.log.warn( "%s - Not enough arguments: %s" % ( self.typeString, args ) )
+                    return EventStates().ABORT
+                elif len( args ) > 3:
+                    main.log.warn( "%s - Too many arguments: %s" % ( self.typeString, args ) )
+                    return EventStates().ABORT
+                else:
+                    for device in main.devices:
+                        if device.name == args[ 0 ]:
+                            self.deviceA = device
+                        elif device.name == args[ 1 ]:
+                            self.deviceB = device
+                        if self.deviceA != None and self.deviceB != None:
+                            break
+                    if self.deviceA == None:
+                        main.log.warn( "Device %s does not exist: " % ( args[ 0 ] ) )
+                        return EventStates().ABORT
+                    if self.deviceB == None:
+                        main.log.warn( "Device %s does not exist: " % ( args[ 1 ] ) )
+                        return EventStates().ABORT
+                    index = int( args[ 2 ] )
+                    if index < 1 or index > int( main.numCtrls ):
+                        main.log.warn( "%s - invalid argument: %s" % ( self.typeString, index ) )
+                        return EventStates().ABORT
+                    if not main.controllers[ index - 1 ].isUp():
+                        main.log.warn( self.typeString + " - invalid argument: onos %s is down" % ( controller.index ) )
+                        return EventStates().ABORT
+                    self.CLIIndex = index
+                    return self.startPointIntentEvent()
+
+class AddPointIntent( PointIntentEvent ):
+    """
+    Add a point-to-point intent
+    """
+    def __init__( self ):
+        PointIntentEvent.__init__( self )
+        self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+        self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+    def startPointIntentEvent( self ):
+        assert self.deviceA != None and self.deviceB != None
+        controller = main.controllers[ self.CLIIndex - 1 ]
+        # TODO: the following check only work when we use default port number for point intents
+        # Check whether there already exists some intent for the device pair
+        # For now we should avoid installing overlapping intents
+        for intent in main.intents:
+            if not intent.type == 'INTENT_POINT':
+                continue
+            if intent.deviceA == self.deviceA and intent.deviceB == self.deviceB:
+                main.log.warn( self.typeString + " - find an exiting intent for the device pair, abort installation" )
+                return EventStates().ABORT
+        controller = main.controllers[ self.CLIIndex - 1 ]
+        with controller.CLILock:
+            # TODO: handle the case that multiple hosts attach to one device
+            id = controller.CLI.addPointIntent( self.deviceA.dpid, self.deviceB.dpid,
+                                                1, 1, '',
+                                                self.deviceA.hosts[ 0 ].mac,
+                                                self.deviceB.hosts[ 0 ].mac )
+        if id == None:
+            main.log.warn( self.typeString + " - add point intent failed" )
+            return EventStates().FAIL
+        with main.variableLock:
+            newPointIntent = PointIntent( id, self.deviceA, self.deviceB )
+            main.intents.append( newPointIntent )
+            # Update host connectivity status
+            for hostA in self.deviceA.hosts:
+                for hostB in self.deviceB.hosts:
+                    hostA.correspondents.append( hostB )
+        return EventStates().PASS
+
+class DelPointIntent( PointIntentEvent ):
+    """
+    Delete a point-to-point intent
+    """
+    def __init__( self ):
+        PointIntentEvent.__init__( self )
+        self.typeString = main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeString' ]
+        self.typeIndex= int( main.params[ 'EVENT' ][ self.__class__.__name__ ][ 'typeIndex' ] )
+
+    def startPointIntentEvent( self ):
+        assert self.deviceA != None and self.deviceB != None
+        targetIntent = None
+        for intent in main.intents:
+            if not intent.type == 'INTENT_POINT':
+                continue
+            if intent.deviceA == self.deviceA and intent.deviceB == self.deviceB:
+                targetIntent = intent
+                break
+        if targetIntent == None:
+            main.log.warn( self.typeString + " - intent does not exist" )
+            return EventStates().FAIL
+        controller = main.controllers[ self.CLIIndex - 1 ]
+        with controller.CLILock:
+            result = controller.CLI.removeIntent( targetIntent.id, purge=True )
+        if result == None or result == main.FALSE:
+            main.log.warn( self.typeString + " - delete host intent failed" )
+            return EventStates().FAIL
+        with main.variableLock:
+            main.intents.remove( targetIntent )
+            # Update host connectivity status
+            for hostA in self.deviceA.hosts:
+                for hostB in self.deviceB.hosts:
+                    hostA.correspondents.remove( hostB )
+        return EventStates().PASS
