Implement when the upcall from reexpressInterest returns Closure.RESULT_REEXPRESS.
diff --git a/js/NDN.js b/js/NDN.js
index e6e1a37..90186a5 100644
--- a/js/NDN.js
+++ b/js/NDN.js
@@ -195,37 +195,40 @@
  *   this.transport.send to send the interest.
  */
 NDN.prototype.expressInterestHelper = function(interest, closure) {
+    var binaryInterest = encodeToBinaryInterest(interest);
+    var thisNDN = this;    
 	//TODO: check local content store first
 	if (closure != null) {
 		var pitEntry = new PITEntry(interest, closure);
         // TODO: This needs to be a single thread-safe transaction on a global object.
 		NDN.PITTable.push(pitEntry);
 		closure.pitEntry = pitEntry;
-	}
 
-	// Set interest timer
-    var thisNDN = this;
-	if (closure != null) {
+        // Set interest timer.
         var timeoutMilliseconds = (interest.interestLifetime || 4000);
-		pitEntry.timerID = setTimeout(function() {
-			if (LOG > 3) console.log("Interest time out.");
+        var timeoutCallback = function() {
+			if (LOG > 3) console.log("Interest time out: " + interest.name.to_uri());
 				
-			// Remove PIT entry from NDN.PITTable.
+			// Remove PIT entry from NDN.PITTable, even if we add it again later to re-express
+            //   the interest because we don't want to match it in the mean time.
             // TODO: Make this a thread-safe operation on the global PITTable.
 			var index = NDN.PITTable.indexOf(pitEntry);
-			//console.log(NDN.PITTable);
 			if (index >= 0) 
 	            NDN.PITTable.splice(index, 1);
-			//console.log(NDN.PITTable);
-			//console.log(pitEntry.interest.name.getName());
 				
 			// Raise closure callback
-			closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, new UpcallInfo(thisNDN, interest, 0, null));
-		}, timeoutMilliseconds);
-		//console.log(closure.timerID);
+			if (closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, 
+                  new UpcallInfo(thisNDN, interest, 0, null)) == Closure.RESULT_REEXPRESS) {
+			    if (LOG > 3) console.log("Re-express interest: " + interest.name.to_uri());
+                pitEntry.timerID = setTimeout(timeoutCallback, timeoutMilliseconds);
+                NDN.PITTable.push(pitEntry);
+                thisNDN.transport.send(binaryInterest);
+            }
+		};
+		pitEntry.timerID = setTimeout(timeoutCallback, timeoutMilliseconds);
 	}
 
-	this.transport.send(encodeToBinaryInterest(interest));
+	this.transport.send(binaryInterest);
 };
 
 NDN.prototype.registerPrefix = function(name, closure, flag) {
diff --git a/js/tools/build/ndn-js-uncomp.js b/js/tools/build/ndn-js-uncomp.js
index bb22c6a..9b1be2a 100644
--- a/js/tools/build/ndn-js-uncomp.js
+++ b/js/tools/build/ndn-js-uncomp.js
@@ -7748,37 +7748,40 @@
  *   this.transport.send to send the interest.
  */
 NDN.prototype.expressInterestHelper = function(interest, closure) {
+    var binaryInterest = encodeToBinaryInterest(interest);
+    var thisNDN = this;    
 	//TODO: check local content store first
 	if (closure != null) {
 		var pitEntry = new PITEntry(interest, closure);
         // TODO: This needs to be a single thread-safe transaction on a global object.
 		NDN.PITTable.push(pitEntry);
 		closure.pitEntry = pitEntry;
-	}
 
-	// Set interest timer
-    var thisNDN = this;
-	if (closure != null) {
+        // Set interest timer.
         var timeoutMilliseconds = (interest.interestLifetime || 4000);
-		pitEntry.timerID = setTimeout(function() {
-			if (LOG > 3) console.log("Interest time out.");
+        var timeoutCallback = function() {
+			if (LOG > 3) console.log("Interest time out: " + interest.name.to_uri());
 				
-			// Remove PIT entry from NDN.PITTable.
+			// Remove PIT entry from NDN.PITTable, even if we add it again later to re-express
+            //   the interest because we don't want to match it in the mean time.
             // TODO: Make this a thread-safe operation on the global PITTable.
 			var index = NDN.PITTable.indexOf(pitEntry);
-			//console.log(NDN.PITTable);
 			if (index >= 0) 
 	            NDN.PITTable.splice(index, 1);
-			//console.log(NDN.PITTable);
-			//console.log(pitEntry.interest.name.getName());
 				
 			// Raise closure callback
-			closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, new UpcallInfo(thisNDN, interest, 0, null));
-		}, timeoutMilliseconds);
-		//console.log(closure.timerID);
+			if (closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, 
+                  new UpcallInfo(thisNDN, interest, 0, null)) == Closure.RESULT_REEXPRESS) {
+			    if (LOG > 3) console.log("Re-express interest: " + interest.name.to_uri());
+                pitEntry.timerID = setTimeout(timeoutCallback, timeoutMilliseconds);
+                NDN.PITTable.push(pitEntry);
+                thisNDN.transport.send(binaryInterest);
+            }
+		};
+		pitEntry.timerID = setTimeout(timeoutCallback, timeoutMilliseconds);
 	}
 
-	this.transport.send(encodeToBinaryInterest(interest));
+	this.transport.send(binaryInterest);
 };
 
 NDN.prototype.registerPrefix = function(name, closure, flag) {
diff --git a/js/tools/build/ndn-js.js b/js/tools/build/ndn-js.js
index e6a4ef6..5c27b24 100644
--- a/js/tools/build/ndn-js.js
+++ b/js/tools/build/ndn-js.js
@@ -260,7 +260,8 @@
 NDN.makeShuffledGetHostAndPort=function(a,b){a=a.slice(0,a.length);DataUtils.shuffle(a);return function(){return 0==a.length?null:{host:a.splice(0,1)[0],port:b}}};
 NDN.prototype.expressInterest=function(a,b,c){var d=new Interest(a);null!=c?(d.minSuffixComponents=c.minSuffixComponents,d.maxSuffixComponents=c.maxSuffixComponents,d.publisherPublicKeyDigest=c.publisherPublicKeyDigest,d.exclude=c.exclude,d.childSelector=c.childSelector,d.answerOriginKind=c.answerOriginKind,d.scope=c.scope,d.interestLifetime=c.interestLifetime):d.interestLifetime=4E3;if(null==this.host||null==this.port)if(null==this.getHostAndPort)console.log("ERROR: host OR port NOT SET");else{var e=
 this;this.connectAndExecute(function(){e.reconnectAndExpressInterest(d,b)})}else this.reconnectAndExpressInterest(d,b)};NDN.prototype.reconnectAndExpressInterest=function(a,b){if(this.transport.connectedHost!=this.host||this.transport.connectedPort!=this.port){var c=this;this.transport.connect(c,function(){c.expressInterestHelper(a,b)})}else this.expressInterestHelper(a,b)};
-NDN.prototype.expressInterestHelper=function(a,b){if(null!=b){var c=new PITEntry(a,b);NDN.PITTable.push(c);b.pitEntry=c}var d=this;null!=b&&(c.timerID=setTimeout(function(){3<LOG&&console.log("Interest time out.");var e=NDN.PITTable.indexOf(c);0<=e&&NDN.PITTable.splice(e,1);b.upcall(Closure.UPCALL_INTEREST_TIMED_OUT,new UpcallInfo(d,a,0,null))},a.interestLifetime||4E3));this.transport.send(encodeToBinaryInterest(a))};
+NDN.prototype.expressInterestHelper=function(a,b){var c=encodeToBinaryInterest(a),d=this;if(null!=b){var e=new PITEntry(a,b);NDN.PITTable.push(e);b.pitEntry=e;var f=a.interestLifetime||4E3,g=function(){3<LOG&&console.log("Interest time out: "+a.name.to_uri());var j=NDN.PITTable.indexOf(e);0<=j&&NDN.PITTable.splice(j,1);b.upcall(Closure.UPCALL_INTEREST_TIMED_OUT,new UpcallInfo(d,a,0,null))==Closure.RESULT_REEXPRESS&&(3<LOG&&console.log("Re-express interest: "+a.name.to_uri()),e.timerID=setTimeout(g,
+f),NDN.PITTable.push(e),d.transport.send(c))};e.timerID=setTimeout(g,f)}this.transport.send(c)};
 NDN.prototype.registerPrefix=function(a,b,c){var d=this,e=function(){if(null==d.ccndid){var e=new Interest(NDN.ccndIdFetcher);e.interestLifetime=4E3;3<LOG&&console.log("Expressing interest for ccndid from ccnd.");d.reconnectAndExpressInterest(e,new NDN.FetchCcndidClosure(d,a,b,c))}else d.registerPrefixHelper(a,b,c)};null==this.host||null==this.port?null==this.getHostAndPort?console.log("ERROR: host OR port NOT SET"):this.connectAndExecute(e):e()};
 NDN.FetchCcndidClosure=function(a,b,c,d){Closure.call(this);this.ndn=a;this.name=b;this.callerClosure=c;this.flag=d};
 NDN.FetchCcndidClosure.prototype.upcall=function(a,b){if(a==Closure.UPCALL_INTEREST_TIMED_OUT)return console.log("Timeout while requesting the ccndid.  Cannot registerPrefix for "+this.name.to_uri()+" ."),Closure.RESULT_OK;if(!(a==Closure.UPCALL_CONTENT||a==Closure.UPCALL_CONTENT_UNVERIFIED))return Closure.RESULT_ERR;var c=b.contentObject;!c.signedInfo||!c.signedInfo.publisher||!c.signedInfo.publisher.publisherPublicKeyDigest?console.log("ContentObject doesn't have a publisherPublicKeyDigest. Cannot set ccndid and registerPrefix for "+