For expressInterest, if host is null use getHostAndPort to get hosts until one connects (at the moment, only used for XPCOM).
diff --git a/js/NDN.js b/js/NDN.js
index eb67d76..e515975 100644
--- a/js/NDN.js
+++ b/js/NDN.js
@@ -9,19 +9,24 @@
 /**
  * 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');
+	this.port = (settings.port || 9696);
     this.readyStatus = NDN.UNOPEN;
     // Event handler
     this.onopen = (settings.onopen || function() { if (LOG > 3) console.log("NDN connection established."); });
@@ -64,6 +69,23 @@
 	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),
@@ -76,11 +98,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;
@@ -94,11 +111,80 @@
     }
     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;
+};
+