diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
new file mode 100755
index 0000000..9f6353e
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
@@ -0,0 +1,407 @@
+package net.onrc.onos.core.intent.runtime;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.floodlightcontroller.core.module.IFloodlightModule;
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.onrc.onos.core.datagrid.IDatagridService;
+import net.onrc.onos.core.datagrid.IEventChannel;
+import net.onrc.onos.core.datagrid.IEventChannelListener;
+import net.onrc.onos.core.intent.Intent;
+import net.onrc.onos.core.intent.IntentMap;
+import net.onrc.onos.core.intent.IntentOperation;
+import net.onrc.onos.core.intent.IntentOperationList;
+import net.onrc.onos.core.intent.PathIntent;
+import net.onrc.onos.core.intent.PathIntentMap;
+import net.onrc.onos.core.intent.ShortestPathIntent;
+import net.onrc.onos.core.intent.Intent.IntentState;
+import net.onrc.onos.core.intent.IntentOperation.Operator;
+import net.onrc.onos.ofcontroller.networkgraph.DeviceEvent;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphListener;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
+import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
+import net.onrc.onos.ofcontroller.networkgraph.PortEvent;
+import net.onrc.onos.ofcontroller.networkgraph.SwitchEvent;
+import net.onrc.onos.registry.controller.IControllerRegistryService;
+
+/**
+ * @author Toshio Koide (t-koide@onlab.us)
+ */
+public class PathCalcRuntimeModule implements IFloodlightModule, IPathCalcRuntimeService, INetworkGraphListener, IEventChannelListener<Long, IntentStateList> {
+	class PerfLog {
+		private String step;
+		private long time;
+
+		public PerfLog(String step) {
+			this.step = step;
+			this.time = System.nanoTime();
+		}
+
+		public void logThis() {
+			log.error("Time:{}, Step:{}", time, step);
+		}
+	}
+	class PerfLogger {
+		private LinkedList<PerfLog> logData = new LinkedList<>();
+
+		public PerfLogger(String logPhase) {
+			log("start_" + logPhase);
+		}
+
+		public void log(String step) {
+			logData.add(new PerfLog(step));
+		}
+
+		public void flushLog() {
+			log("finish");
+			for (PerfLog log: logData) {
+				log.logThis();
+			}
+			logData.clear();
+		}
+	}
+	private PathCalcRuntime runtime;
+	private IDatagridService datagridService;
+	private INetworkGraphService networkGraphService;
+	private IntentMap highLevelIntents;
+	private PathIntentMap pathIntents;
+	private IControllerRegistryService controllerRegistry;
+	private PersistIntent persistIntent;
+
+	private IEventChannel<Long, IntentOperationList> opEventChannel;
+	private final ReentrantLock lock = new ReentrantLock();
+	private HashSet<LinkEvent> unmatchedLinkEvents = new HashSet<>();
+	private static final String INTENT_OP_EVENT_CHANNEL_NAME = "onos.pathintent";
+	private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";
+	private static final Logger log = LoggerFactory.getLogger(PathCalcRuntimeModule.class);
+
+	// ================================================================================
+	// private methods
+	// ================================================================================
+
+	private void reroutePaths(Collection<Intent> oldPaths) {
+		if (oldPaths == null || oldPaths.isEmpty())
+			return;
+
+		IntentOperationList reroutingOperation = new IntentOperationList();
+		for (Intent intent : oldPaths) {
+			PathIntent pathIntent = (PathIntent) intent;
+			if (pathIntent.isPathFrozen())
+				continue;
+			if (pathIntent.getState().equals(IntentState.INST_ACK) && // XXX: path intents in flight
+					!reroutingOperation.contains(pathIntent.getParentIntent())) {
+				reroutingOperation.add(Operator.ADD, pathIntent.getParentIntent());
+			}
+		}
+		executeIntentOperations(reroutingOperation);
+	}
+
+
+	// ================================================================================
+	// IFloodlightModule implementations
+	// ================================================================================
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
+		Collection<Class<? extends IFloodlightService>> l = new ArrayList<>(1);
+		l.add(IPathCalcRuntimeService.class);
+		return l;
+	}
+
+	@Override
+	public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
+		Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<>();
+		m.put(IPathCalcRuntimeService.class, this);
+		return m;
+	}
+
+	@Override
+	public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
+		Collection<Class<? extends IFloodlightService>> l = new ArrayList<>(2);
+		l.add(IDatagridService.class);
+		l.add(INetworkGraphService.class);
+		return l;
+	}
+
+	@Override
+	public void init(FloodlightModuleContext context) throws FloodlightModuleException {
+		datagridService = context.getServiceImpl(IDatagridService.class);
+		networkGraphService = context.getServiceImpl(INetworkGraphService.class);
+		controllerRegistry = context.getServiceImpl(IControllerRegistryService.class);
+	}
+
+	@Override
+	public void startUp(FloodlightModuleContext context) {
+		highLevelIntents = new IntentMap();
+		runtime = new PathCalcRuntime(networkGraphService.getNetworkGraph());
+		pathIntents = new PathIntentMap();
+		opEventChannel = datagridService.createChannel(INTENT_OP_EVENT_CHANNEL_NAME, Long.class, IntentOperationList.class);
+		datagridService.addListener(INTENT_STATE_EVENT_CHANNEL_NAME, this, Long.class, IntentStateList.class);
+		networkGraphService.registerNetworkGraphListener(this);
+		persistIntent = new PersistIntent(controllerRegistry, networkGraphService);
+	}
+
+	// ================================================================================
+	// IPathCalcRuntimeService implementations
+	// ================================================================================
+
+	@Override
+	public IntentOperationList executeIntentOperations(IntentOperationList list) {
+		if (list == null || list.size() == 0)
+			return null;
+		PerfLogger p = new PerfLogger("executeIntentOperations_" + list.get(0).operator);
+
+		lock.lock(); // TODO optimize locking using smaller steps
+		try {
+			// update the map of high-level intents
+			p.log("begin_updateInMemoryIntents");
+			highLevelIntents.executeOperations(list);
+
+			// change states of high-level intents
+			IntentStateList states = new IntentStateList();
+			for (IntentOperation op : list) {
+				switch (op.operator) {
+				case ADD:
+					switch (op.intent.getState()) {
+					case CREATED:
+						states.put(op.intent.getId(), IntentState.INST_REQ);
+						break;
+					case INST_ACK:
+						states.put(op.intent.getId(), IntentState.REROUTE_REQ);
+						break;
+					default:
+						break;
+					}
+					break;
+				case REMOVE:
+					switch (op.intent.getState()) {
+					case CREATED:
+						states.put(op.intent.getId(), IntentState.DEL_REQ);
+						break;
+					default:
+						break;
+					}
+					break;
+				default:
+					break;
+				}
+			}
+			highLevelIntents.changeStates(states);
+			p.log("end_updateInMemoryIntents");
+
+			// calculate path-intents (low-level operations)
+			p.log("begin_calcPathIntents");
+			IntentOperationList pathIntentOperations = runtime.calcPathIntents(list, highLevelIntents, pathIntents);
+			p.log("end_calcPathIntents");
+
+			// persist calculated low-level operations into data store
+			p.log("begin_persistPathIntents");
+			long key = persistIntent.getKey();
+			persistIntent.persistIfLeader(key, pathIntentOperations);
+			p.log("end_persistPathIntents");
+
+			// remove error-intents and reflect them to high-level intents
+			p.log("begin_removeErrorIntents");
+			states.clear();
+			Iterator<IntentOperation> i = pathIntentOperations.iterator();
+			while (i.hasNext()) {
+				IntentOperation op = i.next();
+				if (op.operator.equals(Operator.ERROR)) {
+					states.put(op.intent.getId(), IntentState.INST_NACK);
+					i.remove();
+				}
+			}
+			highLevelIntents.changeStates(states);
+			p.log("end_removeErrorIntents");
+
+			// update the map of path intents and publish the path operations
+			p.log("begin_updateInMemoryPathIntents");
+			pathIntents.executeOperations(pathIntentOperations);
+			p.log("end_updateInMemoryPathIntents");
+
+			// XXX Demo special: add a complete path to remove operation
+			p.log("begin_addPathToRemoveOperation");
+			for (IntentOperation op: pathIntentOperations) {
+				if(op.operator.equals(Operator.REMOVE)) {
+					op.intent = pathIntents.getIntent(op.intent.getId());
+				}
+				if (op.intent instanceof PathIntent) {
+					log.debug("operation: {}, intent:{}", op.operator, op.intent);
+				}
+			}
+			p.log("end_addPathToRemoveOperation");
+
+			// send notification
+			p.log("begin_sendNotification");
+			// XXX: Send notifications using the same key every time
+			// and receive them by entryAdded() and entryUpdated()
+			opEventChannel.addEntry(0L, pathIntentOperations);
+			p.log("end_sendNotification");
+			//opEventChannel.removeEntry(key);
+			return pathIntentOperations;
+		}
+		finally {
+			p.flushLog();
+			lock.unlock();
+		}
+	}
+
+	@Override
+	public IntentMap getHighLevelIntents() {
+		return highLevelIntents;
+	}
+
+	@Override
+	public IntentMap getPathIntents() {
+		return pathIntents;
+	}
+
+	@Override
+	public void purgeIntents() {
+		highLevelIntents.purge();
+		pathIntents.purge();
+	}
+
+	// ================================================================================
+	// INetworkGraphListener implementations
+	// ================================================================================
+
+	@Override
+	public void networkGraphEvents(Collection<SwitchEvent> addedSwitchEvents,
+			Collection<SwitchEvent> removedSwitchEvents,
+			Collection<PortEvent> addedPortEvents,
+			Collection<PortEvent> removedPortEvents,
+			Collection<LinkEvent> addedLinkEvents,
+			Collection<LinkEvent> removedLinkEvents,
+			Collection<DeviceEvent> addedDeviceEvents,
+			Collection<DeviceEvent> removedDeviceEvents) {
+
+		PerfLogger p = new PerfLogger("networkGraphEvents");
+		HashSet<Intent> affectedPaths = new HashSet<>();
+
+		boolean rerouteAll = false;
+		for(LinkEvent le : addedLinkEvents) {
+		    LinkEvent rev = new LinkEvent(le.getDst().getDpid(), le.getDst().getNumber(), le.getSrc().getDpid(), le.getSrc().getNumber());
+		    if(unmatchedLinkEvents.contains(rev)) {
+			rerouteAll = true;
+			unmatchedLinkEvents.remove(rev);
+			log.debug("Found matched LinkEvent: {} {}", rev, le);
+		    }
+		    else {
+			unmatchedLinkEvents.add(le);
+			log.debug("Adding unmatched LinkEvent: {}", le);
+		    }
+		}
+		for(LinkEvent le : removedLinkEvents) {
+		    if (unmatchedLinkEvents.contains(le)) {
+			unmatchedLinkEvents.remove(le);
+			log.debug("Removing LinkEvent: {}", le);
+		    }
+		}
+		if(unmatchedLinkEvents.size() > 0) {
+		    log.debug("Unmatched link events: {} events", unmatchedLinkEvents.size());
+		}
+
+		if ( rerouteAll ) {//addedLinkEvents.size() > 0) { // ||
+//				addedPortEvents.size() > 0 ||
+//				addedSwitchEvents.size() > 0) {
+			p.log("begin_getAllIntents");
+			affectedPaths.addAll(getPathIntents().getAllIntents());
+			p.log("end_getAllIntents");
+		}
+		else if (removedSwitchEvents.size() > 0 ||
+			 removedLinkEvents.size() > 0 ||
+			 removedPortEvents.size() > 0) {
+			p.log("begin_getIntentsByLink");
+			for (LinkEvent linkEvent: removedLinkEvents)
+				affectedPaths.addAll(pathIntents.getIntentsByLink(linkEvent));
+			p.log("end_getIntentsByLink");
+
+			p.log("begin_getIntentsByPort");
+			for (PortEvent portEvent: removedPortEvents)
+				affectedPaths.addAll(pathIntents.getIntentsByPort(portEvent.getDpid(), portEvent.getNumber()));
+			p.log("end_getIntentsByPort");
+
+			p.log("begin_getIntentsByDpid");
+			for (SwitchEvent switchEvent: removedSwitchEvents)
+				affectedPaths.addAll(pathIntents.getIntentsByDpid(switchEvent.getDpid()));
+			p.log("end_getIntentsByDpid");
+		}
+		p.log("begin_reroutePaths");
+		reroutePaths(affectedPaths);
+		p.log("end_reroutePaths");
+		p.flushLog();
+	}
+
+	// ================================================================================
+	// IEventChannelListener implementations
+	// ================================================================================
+
+	@Override
+	public void entryAdded(IntentStateList value) {
+		entryUpdated(value);
+	}
+
+	@Override
+	public void entryRemoved(IntentStateList value) {
+		// do nothing
+	}
+
+	@Override
+	public void entryUpdated(IntentStateList value) {
+		// TODO draw state transition diagram in multiple ONOS instances and update this method
+		PerfLogger p = new PerfLogger("entryUpdated");
+		lock.lock(); // TODO optimize locking using smaller steps
+		try {
+			// reflect state changes of path-level intent into application-level intents
+			p.log("begin_changeStateByNotification");
+			IntentStateList highLevelIntentStates = new IntentStateList();
+			IntentStateList pathIntentStates = new IntentStateList();
+			for (Entry<String, IntentState> entry: value.entrySet()) {
+				PathIntent pathIntent = (PathIntent) pathIntents.getIntent(entry.getKey());
+				if (pathIntent == null) continue;
+
+				Intent parentIntent = pathIntent.getParentIntent();
+				if (parentIntent == null ||
+						!(parentIntent instanceof ShortestPathIntent) ||
+						!((ShortestPathIntent) parentIntent).getPathIntentId().equals(pathIntent.getId()))
+					continue;
+
+				IntentState state = entry.getValue();
+				switch (state) {
+				//case INST_REQ:
+				case INST_ACK:
+				case INST_NACK:
+				//case DEL_REQ:
+				case DEL_ACK:
+				case DEL_PENDING:
+					highLevelIntentStates.put(parentIntent.getId(), state);
+					pathIntentStates.put(entry.getKey(), entry.getValue());
+					break;
+				default:
+					break;
+				}
+			}
+			highLevelIntents.changeStates(highLevelIntentStates);
+			pathIntents.changeStates(pathIntentStates);
+			p.log("end_changeStateByNotification");
+		}
+		finally {
+			p.flushLog();
+			lock.unlock();
+		}
+	}
+}
