diff --git a/js/NDN.js b/js/NDN.js
index 0410425..41de1d7 100644
--- a/js/NDN.js
+++ b/js/NDN.js
@@ -31,6 +31,7 @@
     // Event handler
     this.onopen = (settings.onopen || function() { if (LOG > 3) console.log("NDN connection established."); });
     this.onclose = (settings.onclose || function() { if (LOG > 3) console.log("NDN connection closed."); });
+	this.ccndid = null;
 };
 
 NDN.UNOPEN = 0;  // created but not opened yet
@@ -101,6 +102,22 @@
 	return result;
 };
 
+// For publishing data
+NDN.CSTable = new Array();
+
+var CSEntry = function CSEntry(name, closure) {
+	this.name = name;        // String
+	this.closure = closure;  // Closure
+};
+
+function getEntryForRegisteredPrefix(name) {
+	for (var i = 0; i < NDN.CSTable.length; i++) {
+		if (NDN.CSTable[i].name.match(name) != null)
+			return NDN.CSTable[i];
+	}
+	return null;
+}
+
 /*
  * Return a function that selects a host at random from hostList and returns { host: host, port: port }.
  * If no more hosts remain, return null.
@@ -155,7 +172,219 @@
 };
 
 NDN.prototype.registerPrefix = function(name, closure, flag) {
-    return this.transport.registerPrefix(this, name, closure, flag);
+    if (this.readyStatus != NDN.OPENED) {
+		console.log('Connection is not established.');
+        return -1;
+    }
+
+	if (this.ccndid == null) {
+		console.log('ccnd node ID unkonwn. Cannot register prefix.');
+		return -1;
+	}
+		
+	var fe = new ForwardingEntry('selfreg', name, null, null, 3, 2147483647);
+	var bytes = encodeForwardingEntry(fe);
+		
+	var si = new SignedInfo();
+	si.setFields();
+		
+	var co = new ContentObject(new Name(), si, bytes, new Signature()); 
+	co.sign();
+	var coBinary = encodeToBinaryContentObject(co);
+		
+	//var nodename = unescape('%00%88%E2%F4%9C%91%16%16%D6%21%8E%A0c%95%A5%A6r%11%E0%A0%82%89%A6%A9%85%AB%D6%E2%065%DB%AF');
+	var nodename = this.ccndid;
+	var interestName = new Name(['ccnx', nodename, 'selfreg', coBinary]);
+
+	var interest = new Interest(interestName);
+	interest.scope = 1;
+	if (LOG > 3) console.log('Send Interest registration packet.');
+    	
+    var csEntry = new CSEntry(name.getName(), closure);
+	NDN.CSTable.push(csEntry);
+    
+    this.transport.send(encodeToBinaryInterest(interest));
+		
+	return 0;
+};
+
+/*
+ * This is called when an entire binary XML element is received, such as a ContentObject or Interest.
+ * Look up in the PITTable and call the closure callback.
+ */
+NDN.prototype.onReceivedElement = function(element) {
+	var decoder = new BinaryXMLDecoder(element);
+	// Dispatch according to packet type
+	if (decoder.peekStartElement(CCNProtocolDTags.Interest)) {  // Interest packet
+		if (LOG > 3) console.log('Interest packet received.');
+				
+		var interest = new Interest();
+		interest.from_ccnb(decoder);
+		if (LOG > 3) console.log(interest);
+		var nameStr = escape(interest.name.getName());
+		if (LOG > 3) console.log(nameStr);
+				
+		var entry = getEntryForRegisteredPrefix(nameStr);
+		if (entry != null) {
+			//console.log(entry);
+			var info = new UpcallInfo(this, interest, 0, null);
+			var ret = entry.closure.upcall(Closure.UPCALL_INTEREST, info);
+			if (ret == Closure.RESULT_INTEREST_CONSUMED && info.contentObject != null) 
+				this.transport.send(encodeToBinaryContentObject(info.contentObject));
+		}				
+	} else if (decoder.peekStartElement(CCNProtocolDTags.ContentObject)) {  // Content packet
+		if (LOG > 3) console.log('ContentObject packet received.');
+				
+		var co = new ContentObject();
+		co.from_ccnb(decoder);
+				
+		if (this.ccndid == null && NDN.ccndIdFetcher.match(co.name)) {
+			// We are in starting phase, record publisherPublicKeyDigest in ccndid
+			if(!co.signedInfo || !co.signedInfo.publisher 
+				|| !co.signedInfo.publisher.publisherPublicKeyDigest) {
+				console.log("Cannot contact router, close NDN now.");
+						
+				// Close NDN if we fail to connect to a ccn router
+				this.readyStatus = NDN.CLOSED;
+				this.onclose();
+				//console.log("NDN.onclose event fired.");
+			} else {
+				//console.log('Connected to ccnd.');
+				this.ccndid = co.signedInfo.publisher.publisherPublicKeyDigest;
+				if (LOG>3) console.log(ndn.ccndid);
+						
+				// Call NDN.onopen after success
+				this.readyStatus = NDN.OPENED;
+				this.onopen();
+				//console.log("NDN.onopen event fired.");
+			}
+		} else {
+			var pitEntry = NDN.getEntryForExpressedInterest(co.name);
+			if (pitEntry != null) {
+				//console.log(pitEntry);
+				// Remove PIT entry from NDN.PITTable
+				var index = NDN.PITTable.indexOf(pitEntry);
+				if (index >= 0)
+					NDN.PITTable.splice(index, 1);
+						
+				var currentClosure = pitEntry.closure;
+						
+				// Cancel interest timer
+				clearTimeout(pitEntry.timerID);
+				//console.log("Clear interest timer");
+				//console.log(currentClosure.timerID);
+						
+				// Key verification
+						
+				// Recursive key fetching & verification closure
+				var KeyFetchClosure = function KeyFetchClosure(content, closure, key, sig, wit) {
+					this.contentObject = content;  // unverified content object
+					this.closure = closure;  // closure corresponding to the contentObject
+					this.keyName = key;  // name of current key to be fetched
+					this.sigHex = sig;  // hex signature string to be verified
+					this.witness = wit;
+						
+					Closure.call(this);
+				};
+						
+                var thisNdn = this;
+				KeyFetchClosure.prototype.upcall = function(kind, upcallInfo) {
+					if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
+						console.log("In KeyFetchClosure.upcall: interest time out.");
+						console.log(this.keyName.contentName.getName());
+					} else if (kind == Closure.UPCALL_CONTENT) {
+						//console.log("In KeyFetchClosure.upcall: signature verification passed");
+								
+						var rsakey = decodeSubjectPublicKeyInfo(upcallInfo.contentObject.content);
+						var verified = rsakey.verifyByteArray(this.contentObject.rawSignatureData, this.witness, this.sigHex);
+								
+						var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
+						//console.log("raise encapsulated closure");
+						this.closure.upcall(flag, new UpcallInfo(thisNdn, null, 0, this.contentObject));
+								
+						// Store key in cache
+						var keyEntry = new KeyStoreEntry(keylocator.keyName, rsakey, new Date().getTime());
+						NDN.addKeyEntry(keyEntry);
+						//console.log(NDN.KeyStore);
+					} else if (kind == Closure.UPCALL_CONTENT_BAD) {
+						console.log("In KeyFetchClosure.upcall: signature verification failed");
+					}
+				};
+						
+				if (co.signedInfo && co.signedInfo.locator && co.signature) {
+					if (LOG > 3) console.log("Key verification...");
+					var sigHex = DataUtils.toHex(co.signature.signature).toLowerCase();
+							
+					var wit = null;
+					if (co.signature.Witness != null) {
+						wit = new Witness();
+						wit.decode(co.signature.Witness);
+					}
+							
+					var keylocator = co.signedInfo.locator;
+					if (keylocator.type == KeyLocatorType.KEYNAME) {
+						if (LOG > 3) console.log("KeyLocator contains KEYNAME");
+						//var keyname = keylocator.keyName.contentName.getName();
+						//console.log(nameStr);
+						//console.log(keyname);
+								
+						if (keylocator.keyName.contentName.match(co.name)) {
+							if (LOG > 3) console.log("Content is key itself");
+									
+							var rsakey = decodeSubjectPublicKeyInfo(co.content);
+							var verified = rsakey.verifyByteArray(co.rawSignatureData, wit, sigHex);
+							var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
+									
+							currentClosure.upcall(flag, new UpcallInfo(this, null, 0, co));
+									
+							// SWT: We don't need to store key here since the same key will be
+							//      stored again in the closure.
+							//var keyEntry = new KeyStoreEntry(keylocator.keyName, rsakey, new Date().getTime());
+							//NDN.addKeyEntry(keyEntry);
+							//console.log(NDN.KeyStore);
+						} else {
+							// Check local key store
+							var keyEntry = NDN.getKeyByName(keylocator.keyName);
+							if (keyEntry) {
+								// Key found, verify now
+								if (LOG > 3) console.log("Local key cache hit");
+								var rsakey = keyEntry.rsaKey;
+								var verified = rsakey.verifyByteArray(co.rawSignatureData, wit, sigHex);
+								var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
+										
+								// Raise callback
+								currentClosure.upcall(flag, new UpcallInfo(this, null, 0, co));
+							} else {
+								// Not found, fetch now
+								if (LOG > 3) console.log("Fetch key according to keylocator");
+								var nextClosure = new KeyFetchClosure(co, currentClosure, keylocator.keyName, sigHex, wit);
+								this.expressInterest(keylocator.keyName.contentName.getPrefix(4), nextClosure);
+							}
+						}
+					} else if (keylocator.type == KeyLocatorType.KEY) {
+						if (LOG > 3) console.log("Keylocator contains KEY");
+								
+						var rsakey = decodeSubjectPublicKeyInfo(co.signedInfo.locator.publicKey);
+						var verified = rsakey.verifyByteArray(co.rawSignatureData, wit, sigHex);
+								
+						var flag = (verified == true) ? Closure.UPCALL_CONTENT : Closure.UPCALL_CONTENT_BAD;
+						// Raise callback
+						currentClosure.upcall(Closure.UPCALL_CONTENT, new UpcallInfo(this, null, 0, co));
+								
+						// Since KeyLocator does not contain key name for this key,
+						// we have no way to store it as a key entry in KeyStore.
+					} else {
+						var cert = keylocator.certificate;
+						console.log("KeyLocator contains CERT");
+						console.log(cert);
+								
+						// TODO: verify certificate
+					}
+				}
+			}
+		}
+	} else
+		console.log('Incoming packet is not Interest or ContentObject. Discard now.');
 };
 
 /*
@@ -180,8 +409,8 @@
     this.port = hostAndPort.port;   
     console.log("Trying host from getHostAndPort: " + this.host);
     
-    // Fetch the ccndId.
-    var interest = new Interest(NDN.ccndIdFetcher);
+    // Fetch any content.
+    var interest = new Interest(new Name("/"));
 	interest.interestLifetime = 4000; // milliseconds    
 
     var thisNDN = this;
@@ -207,8 +436,7 @@
 
 NDN.ConnectClosure.prototype.upcall = function(kind, upcallInfo) {
     if (!(kind == Closure.UPCALL_CONTENT ||
-          kind == Closure.UPCALL_CONTENT_UNVERIFIED ||
-          kind == Closure.UPCALL_INTEREST))
+          kind == Closure.UPCALL_CONTENT_UNVERIFIED))
         // The upcall is not for us.
         return Closure.RESULT_ERR;
         
@@ -220,3 +448,44 @@
     return Closure.RESULT_OK;
 };
 
+/*
+ * A BinaryXmlElementReader lets you call onReceivedData multiple times which uses a
+ *   BinaryXMLStructureDecoder to detect the end of a binary XML element and calls
+ *   elementListener.onReceivedElement(element) with the element. 
+ * This handles the case where a single call to onReceivedData may contain multiple elements.
+ */
+var BinaryXmlElementReader = function BinaryXmlElementReader(elementListener) {
+    this.elementListener = elementListener;
+	this.dataParts = [];
+    this.structureDecoder = new BinaryXMLStructureDecoder();
+};
+
+BinaryXmlElementReader.prototype.onReceivedData = function(/* Uint8Array */ rawData) {
+    dump("got " + rawData.length + " bytes\n");
+    // Process multiple objects in the data.
+    while(true) {
+        // Scan the input to check if a whole ccnb object has been read.
+        this.structureDecoder.seek(0);
+        if (this.structureDecoder.findElementEnd(rawData)) {
+            // Got the remainder of an object.  Report to the caller.
+            this.dataParts.push(rawData.subarray(0, this.structureDecoder.offset));
+            dump("calling onReceivedElement\n");
+            this.elementListener.onReceivedElement(DataUtils.concatArrays(this.dataParts));
+        
+            // Need to read a new object.
+            rawData = rawData.subarray(this.structureDecoder.offset, rawData.length);
+            this.dataParts = [];
+            this.structureDecoder = new BinaryXMLStructureDecoder();
+            if (rawData.length == 0)
+                // No more data in the packet.
+                return;
+            
+            // else loop back to decode.
+        }
+        else {
+            // Save for a later call to concatArrays so that we only copy data once.
+            this.dataParts.push(rawData);
+            return;
+        }
+    }    
+}
\ No newline at end of file
