diff --git a/js/tools/build/ndn-js-uncomp.js b/js/tools/build/ndn-js-uncomp.js
index c2f610c..73d3862 100644
--- a/js/tools/build/ndn-js-uncomp.js
+++ b/js/tools/build/ndn-js-uncomp.js
@@ -75,19 +75,25 @@
 /**
  * settings is an associative array with the following defaults:
  * {
- *   host: 'localhost',
- *   port: 9696,
  *   getTransport: function() { return new WebSocketTransport(); }
+ *   getHostAndPort: transport.defaultGetHostAndPort,
+ *   host: 'localhost', // If null, use getHostAndPort when connecting.
+ *   port: 9696,
  *   onopen: function() { if (LOG > 3) console.log("NDN connection established."); }
  *   onclose: function() { if (LOG > 3) console.log("NDN connection closed."); }
  * }
+ * 
+ * getHostAndPort is a function, on each call it returns a new { host: host, port: port } or
+ *   null if there are no more hosts.
  */
 var NDN = function NDN(settings) {
     settings = (settings || {});
-	this.host = (settings.host || "localhost");
-	this.port = (settings.port || 9696);
     var getTransport = (settings.getTransport || function() { return new WebSocketTransport(); });
     this.transport = getTransport();
+    this.getHostAndPort = (settings.getHostAndPort || this.transport.defaultGetHostAndPort);
+	this.host = (settings.host !== undefined ? settings.host : 'localhost');
+    dump("this.host " + this.host + "\n");
+	this.port = (settings.port || 9696);
     this.readyStatus = NDN.UNOPEN;
     // Event handler
     this.onopen = (settings.onopen || function() { if (LOG > 3) console.log("NDN connection established."); });
@@ -98,13 +104,55 @@
 NDN.OPENED = 1;  // connection to ccnd opened
 NDN.CLOSED = 2;  // connection to ccnd closed
 
-/* Java Socket Bridge and XPCOM transport */
+NDN.ccndIdFetcher = '/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY';
 
 NDN.prototype.createRoute = function(host,port){
 	this.host=host;
 	this.port=port;
 }
 
+// For fetching data
+NDN.PITTable = new Array();
+
+var PITEntry = function PITEntry(interest, closure) {
+	this.interest = interest;  // Interest
+	this.closure = closure;    // Closure
+};
+
+// Return the longest entry from NDN.PITTable that matches name.
+NDN.getEntryForExpressedInterest = function(/*Name*/ name) {
+    // TODO: handle multiple matches?  Maybe not from registerPrefix because multiple ContentObject
+    //   could be sent for one Interest?
+    var result = null;
+    
+	for (var i = 0; i < NDN.PITTable.length; i++) {
+		if (NDN.PITTable[i].interest.matches_name(name)) {
+            if (result == null || 
+                NDN.PITTable[i].interest.name.components.length > result.interest.name.components.length)
+                result = NDN.PITTable[i];
+        }
+	}
+    
+	return result;
+};
+
+/*
+ * Return a function that selects a host at random from hostList and returns { host: host, port: port }.
+ * If no more hosts remain, return null.
+ */
+NDN.makeShuffledGetHostAndPort = function(hostList, port) {
+    // Make a copy.
+    hostList = hostList.slice(0, hostList.length);
+    DataUtils.shuffle(hostList);
+
+    return function() {
+        if (hostList.length == 0)
+            return null;
+        
+        return { host: hostList.splice(0, 1)[0], port: port };
+    };
+};
+
 /** Encode name as an Interest. If template is not null, use its attributes.
  *  Send the interest to host:port, read the entire response and call
  *  closure.upcall(Closure.UPCALL_CONTENT (or Closure.UPCALL_CONTENT_UNVERIFIED),
@@ -117,11 +165,6 @@
         closure,
         // Interest
         template) {
-	if (this.host == null || this.port == null) {
-		dump('ERROR host OR port NOT SET\n');
-        return;
-    }
-    
 	var interest = new Interest(name);
     if (template != null) {
 		interest.minSuffixComponents = template.minSuffixComponents;
@@ -135,14 +178,83 @@
     }
     else
         interest.interestLifetime = 4.0;   // default interest timeout value in seconds.
-    
-    this.transport.expressInterest(this, interest, closure);
-};
 
+	if (this.host == null || this.port == null) {
+        if (this.getHostAndPort == null)
+            console.log('ERROR: host OR port NOT SET');
+        else
+            this.connectAndExpressInterest(interest, closure);
+    }
+    else
+        this.transport.expressInterest(this, interest, closure);
+};
 
 NDN.prototype.registerPrefix = function(name, closure, flag) {
     return this.transport.registerPrefix(this, name, closure, flag);
 }
+
+/*
+ * Assume this.getHostAndPort is not null.  This is called when this.host is null or its host
+ *   is not alive.  Get a host and port, connect, then express callerInterest with callerClosure.
+ */
+NDN.prototype.connectAndExpressInterest = function(callerInterest, callerClosure) {
+    var hostAndPort = this.getHostAndPort();
+    if (hostAndPort == null) {
+        console.log('ERROR: No more hosts from getHostAndPort');
+        this.host = null;
+        return;
+    }
+
+    if (hostAndPort.host == this.host && hostAndPort.port == this.port) {
+        console.log('ERROR: The host returned by getHostAndPort is not alive: ' + 
+                this.host + ":" + this.port);
+        return;
+    }
+        
+    this.host = hostAndPort.host;
+    this.port = hostAndPort.port;   
+    console.log("Trying host from getHostAndPort: " + this.host);
+    
+    // Fetch the ccndId.
+    var interest = new Interest(new Name(NDN.ccndIdFetcher));
+	interest.interestLifetime = 4.0; // seconds    
+
+    var thisNDN = this;
+	var timerID = setTimeout(function() {
+        console.log("Timeout waiting for host " + thisNDN.host);
+        // Try again.
+        thisNDN.connectAndExpressInterest(callerInterest, callerClosure);
+	}, 3000);
+  
+    this.transport.expressInterest
+        (this, interest, new NDN.ConnectClosure(this, callerInterest, callerClosure, timerID));
+}
+
+NDN.ConnectClosure = function ConnectClosure(ndn, callerInterest, callerClosure, timerID) {
+    // Inherit from Closure.
+    Closure.call(this);
+    
+    this.ndn = ndn;
+    this.callerInterest = callerInterest;
+    this.callerClosure = callerClosure;
+    this.timerID = timerID;
+};
+
+NDN.ConnectClosure.prototype.upcall = function(kind, upcallInfo) {
+    if (!(kind == Closure.UPCALL_CONTENT ||
+          kind == Closure.UPCALL_CONTENT_UNVERIFIED ||
+          kind == Closure.UPCALL_INTEREST))
+        // The upcall is not for us.
+        return Closure.RESULT_ERR;
+        
+    // The host is alive, so cancel the timeout and issue the caller's interest.
+    clearTimeout(this.timerID);
+    console.log(this.ndn.host + ": Host is alive. Fetching callerInterest.");
+    this.ndn.transport.expressInterest(this.ndn, this.callerInterest, this.callerClosure);
+
+    return Closure.RESULT_OK;
+};
+
 /** 
  * @author: Wentao Shang
  * See COPYING for copyright and distribution information.
@@ -155,10 +267,12 @@
 	this.buffer = new Uint8Array(this.maxBufferSize);
 	this.bufferOffset = 0;
 	this.structureDecoder = new BinaryXMLStructureDecoder();
+    this.defaultGetHostAndPort = NDN.makeShuffledGetHostAndPort
+        (["A.ws.ndn.ucla.edu", "B.ws.ndn.ucla.edu", "C.ws.ndn.ucla.edu", "D.ws.ndn.ucla.edu", 
+          "E.ws.ndn.ucla.edu"],
+         9696);
 };
 
-var ccndIdFetcher = '/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY';
-
 WebSocketTransport.prototype.connectWebSocket = function(ndn) {
 	if (this.ws != null)
 		delete this.ws;
@@ -239,7 +353,7 @@
 				nameStr = co.name.getName();
 				if (LOG > 3) console.log(nameStr);
 				
-				if (self.ccndid == null && nameStr.match(ccndIdFetcher) != null) {
+				if (self.ccndid == null && nameStr.match(NDN.ccndIdFetcher) != null) {
 					// We are in starting phase, record publisherPublicKeyDigest in self.ccndid
 					if(!co.signedInfo || !co.signedInfo.publisher 
 						|| !co.signedInfo.publisher.publisherPublicKeyDigest) {
@@ -260,7 +374,7 @@
 						//console.log("NDN.onopen event fired.");
 					}
 				} else {
-					var pitEntry = getEntryForExpressedInterest(nameStr);
+					var pitEntry = NDN.getEntryForExpressedInterest(co.name);
 					if (pitEntry != null) {
 						//console.log(pitEntry);
 						
@@ -269,9 +383,10 @@
 						//console.log("Clear interest timer");
 						//console.log(pitEntry.closure.timerID);
 						
-						// Remove PIT entry from PITTable
-						var index = PITTable.indexOf(pitEntry);
-						PITTable.splice(index, 1);
+						// Remove PIT entry from NDN.PITTable
+						var index = NDN.PITTable.indexOf(pitEntry);
+						if (index >= 0)
+                            NDN.PITTable.splice(index, 1);
 						
 						// Raise callback
 						pitEntry.closure.upcall(Closure.UPCALL_CONTENT, new UpcallInfo(ndn, null, 0, co));
@@ -298,7 +413,7 @@
 		if (LOG > 3) console.log('ws.onopen: ReadyState: ' + this.readyState);
 
 		// Fetch ccndid now
-		var interest = new Interest(new Name(ccndIdFetcher));
+		var interest = new Interest(new Name(NDN.ccndIdFetcher));
 		interest.interestLifetime = 4.0; // seconds
 		var subarray = encodeToBinaryInterest(interest);
 		
@@ -323,25 +438,7 @@
 		ndn.onclose();
 		//console.log("NDN.onclose event fired.");
 	}
-}
-
-
-// For fetching data
-var PITTable = new Array();
-
-var PITEntry = function PITEntry(interest, closure) {
-	this.interest = interest;  // String
-	this.closure = closure;    // Closure
-}
-
-function getEntryForExpressedInterest(name) {
-	for (var i = 0; i < PITTable.length; i++) {
-		if (name.match(PITTable[i].interest) != null)
-			return PITTable[i];
-			// TODO: handle multiple matching prefixes
-	}
-	return null;
-}
+};
 
 WebSocketTransport.prototype.expressInterest = function(ndn, interest, closure) {
 	if (this.ws != null) {
@@ -351,8 +448,8 @@
 		var bytearray = new Uint8Array(binaryInterest.length);
 		bytearray.set(binaryInterest);
 		
-		var pitEntry = new PITEntry(interest.name.getName(), closure);
-		PITTable.push(pitEntry);
+		var pitEntry = new PITEntry(interest, closure);
+		NDN.PITTable.push(pitEntry);
 		
 		this.ws.send(bytearray.buffer);
 		if (LOG > 3) console.log('ws.send() returned.');
@@ -361,11 +458,12 @@
 		closure.timerID = setTimeout(function() {
 			if (LOG > 3) console.log("Interest time out.");
 			
-			// Remove PIT entry from PITTable
-			var index = PITTable.indexOf(pitEntry);
-			//console.log(PITTable);
-			PITTable.splice(index, 1);
-			//console.log(PITTable);
+			// Remove PIT entry from NDN.PITTable
+			var index = NDN.PITTable.indexOf(pitEntry);
+			//console.log(NDN.PITTable);
+			if (index >= 0) 
+                NDN.PITTable.splice(index, 1);
+			//console.log(NDN.PITTable);
 			// Raise closure callback
 			closure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, new UpcallInfo(ndn, interest, 0, null));
 		}, interest.interestLifetime * 1000);  // convert interestLifetime from seconds to ms.
@@ -382,7 +480,7 @@
 var CSEntry = function CSEntry(name, closure) {
 	this.name = name;        // String
 	this.closure = closure;  // Closure
-}
+};
 
 function getEntryForRegisteredPrefix(name) {
 	for (var i = 0; i < CSTable.length; i++) {
@@ -437,7 +535,7 @@
 		console.log('WebSocket connection is not established.');
 		return -1;
 	}
-}
+};
 
 /**
  * @author: Meki Cheraoui
@@ -900,6 +998,22 @@
 }
 
 /*
+ * Return true if this Name has the same components as name.
+ */
+Name.prototype.equalsName = function(name) {
+    if (this.components.length != name.components.length)
+        return false;
+    
+    // Start from the last component because they are more likely to differ.
+    for (var i = this.components.length - 1; i >= 0; --i) {
+        if (!DataUtils.arraysEqual(this.components[i], name.components[i]))
+            return false;
+    }
+    
+    return true;
+}
+
+/*
  * Find the last component in name that has a ContentDigest and return the digest value as Uint8Array, 
  *   or null if not found.
  * A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
@@ -4086,6 +4200,19 @@
     }
     return result.subarray(size - i, size);
 };
+
+/*
+ * Modify array to randomly shuffle the elements.
+ */
+DataUtils.shuffle = function(array) {
+    for (var i = array.length - 1; i >= 1; --i) {
+        // j is from 0 to i.
+        var j = Math.floor(Math.random() * (i + 1));
+        var temp = array[i];
+        array[i] = array[j];
+        array[j] = temp;
+    }
+}
 /**
  * This file contains utilities to help encode and decode NDN objects.
  * author: Meki Cheraoui
