diff --git a/gui/html/chronoshare.js b/gui/html/chronoshare.js
index 3ceb828..c8b8ae0 100644
--- a/gui/html/chronoshare.js
+++ b/gui/html/chronoshare.js
@@ -1,65 +1,161 @@
 
-  hostip = "127.0.0.1";
-        
-  var AsyncGetClosure = function AsyncGetClosure() {
-                      Closure.call(this);
-              };
+$.Class ("FilesClosure", {}, {
+    upcall: function(kind, upcallInfo) {
+        $("#loader").fadeOut (500); // ("hidden");
+        if (kind == Closure.UPCALL_CONTENT) {
+            convertedData = DataUtils.toString (upcallInfo.contentObject.content);
+            $("#json").text (convertedData);
+            $("#json").removeClass ("hidden");
+            data = JSON.parse (convertedData);
 
-              AsyncGetClosure.prototype.upcall = function(kind, upcallInfo, tmp) {
-                      if (kind == Closure.UPCALL_FINAL) {
-                              // Do nothing.
-                      } else if (kind == Closure.UPCALL_CONTENT) {
-                              var content = upcallInfo.contentObject;
-      var nameStr = content.name.getName().split("/").slice(5,6);
-      
-      if (nameStr == "prefix") {
-        document.getElementById('prefixcontent').innerHTML = DataUtils.toString(content.content);
-        prefix();
-      } else if (nameStr == "link") {
-        document.getElementById('linkcontent').innerHTML = DataUtils.toString(content.content);
-        link();
-      } else {
-        var data = DataUtils.toString(content.content);
-        var obj = jQuery.parseJSON(data);
-        document.getElementById("lastupdated").innerHTML = obj.lastupdated;
-        document.getElementById("lastlog").innerHTML = obj.lastlog;
-        document.getElementById("lasttimestamp").innerHTML = obj.lasttimestamp;
-      }
-                      } else if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
-                              console.log("Closure.upcall called with interest time out.");
-                      }
-                      return Closure.RESULT_OK;
-              };
+            // error handling?
+            // if (data.files instanceof Array) {
+            //     alert (data.files);
+            // }
 
-              function getStatus(name) {
-    // Template interest to get the latest content.
-    var interest = new Interest("/tmp/");
-                      interest.childSelector = 1;
-                      interest.interestLifetime = 4000;
-
-                      ndn.expressInterest(new Name("/ndn/memphis.edu/netlab/status/" + name), new AsyncGetClosure(), interest);
-  }
-
-  // Calls to get the content data.
-  function begin() {
-    getStatus("metadata");
-    getStatus("prefix");
-    getStatus("link");
-  }
-
-  var ndn;
-  $(document).ready(function() {
-    $("#all").fadeIn(500);
-    var res = detect();
-
-    if (!res) {
-      $("#base").fadeOut(50);
-      $("#nosupport").fadeIn(500);
+            var html = $("tbody#files");
+            for (var i = 0; i < data.files.length; i++) {
+                file = data.files[i];
+                html = html.append ([
+                    "<tr"+(i%2?" class=\"odd\"":"")+">",
+                    "<td class=\"border-left\">" + file.filename + "</td>",
+                    "<td>" + file.version + "</td>",
+                    "<td>" + file.timestamp + "</td>",
+                    "<td class=\"border-right\">" + "</td>",
+                    "</tr>"
+                ].join());
+            }
+        }
+        else if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
+            $("#error").html ("Interest timed out");
+            $("#error").removeClass ("hidden");
+        }
+        else {
+            $("#error").html ("Unknown error happened");
+            $("#error").removeClass ("hidden");
+            // some kind of error
+        }
     }
-    else {
-      openHandle = function() { console.log("NDN established"); };
-      ndn = new NDN({host:hostip, onopen:openHandle});
-      ndn.transport.connectWebSocket(ndn);
-    }
-  });
+});
 
+
+$.Class ("ChronoShare", { },
+ {
+     init: function (username, foldername) {
+         this.username = new Name (username);
+         this.files = new Name ("/localhost").add (this.username).add ("chronoshare").add (foldername).add ("info").add ("files").add ("folder");
+
+         this.actions = new Name ("/localhost").add (this.username).add ("chronoshare").add (foldername).add ("info").add ("actions").add ("folder");
+
+         this.restore = new Name ("/localhost").add (this.username).add ("chronoshare").add (foldername).add ("cmd").add ("restore").add ("file");
+
+         this.ndn = new NDN ({host:"127.0.0.1", getHostAndPort: function() { return {host: "127.0.0.1", port: 9696}}});
+         // this.ndn.transport.connect (this.ndn);
+     },
+
+     run: function () {
+         request = new Name ().add (this.files)./*add (folder_in_question).*/add ("nonce").addSegment (0);
+         console.log (request.to_uri ());
+         $("#files").empty ();
+         // $("#loader").removeClass ("hidden");
+         $("#loader").fadeIn (500);
+         this.ndn.expressInterest (request, new FilesClosure ());
+     }
+// ,
+
+     // sendRequest: function () {
+     //     alert ('bla');
+     // }
+ });
+
+
+// $.Class ("onFiles",
+//  {
+//  },
+
+//  {
+//      upcall: function(kind, upcallInfo, tmp) {
+//          if (kind
+//      }
+//  });
+
+// var AsyncGetClosure = function AsyncGetClosure() {
+//     Closure.call(this);
+// };
+
+// AsyncGetClosure.prototype.upcall = function(kind, upcallInfo, tmp) {
+//     if (kind == Closure.UPCALL_FINAL) {
+//         // Do nothing.
+//     } else if (kind == Closure.UPCALL_CONTENT) {
+//         var content = upcallInfo.contentObject;
+// 	var nameStr = content.name.getName().split("/").slice(5,6);
+
+// 	if (nameStr == "prefix") {
+// 	    document.getElementById('prefixcontent').innerHTML = DataUtils.toString(content.content);
+// 	    prefix();
+// 	} else if (nameStr == "link") {
+// 	    document.getElementById('linkcontent').innerHTML = DataUtils.toString(content.content);
+// 	    link();
+// 	} else {
+// 	    var data = DataUtils.toString(content.content);
+// 	    var obj = jQuery.parseJSON(data);
+// 	    document.getElementById("lastupdated").innerHTML = obj.lastupdated;
+// 	    document.getElementById("lastlog").innerHTML = obj.lastlog;
+// 	    document.getElementById("lasttimestamp").innerHTML = obj.lasttimestamp;
+// 	}
+//     } else if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
+//         console.log("Closure.upcall called with interest time out.");
+//     }
+//     return Closure.RESULT_OK;
+// };
+
+// function getStatus(name) {
+//     // Template interest to get the latest content.
+//     var interest = new Interest("/tmp/");
+//     interest.childSelector = 1;
+//     interest.interestLifetime = 4000;
+
+//     ndn.expressInterest(new Name("/ndn/memphis.edu/netlab/status/" + name), new AsyncGetClosure(), interest);
+// }
+
+// // Calls to get the content data.
+// function begin() {
+//     getStatus("metadata");
+//     getStatus("prefix");
+//     getStatus("link");
+// }
+
+// var ndn;
+// $(document).ready(function() {
+//     $("#all").fadeIn(500);
+//     var res = detect();
+
+//     if (!res) {
+// 	$("#base").fadeOut(50);
+// 	$("#nosupport").fadeIn(500);
+//     } else {
+//         //$("#all").fadeIn(500);
+
+//         $.get("test.php", function() {
+// 	    openHandle = function() { begin() };
+//             ndn = new NDN({host:hostip, onopen:openHandle});
+//             ndn.transport.connectWebSocket(ndn);
+// 	    $("#base").fadeOut(500, function () {
+//                 $("#status").fadeIn(1000);
+//             });
+//         });
+//     }
+// });
+
+// $("#continue").click(function() {
+//     $("#nosupport").fadeOut(50);
+//     $("#base").fadeIn(500);
+//     $.get("test.php", function() {
+//         openHandle = function() { begin() };
+//         ndn = new NDN({host:hostip, onopen:openHandle});
+//         ndn.transport.connectWebSocket(ndn);
+//         $("#base").fadeOut(500, function () {
+//             $("#status").fadeIn(1000);
+//         });
+//     });
+// });
diff --git a/gui/html/chronoshare.png b/gui/html/chronoshare.png
new file mode 100644
index 0000000..589ff92
--- /dev/null
+++ b/gui/html/chronoshare.png
Binary files differ
diff --git a/gui/html/detect.js b/gui/html/detect.js
index 6f4fe1c..f5f0f64 100644
--- a/gui/html/detect.js
+++ b/gui/html/detect.js
@@ -18,23 +18,23 @@
         browserName = "Microsoft Internet Explorer";
         fullVersion = nAgt.substring(verOffset + 5);
     }
-    // In Chrome, the true version is after "Chrome" 
+    // In Chrome, the true version is after "Chrome"
     else if ((verOffset = nAgt.indexOf("Chrome")) != -1) {
         browserName = "Chrome";
         fullVersion = nAgt.substring(verOffset + 7);
     }
-    // In Safari, the true version is after "Safari" or after "Version" 
+    // In Safari, the true version is after "Safari" or after "Version"
     else if ((verOffset = nAgt.indexOf("Safari")) != -1) {
         browserName = "Safari";
         fullVersion = nAgt.substring(verOffset + 7);
         if ((verOffset = nAgt.indexOf("Version")) != -1) fullVersion = nAgt.substring(verOffset + 8);
     }
-    // In Firefox, the true version is after "Firefox" 
+    // In Firefox, the true version is after "Firefox"
     else if ((verOffset = nAgt.indexOf("Firefox")) != -1) {
         browserName = "Firefox";
         fullVersion = nAgt.substring(verOffset + 8);
     }
-    // In most other browsers, "name/version" is at the end of userAgent 
+    // In most other browsers, "name/version" is at the end of userAgent
     else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) {
         browserName = nAgt.substring(nameOffset, verOffset);
         fullVersion = nAgt.substring(verOffset + 1);
@@ -52,17 +52,9 @@
         majorVersion = parseInt(navigator.appVersion, 10);
     }
 
-    //document.write(''
-    // +'Browser name  = '+browserName+'<br>'
-    // +'Full version  = '+fullVersion+'<br>'
-    // +'Major version = '+majorVersion+'<br>'
-    // +'navigator.appName = '+navigator.appName+'<br>'
-    // +'navigator.userAgent = '+navigator.userAgent+'<br>'
-    //)
-
-	if (browserName == "Safari" && fullVersion == "5.1.7") {
-		return false;
-	} else {
-		return true;
-	}
+    if (browserName == "Safari" && fullVersion == "5.1.7") {
+	return false;
+    } else {
+	return true;
+    }
 }
diff --git a/gui/html/index.html b/gui/html/index.html
index 19f97ea..21842a8 100644
--- a/gui/html/index.html
+++ b/gui/html/index.html
@@ -1,97 +1,90 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta http-equiv="x-ua-compatible" content="ie=edge" />
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+    <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" />
 
-<html>  
-<head>
-  <meta charset="utf-8">
-  <title>ChronoShare</title>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>ChronoShare</title>
 
-  <!-- Load styles -->
-  <link href="http://fonts.googleapis.com/css?family=Rambla:400,700|Istok+Web:400,700" rel="stylesheet" type="text/css">
-  <link rel="stylesheet" type="text/css" href="style.css" />
+    <!-- Load styles -->
+    <link rel="stylesheet" href="style.css" type="text/css" />
+    <script type="text/javascript" src="jquery.min.js"></script>
+    <script type="text/javascript" src="jquery.class.min.js"></script>
+    <script type="text/javascript" src="ndn-js-uncomp.js"></script>
+  </head>
 
-  <style type="text/css">
-    #prefixcontent, #linkcontent, #status, #nosupport { display: none; }
-    
-    #nosupport h1 {
-      font-size: 300%;
-    }
-  
-    #nosupport {
-      text-align: center;
-      display: none;
-    }
+  <body>
+    <header>
+      <h1>ChronoShare</h1>
+      <h2 id="folderName"></h2>
 
-    #continue {
-      cursor: pointer;
-    }
-  </style>
-</head>
-
-<body>
-  <script type="text/javascript">document.write('<div id="all">');</script>
-  
-  <div id="contentwrapper">
-    <div id="header">
-      <div id="title">
-        <h1>NDN ·</span> <span id="grey">routing</span> <span id="green">status</span></h1>
-      </div>
-      <div id="navbar">
+      <nav>
         <ul>
-          <li>Shared Folder</li>
-          <li>History</li>
+          <li><a href="#files">File list</a></li>
+          <li><a href="#history">History</a></li>
         </ul>
+      </nav>
+    </header>
+
+    <article>
+      <!-- <img id="loader" src="load.gif" /> -->
+      <div id="content" class="hidden">
+
+        <table class="file-list">
+          <thead>
+            <tr>
+              <th class="filename border-left" scope="col">Filename</th>
+              <th class="version" scope="col">Version</th>
+              <th class="modified" scope="col">Modified</th>
+              <th class="modified-by border-right" scope="col">Modified By</th>
+            </tr>
+          </thead>
+
+          <tbody id="files">
+          </tbody>
+
+          <tfoot><tr><td colspan="4" class="border-right border-left"></td></tr></tfoot>
+        </table>
+
+        <div class="hidden" id="loader">
+          <img src="load.gif" />
+        </div>
+
+
+        <red class="hidden" id="error">
+        </red>
+
+        <pre class="hidden" id="json">
+        </pre>
       </div>
-    </div>
 
-    <div id="wrap">
-      <div class="titles2"><p>Advertised Prefixes:</p></div>
-      <table id="box-table-a" class="one">
-        <thead>
-          <tr>
-            <th class="border_left" scope="col">Router</th>
-            <th scope="col">Timestamp</th>
-            <th scope="col">Prefix</th>
-            <th class="border_right" scope="col">Status</th>
-          </tr>
-        </thead>
 
-        <tbody>
-        </tbody>
-    
-        <tfoot><tr><td colspan="4"></td></td></tfoot>
-      </table>
 
-    </div> <!-- "wrap" -->
+      <div id="no-support">
+        <!-- This block will be removed if jQuery has been loaded -->
+        <h1><green>Oops!</green></h1>
+        <h3><grey>It looks like you're using a browser that is <green>not supported</green>.</grey></h3>
+      </div>
+    </article>
 
-  </div> <!-- "contentwrapper" -->
+    <footer>
+      <grey>Powered by</grey><green> NDN.JS</green><grey>.<grey>
+    </footer>
 
-  <div id="leftcolumn"></div>
-  <div id="rightcolumn"></div>
+    <script src="detect.js"></script>
+    <script type="text/javascript" src="chronoshare.js"></script>
+    <script type="text/javascript">
+      $(window).ready (function () {
+         if (detect ()) {
+             $("#no-support").remove ();
+             $("#content").removeClass ("hidden");
 
-  <div id="prefixcontent"></div>
-  <div id="linkcontent"></div>
-
-  <div id="base">
-    <h3><span id="green">Generating</span><span id="grey"> & </span><span id="green">Retrieving</span><span id="grey"> Content</span></h3>
-    <img id="loader" src="load.gif" />
-    <h3><span id="grey">Powered by</span><span id="green"> NDN.JS</span><span id="grey">.</span></h3>
-  </div>
-
-  <div id="nosupport">
-    <h1><span id="green">Oops!</span></h1>
-    <h3><span id="grey">It looks like you're using a browser that is not <span id="green">supported</span>.</span></h3>
-  </div>
-
-  <script type="text/javascript">document.write('</div>');</script>
-
-  <!-- Load scripts at the bottom for efficiency -->
-  <script type="text/javascript" src="jquery.min.js"></script>
-  <script type="text/javascript" src="ndn-js.js"></script>
-  <script src="content.js"></script>
-  <script src="detect.js"></script>
-  <script type="text/javascript" src="chronoshare.js"></script>
-
-</body>
-
+             folder=new ChronoShare ("/ndn/ucla.edu/alex/macbook", "testing7");
+             folder.run ();
+         }
+      });
+    </script>
+  </body>
 </html>
-
-
diff --git a/gui/html/jquery.class.min.js b/gui/html/jquery.class.min.js
new file mode 100644
index 0000000..fae65ca
--- /dev/null
+++ b/gui/html/jquery.class.min.js
@@ -0,0 +1,7 @@
+(function(l){var j={undHash:/_|-/,colons:/::/,words:/([A-Z]+)([A-Z][a-z])/g,lowUp:/([a-z\d])([A-Z])/g,dash:/([a-z\d])([A-Z])/g,replacer:/\{([^\}]+)\}/g,dot:/\./},r=function(b,g,f){return b[g]||f&&(b[g]={})},s=function(b){return(b=typeof b)&&(b=="function"||b=="object")},q=function(b,g,f){b=b?b.split(j.dot):[];var h=b.length;g=l.isArray(g)?g:[g||window];var a,d,e,c=0;if(h==0)return g[0];for(;a=g[c++];){for(e=0;e<h-1&&s(a);e++)a=r(a,b[e],f);if(s(a)){d=r(a,b[e],f);if(d!==undefined){f===false&&delete a[b[e]];
+return d}}}},p=l.String=l.extend(l.String||{},{getObject:q,capitalize:function(b){return b.charAt(0).toUpperCase()+b.substr(1)},camelize:function(b){b=p.classize(b);return b.charAt(0).toLowerCase()+b.substr(1)},classize:function(b,g){b=b.split(j.undHash);for(var f=0;f<b.length;f++)b[f]=p.capitalize(b[f]);return b.join(g||"")},niceName:function(){p.classize(parts[i]," ")},underscore:function(b){return b.replace(j.colons,"/").replace(j.words,"$1_$2").replace(j.lowUp,"$1_$2").replace(j.dash,"_").toLowerCase()},
+sub:function(b,g,f){var h=[];h.push(b.replace(j.replacer,function(a,d){a=q(d,g,typeof f=="boolean"?!f:f);d=typeof a;if((d==="object"||d==="function")&&d!==null){h.push(a);return""}else return""+a}));return h.length<=1?h[0]:h}})})(jQuery);
+(function(l){var j=false,r=l.makeArray,s=l.isFunction,q=l.isArray,p=l.extend,b=function(a,d){return a.concat(r(d))},g=/xyz/.test(function(){})?/\b_super\b/:/.*/,f=function(a,d,e){e=e||a;for(var c in a)e[c]=s(a[c])&&s(d[c])&&g.test(a[c])?function(n,o){return function(){var m=this._super,k;this._super=d[n];k=o.apply(this,arguments);this._super=m;return k}}(c,a[c]):a[c]},h=l.Class=function(){arguments.length&&h.extend.apply(h,arguments)};p(h,{callback:function(a){var d=r(arguments),e;a=d.shift();q(a)||
+(a=[a]);e=this;return function(){for(var c=b(d,arguments),n,o=a.length,m=0,k;m<o;m++)if(k=a[m]){if((n=typeof k=="string")&&e._set_called)e.called=k;c=(n?e[k]:k).apply(e,c||[]);if(m<o-1)c=!q(c)||c._use_call?[c]:c}return c}},getObject:l.String.getObject,newInstance:function(){var a=this.rawInstance(),d;if(a.setup)d=a.setup.apply(a,arguments);if(a.init)a.init.apply(a,q(d)?d:arguments);return a},setup:function(a){this.defaults=p(true,{},a.defaults,this.defaults);return arguments},rawInstance:function(){j=
+true;var a=new this;j=false;return a},extend:function(a,d,e){function c(){if(!j)return this.constructor!==c&&arguments.length?arguments.callee.extend.apply(arguments.callee,arguments):this.Class.newInstance.apply(this.Class,arguments)}if(typeof a!="string"){e=d;d=a;a=null}if(!e){e=d;d=null}e=e||{};var n=this,o=this.prototype,m,k,t,u;j=true;u=new this;j=false;f(e,o,u);for(m in this)if(this.hasOwnProperty(m))c[m]=this[m];f(d,this,c);if(a){t=a.split(/\./);k=t.pop();t=o=h.getObject(t.join("."),window,
+true);o[k]=c}p(c,{prototype:u,namespace:t,shortName:k,constructor:c,fullName:a});c.prototype.Class=c.prototype.constructor=c;n=c.setup.apply(c,b([n],arguments));if(c.init)c.init.apply(c,n||[]);return c}});h.prototype.callback=h.callback})(jQuery);
diff --git a/gui/html/ndn-js-uncomp.js b/gui/html/ndn-js-uncomp.js
new file mode 100644
index 0000000..9116b15
--- /dev/null
+++ b/gui/html/ndn-js-uncomp.js
@@ -0,0 +1,8182 @@
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ * Provide the callback closure for the async communication methods in the NDN class.
+ * This is a port of Closure.py from PyCCN, written by: 
+ * Derek Kulinski <takeda@takeda.tk>
+ * Jeff Burke <jburke@ucla.edu>
+ */
+
+/*
+ * Create a subclass of Closure and pass an object to async calls.
+ */
+var Closure = function Closure() {
+	// I don't think storing NDN's closure is needed
+	// and it creates a reference loop, as of now both
+	// of those variables are never set -- Derek
+	//
+	// Use instance variables to return data to callback
+	this.ndn_data = null;  // this holds the ndn_closure
+    this.ndn_data_dirty = false;
+    
+};
+
+// Upcall result
+Closure.RESULT_ERR               = -1; // upcall detected an error
+Closure.RESULT_OK                =  0; // normal upcall return
+Closure.RESULT_REEXPRESS         =  1; // reexpress the same interest again
+Closure.RESULT_INTEREST_CONSUMED =  2; // upcall claims to consume interest
+Closure.RESULT_VERIFY            =  3; // force an unverified result to be verified
+Closure.RESULT_FETCHKEY          =  4; // get the key in the key locator and re-call the interest
+                                       //   with the key available in the local storage
+
+// Upcall kind
+Closure.UPCALL_FINAL              = 0; // handler is about to be deregistered
+Closure.UPCALL_INTEREST           = 1; // incoming interest
+Closure.UPCALL_CONSUMED_INTEREST  = 2; // incoming interest, someone has answered
+Closure.UPCALL_CONTENT            = 3; // incoming verified content
+Closure.UPCALL_INTEREST_TIMED_OUT = 4; // interest timed out
+Closure.UPCALL_CONTENT_UNVERIFIED = 5; // content that has not been verified
+Closure.UPCALL_CONTENT_BAD        = 6; // verification failed
+
+/*
+ * Override this in your subclass.
+ * If you're getting strange errors in upcall()
+ * check your code whether you're returning a value.
+ */
+Closure.prototype.upcall = function(kind, upcallInfo) {
+	//dump('upcall ' + this + " " + kind + " " + upcallInfo + "\n");
+	return Closure.RESULT_OK;
+};
+
+var UpcallInfo = function UpcallInfo(ndn, interest, matchedComps, contentObject) {
+	this.ndn = ndn;  // NDN object (not used)
+	this.interest = interest;  // Interest object
+	this.matchedComps = matchedComps;  // int
+	this.contentObject = contentObject;  // Content object
+};
+
+UpcallInfo.prototype.toString = function() {
+	var ret = "ndn = " + this.ndn;
+	ret += "\nInterest = " + this.interest;
+	ret += "\nmatchedComps = " + this.matchedComps;
+	ret += "\nContentObject: " + this.contentObject;
+	return ret;
+}
+/** 
+ * @author: Wentao Shang
+ * See COPYING for copyright and distribution information.
+ */
+
+var WebSocketTransport = function WebSocketTransport() {    
+    if (!WebSocket)
+        throw new Error("WebSocket support is not available on this platform.");
+    
+	this.ws = null;
+    this.connectedHost = null; // Read by NDN.
+    this.connectedPort = null; // Read by NDN.
+    this.elementReader = null;
+    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);
+};
+
+/*
+ * Connect to the host and port in ndn.  This replaces a previous connection and sets connectedHost
+ *   and connectedPort.  Once connected, call onopenCallback().
+ * Listen on the port to read an entire binary XML encoded element and call
+ *    ndn.onReceivedElement(element).
+ */
+WebSocketTransport.prototype.connect = function(ndn, onopenCallback) {
+	if (this.ws != null)
+		delete this.ws;
+	
+	this.ws = new WebSocket('ws://' + ndn.host + ':' + ndn.port);
+	if (LOG > 0) console.log('ws connection created.');
+    this.connectedHost = ndn.host;
+    this.connectedPort = ndn.port;
+	
+	this.ws.binaryType = "arraybuffer";
+	
+    this.elementReader = new BinaryXmlElementReader(ndn);
+	var self = this;
+	this.ws.onmessage = function(ev) {
+		var result = ev.data;
+		//console.log('RecvHandle called.');
+			
+		if(result == null || result == undefined || result == "" ) {
+			console.log('INVALID ANSWER');
+		} else if (result instanceof ArrayBuffer) {
+	        var bytearray = new Uint8Array(result);
+	        
+			if (LOG>3) console.log('BINARY RESPONSE IS ' + DataUtils.toHex(bytearray));
+			
+			try {
+                // Find the end of the binary XML element and call ndn.onReceivedElement.
+                self.elementReader.onReceivedData(bytearray);
+			} catch (ex) {
+				console.log("NDN.ws.onmessage exception: " + ex);
+				return;
+			}
+		}
+	}
+	
+	this.ws.onopen = function(ev) {
+		if (LOG > 3) console.log(ev);
+		if (LOG > 3) console.log('ws.onopen: WebSocket connection opened.');
+		if (LOG > 3) console.log('ws.onopen: ReadyState: ' + this.readyState);
+        // NDN.registerPrefix will fetch the ccndid when needed.
+        
+        onopenCallback();
+	}
+	
+	this.ws.onerror = function(ev) {
+		console.log('ws.onerror: ReadyState: ' + this.readyState);
+		console.log(ev);
+		console.log('ws.onerror: WebSocket error: ' + ev.data);
+	}
+	
+	this.ws.onclose = function(ev) {
+		console.log('ws.onclose: WebSocket connection closed.');
+		self.ws = null;
+		
+		// Close NDN when WebSocket is closed
+		ndn.readyStatus = NDN.CLOSED;
+		ndn.onclose();
+		//console.log("NDN.onclose event fired.");
+	}
+};
+
+/*
+ * Send the Uint8Array data.
+ */
+WebSocketTransport.prototype.send = function(data) {
+	if (this.ws != null) {
+        // If we directly use data.buffer to feed ws.send(), 
+        // WebSocket may end up sending a packet with 10000 bytes of data.
+        // That is, WebSocket will flush the entire buffer
+        // regardless of the offset of the Uint8Array. So we have to create
+        // a new Uint8Array buffer with just the right size and copy the 
+        // content from binaryInterest to the new buffer.
+        //    ---Wentao
+        var bytearray = new Uint8Array(data.length);
+        bytearray.set(data);
+        this.ws.send(bytearray.buffer);
+		if (LOG > 3) console.log('ws.send() returned.');
+	}
+	else
+		console.log('WebSocket connection is not established.');
+}
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ * This class contains all CCNx tags
+ */
+
+
+var CCNProtocolDTags = {
+
+	/**
+	 * Note if you add one of these, add it to the reverse string map as well.
+	 * Emphasize getting the work done at compile time over trying to make something
+	 * flexible and developer error-proof.
+	 */
+
+	 Any : 13,
+	 Name : 14,
+	 Component : 15,
+	 Certificate : 16,
+	 Collection : 17,
+	 CompleteName : 18,
+	 Content : 19,
+	 SignedInfo : 20,
+	 ContentDigest : 21,
+	 ContentHash : 22,
+	 Count : 24,
+	 Header : 25,
+	 Interest : 26,	/* 20090915 */
+	 Key : 27,
+	 KeyLocator : 28,
+	 KeyName : 29,
+	 Length : 30,
+	 Link : 31,
+	 LinkAuthenticator : 32,
+	 NameComponentCount : 33,	/* DeprecatedInInterest */
+	 RootDigest : 36,
+	 Signature : 37,
+	 Start : 38,
+	 Timestamp : 39,
+	 Type : 40,
+	 Nonce : 41,
+	 Scope : 42,
+	 Exclude : 43,
+	 Bloom : 44,
+	 BloomSeed : 45,
+	 AnswerOriginKind : 47,
+	 InterestLifetime : 48,
+	 Witness : 53,
+	 SignatureBits : 54,
+	 DigestAlgorithm : 55,
+	 BlockSize : 56,
+	 FreshnessSeconds : 58,
+	 FinalBlockID : 59,
+	 PublisherPublicKeyDigest : 60,
+	 PublisherCertificateDigest : 61,
+	 PublisherIssuerKeyDigest : 62,
+	 PublisherIssuerCertificateDigest : 63,
+	 ContentObject : 64,	/* 20090915 */
+	 WrappedKey : 65,
+	 WrappingKeyIdentifier : 66,
+	 WrapAlgorithm : 67,
+	 KeyAlgorithm : 68,
+	 Label : 69,
+	 EncryptedKey : 70,
+	 EncryptedNonceKey : 71,
+	 WrappingKeyName : 72,
+	 Action : 73,
+	 FaceID : 74,
+	 IPProto : 75,
+	 Host : 76,
+	 Port : 77,
+	 MulticastInterface : 78,
+	 ForwardingFlags : 79,
+	 FaceInstance : 80,
+	 ForwardingEntry : 81,
+	 MulticastTTL : 82,
+	 MinSuffixComponents : 83,
+	 MaxSuffixComponents : 84,
+	 ChildSelector : 85,
+	 RepositoryInfo : 86,
+	 Version : 87,
+	 RepositoryVersion : 88,
+	 GlobalPrefix : 89,
+	 LocalName : 90,
+	 Policy : 91,
+	 Namespace : 92,
+	 GlobalPrefixName : 93,
+	 PolicyVersion : 94,
+	 KeyValueSet : 95,
+	 KeyValuePair : 96,
+	 IntegerValue : 97,
+	 DecimalValue : 98,
+	 StringValue : 99,
+	 BinaryValue : 100,
+	 NameValue : 101,
+	 Entry : 102,
+	 ACL : 103,
+	 ParameterizedName : 104,
+	 Prefix : 105,
+	 Suffix : 106,
+	 Root : 107,
+	 ProfileName : 108,
+	 Parameters : 109,
+	 InfoString : 110,
+	// 111 unallocated
+	 StatusResponse : 112,
+	 StatusCode : 113,
+	 StatusText : 114,
+
+	// Sync protocol
+	 SyncNode : 115,
+	 SyncNodeKind : 116,
+	 SyncNodeElement : 117,
+	 SyncVersion : 118,
+	 SyncNodeElements : 119,
+	 SyncContentHash : 120,
+	 SyncLeafCount : 121,
+	 SyncTreeDepth : 122,
+	 SyncByteCount : 123,
+	 ConfigSlice : 124,
+	 ConfigSliceList : 125,
+	 ConfigSliceOp : 126,
+
+	// Remember to keep in sync with schema/tagnames.csvsdict
+	 CCNProtocolDataUnit : 17702112,
+	 CCNPROTOCOL_DATA_UNIT : "CCNProtocolDataUnit"
+};
+
+var CCNProtocolDTagsStrings = [
+	null, null, null, null, null, null, null, null, null, null, null,
+	null, null,
+	"Any", "Name", "Component", "Certificate", "Collection", "CompleteName",
+	"Content", "SignedInfo", "ContentDigest", "ContentHash", null, "Count", "Header",
+	"Interest", "Key", "KeyLocator", "KeyName", "Length", "Link", "LinkAuthenticator",
+	"NameComponentCount", null, null, "RootDigest", "Signature", "Start", "Timestamp", "Type",
+	"Nonce", "Scope", "Exclude", "Bloom", "BloomSeed", null, "AnswerOriginKind",
+	"InterestLifetime", null, null, null, null, "Witness", "SignatureBits", "DigestAlgorithm", "BlockSize",
+	null, "FreshnessSeconds", "FinalBlockID", "PublisherPublicKeyDigest", "PublisherCertificateDigest",
+	"PublisherIssuerKeyDigest", "PublisherIssuerCertificateDigest", "ContentObject",
+	"WrappedKey", "WrappingKeyIdentifier", "WrapAlgorithm", "KeyAlgorithm", "Label",
+	"EncryptedKey", "EncryptedNonceKey", "WrappingKeyName", "Action", "FaceID", "IPProto",
+	"Host", "Port", "MulticastInterface", "ForwardingFlags", "FaceInstance",
+	"ForwardingEntry", "MulticastTTL", "MinSuffixComponents", "MaxSuffixComponents", "ChildSelector",
+	"RepositoryInfo", "Version", "RepositoryVersion", "GlobalPrefix", "LocalName",
+	"Policy", "Namespace", "GlobalPrefixName", "PolicyVersion", "KeyValueSet", "KeyValuePair",
+	"IntegerValue", "DecimalValue", "StringValue", "BinaryValue", "NameValue", "Entry",
+	"ACL", "ParameterizedName", "Prefix", "Suffix", "Root", "ProfileName", "Parameters",
+	"InfoString", null,
+    "StatusResponse", "StatusCode", "StatusText", "SyncNode", "SyncNodeKind", "SyncNodeElement",
+    "SyncVersion", "SyncNodeElements", "SyncContentHash", "SyncLeafCount", "SyncTreeDepth", "SyncByteCount",
+    "ConfigSlice", "ConfigSliceList", "ConfigSliceOp" ];
+
+
+//TESTING
+//console.log(exports.CCNProtocolDTagsStrings[17]);
+
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ * This class represents CCNTime Objects
+ */
+
+var CCNTime = function CCNTime(
+                               
+		input) {
+
+
+
+
+	this.NANOS_MAX = 999877929;
+	
+	/*if(typeof input =='object'){
+		this.longDate = DataUtils.byteArrayToUnsignedLong(input);
+		this.binaryDate = input;
+	}*/
+	if(typeof input =='number'){
+		this.msec = input;
+		//this.binaryDate = DataUtils.unsignedLongToByteArray(input);
+
+	}
+	else{
+		if(LOG>1) console.log('UNRECOGNIZED TYPE FOR TIME');
+	}
+};
+
+
+CCNTime.prototype.getJavascriptDate = function(){
+	var d = new Date();
+	d.setTime( this.msec );
+	return d
+};
+
+	/**
+	 * Create a CCNTime
+	 * @param timestamp source timestamp to initialize from, some precision will be lost
+	 */
+
+
+	/**
+	 * Create a CCNTime from its binary encoding
+	 * @param binaryTime12 the binary representation of a CCNTime
+	 */
+/*CCNTime.prototype.setDateBinary = function(
+	//byte [] 
+		binaryTime12) {
+
+
+	if ((null == binaryTime12) || (binaryTime12.length == 0)) {
+		throw new IllegalArgumentException("Invalid binary time!");
+	}
+	
+
+	value = 0;
+	for(i = 0; i < binaryTime12.length; i++) {
+		value = value << 8;
+		b = (binaryTime12[i]) & 0xFF;
+		value |= b;
+	}
+
+	//this.date = new Date(value);
+
+};
+
+//byte[]
+CCNTime.prototype.toBinaryTime = function() {
+
+	return this.msec; //unsignedLongToByteArray(this.date.getTime());
+
+}*/
+/*
+unsignedLongToByteArray= function( value) {
+	if( 0 == value )
+		return [0];
+
+	if( 0 <= value && value <= 0x00FF ) {
+		//byte [] 
+		bb = new Array[1];
+		bb[0] = (value & 0x00FF);
+		return bb;
+	}
+
+	
+	//byte [] 
+	out = null;
+	//int
+	offset = -1;
+	for(var i = 7; i >=0; --i) {
+		//byte
+		b = ((value >> (i * 8)) & 0xFF);
+		if( out == null && b != 0 ) {
+			out = new Array(i+1);//byte[i+1];
+			offset = i;
+		}
+		if( out != null )
+			out[ offset - i ] = b;
+	}
+	return out;
+}*/
+	
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ * This is the closure class for use in expressInterest to re express with exponential falloff.
+ */
+
+/*
+ * Create a new ExponentialReExpressClosure where upcall responds to UPCALL_INTEREST_TIMED_OUT
+ *   by expressing the interest again with double the interestLifetime. If the interesLifetime goes
+ *   over maxInterestLifetime, then call callerClosure.upcall with UPCALL_INTEREST_TIMED_OUT.
+ * When upcall is not UPCALL_INTEREST_TIMED_OUT, just call callerClosure.upcall.
+ * 
+ * settings is an associative array with the following defaults:
+ * {
+ *   maxInterestLifetime: 16000 // milliseconds
+ * }
+ */
+var ExponentialReExpressClosure = function ExponentialReExpressClosure
+        (callerClosure, settings) {
+    // Inherit from Closure.
+    Closure.call(this);
+    
+    this.callerClosure = callerClosure;
+    settings = (settings || {});
+	this.maxInterestLifetime = (settings.maxInterestLifetime || 16000);
+};
+
+ExponentialReExpressClosure.prototype.upcall = function(kind, upcallInfo) {
+    try {
+        if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
+            var interestLifetime = upcallInfo.interest.interestLifetime;
+            if (interestLifetime == null)
+                return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, upcallInfo);
+            
+            var nextInterestLifetime = interestLifetime * 2;
+            if (nextInterestLifetime > this.maxInterestLifetime)
+                return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT, upcallInfo);
+            
+            var nextInterest = upcallInfo.interest.clone();
+            nextInterest.interestLifetime = nextInterestLifetime;
+            upcallInfo.ndn.expressInterest(nextInterest.name, this, nextInterest);
+            return Closure.RESULT_OK;
+        }  
+        else
+            return this.callerClosure.upcall(kind, upcallInfo);
+    } catch (ex) {
+        console.log("ExponentialReExpressClosure.upcall exception: " + ex);
+        return Closure.RESULT_ERR;
+    }
+};
+/**
+ * @author: Meki Cheraoui, Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ * This class represents a Name as an array of components where each is a byte array.
+ */
+
+/*
+ * Create a new Name from _components.
+ * If _components is a string, parse it as a URI.  Otherwise it is an array of components
+ * where each is a string, byte array, ArrayBuffer or Uint8Array.
+ * Convert and store as an array of Uint8Array.
+ * If a component is a string, encode as utf8.
+ */
+var Name = function Name(_components){
+	if( typeof _components == 'string') {
+		if(LOG>3)console.log('Content Name String '+_components);
+		this.components = Name.createNameArray(_components);
+	}
+	else if(typeof _components === 'object'){
+		if(LOG>4)console.log('Content Name Array '+_components);
+		this.components = [];
+        for (var i = 0; i < _components.length; ++i)
+            this.add(_components[i]);
+	}
+	else if(_components==null)
+		this.components =[];
+	else
+		if(LOG>1)console.log("NO CONTENT NAME GIVEN");
+};
+
+Name.prototype.getName = function() {
+    return this.to_uri();
+};
+
+/* Parse name as a URI and return an array of Uint8Array components.
+ *
+ */
+Name.createNameArray = function(name) {
+    name = name.trim();
+    if (name.length <= 0)
+        return [];
+
+    var iColon = name.indexOf(':');
+    if (iColon >= 0) {
+        // Make sure the colon came before a '/'.
+        var iFirstSlash = name.indexOf('/');
+        if (iFirstSlash < 0 || iColon < iFirstSlash)
+            // Omit the leading protocol such as ndn:
+            name = name.substr(iColon + 1, name.length - iColon - 1).trim();
+    }
+
+  	if (name[0] == '/') {
+        if (name.length >= 2 && name[1] == '/') {
+            // Strip the authority following "//".
+            var iAfterAuthority = name.indexOf('/', 2);
+            if (iAfterAuthority < 0)
+                // Unusual case: there was only an authority.
+                return [];
+            else
+                name = name.substr(iAfterAuthority + 1, name.length - iAfterAuthority - 1).trim();
+        }
+        else
+            name = name.substr(1, name.length - 1).trim();
+    }
+
+	var array = name.split('/');
+
+    // Unescape the components.
+    for (var i = 0; i < array.length; ++i) {
+        var component = Name.fromEscapedString(array[i]);
+
+        if (component == null) {
+            // Ignore the illegal componenent.  This also gets rid of a trailing '/'.
+            array.splice(i, 1);
+            --i;
+            continue;
+        }
+        else
+            array[i] = component;
+    }
+
+	return array;
+}
+
+
+Name.prototype.from_ccnb = function(/*XMLDecoder*/ decoder)  {
+		decoder.readStartElement(this.getElementLabel());
+
+
+		this.components = new Array(); //new ArrayList<byte []>();
+
+		while (decoder.peekStartElement(CCNProtocolDTags.Component)) {
+			this.add(decoder.readBinaryElement(CCNProtocolDTags.Component));
+		}
+
+		decoder.readEndElement();
+};
+
+Name.prototype.to_ccnb = function(/*XMLEncoder*/ encoder)  {
+
+		if( this.components ==null )
+			throw new Error("CANNOT ENCODE EMPTY CONTENT NAME");
+
+		encoder.writeStartElement(this.getElementLabel());
+		var count = this.components.length;
+		for (var i=0; i < count; i++) {
+			encoder.writeElement(CCNProtocolDTags.Component, this.components[i]);
+		}
+		encoder.writeEndElement();
+};
+
+Name.prototype.getElementLabel = function(){
+	return CCNProtocolDTags.Name;
+};
+
+/*
+ * component is a string, byte array, ArrayBuffer or Uint8Array.
+ * Convert to Uint8Array and add to this Name.
+ * If a component is a string, encode as utf8.
+ * Return the converted value.
+ */
+Name.prototype.add = function(component){
+    var result;
+    if(typeof component == 'string') {
+        result = DataUtils.stringToUtf8Array(component);
+        this.components.push (result);
+    }
+    else if(typeof component == 'object' && component instanceof Uint8Array) {
+        result = new Uint8Array(component);
+        this.components.push (result);
+    }
+    else if(typeof component == 'object' && component instanceof ArrayBuffer) {
+        // Make a copy.  Don't use ArrayBuffer.slice since it isn't always supported.
+        result = new Uint8Array(new ArrayBuffer(component.byteLength));
+        result.set(new Uint8Array(component));
+        this.components.push(result);
+    }
+    else if(typeof component == 'object' && component instanceof Name) {
+        components = component;
+        if (this == component) {
+            components = new Name (component.components); // special case, when we need to create a copy
+        }
+	for(var i = 0; i < components.components.length; ++i) {
+            result = new Uint8Array (components.components[i]);
+            this.components.push (result);
+        }
+    }
+    else if(typeof component == 'object') {
+        // Assume component is a byte array.  We can't check instanceof Array because
+        //   this doesn't work in JavaScript if the array comes from a different module.
+        result = new Uint8Array(component);
+        this.components.push(result);
+    }
+    else
+	throw new Error("Cannot add Name element at index " + this.components.length +
+                        ": Invalid type");
+
+    return this;
+};
+
+/**
+ * @brief Add component that represents a segment number
+ *
+ * @param number Segment number (integer is expected)
+ *
+ * This component has a special format handling:
+ * - if number is zero, then %00 is added
+ * - if number is between 1 and 255, %00%01 .. %00%FF is added
+ * - ...
+ */
+Name.prototype.addSegment = function(number) {
+    // step 1: figure out how many bytes will be needed
+    var bytes = 1; // at least 1 byte
+    var test_number = number;
+    while (test_number > 0) {
+        bytes ++;
+        test_number >>= 8;
+    }
+
+    var result = new Uint8Array (bytes);
+    var index = 0;
+    result[index] = 0;
+    index ++;
+    while (number > 0) {
+        result[index] = number & 0xFF;
+        number >>= 8;
+        index ++;
+    }
+
+    this.components.push(result);
+    return this;
+}
+
+// Return the escaped name string according to "CCNx URI Scheme".
+Name.prototype.to_uri = function() {
+    if (this.components.length == 0)
+        return "/";
+
+	var result = "";
+
+	for(var i = 0; i < this.components.length; ++i)
+		result += "/"+ Name.toEscapedString(this.components[i]);
+
+	return result;
+};
+
+/*
+ * Return a new Name with the first nComponents components of this Name.
+ */
+Name.prototype.getPrefix = function(nComponents) {
+    return new Name(this.components.slice(0, nComponents));
+}
+
+/*
+ * Return a new ArrayBuffer of the component at i.
+ */
+Name.prototype.getComponent = function(i) {
+    var result = new ArrayBuffer(this.components[i].length);
+    new Uint8Array(result).set(this.components[i]);
+    return result;
+}
+
+/*
+ * The "file name" in a name is the last component that isn't blank and doesn't start with one of the
+ *   special marker octets (for version, etc.).  Return the index in this.components of
+ *   the file name, or -1 if not found.
+ */
+Name.prototype.indexOfFileName = function() {
+    for (var i = this.components.length - 1; i >= 0; --i) {
+        var component = this.components[i];
+        if (component.length <= 0)
+            continue;
+
+        if (component[0] == 0 || component[0] == 0xC0 || component[0] == 0xC1 ||
+            (component[0] >= 0xF5 && component[0] <= 0xFF))
+            continue;
+
+        return i;
+    }
+
+    return -1;
+}
+
+/*
+ * 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.  See Name.getComponentContentDigestValue.
+ */
+Name.prototype.getContentDigestValue = function() {
+    for (var i = this.components.length - 1; i >= 0; --i) {
+        var digestValue = Name.getComponentContentDigestValue(this.components[i]);
+        if (digestValue != null)
+           return digestValue;
+    }
+
+    return null;
+}
+
+/*
+ * If component is a ContentDigest, return the digest value as a Uint8Array subarray (don't modify!).
+ * If not a ContentDigest, return null.
+ * A ContentDigest component is Name.ContentDigestPrefix + 32 bytes + Name.ContentDigestSuffix.
+ */
+Name.getComponentContentDigestValue = function(component) {
+    var digestComponentLength = Name.ContentDigestPrefix.length + 32 + Name.ContentDigestSuffix.length;
+    // Check for the correct length and equal ContentDigestPrefix and ContentDigestSuffix.
+    if (component.length == digestComponentLength &&
+        DataUtils.arraysEqual(component.subarray(0, Name.ContentDigestPrefix.length),
+                              Name.ContentDigestPrefix) &&
+        DataUtils.arraysEqual(component.subarray
+           (component.length - Name.ContentDigestSuffix.length, component.length),
+                              Name.ContentDigestSuffix))
+       return component.subarray(Name.ContentDigestPrefix.length, Name.ContentDigestPrefix.length + 32);
+   else
+       return null;
+}
+
+// Meta GUID "%C1.M.G%C1" + ContentDigest with a 32 byte BLOB.
+Name.ContentDigestPrefix = new Uint8Array([0xc1, 0x2e, 0x4d, 0x2e, 0x47, 0xc1, 0x01, 0xaa, 0x02, 0x85]);
+Name.ContentDigestSuffix = new Uint8Array([0x00]);
+
+/*
+ * Return component as an escaped string according to "CCNx URI Scheme".
+ * We can't use encodeURIComponent because that doesn't encode all the characters we want to.
+ */
+Name.toEscapedString = function(component) {
+    var result = "";
+    var gotNonDot = false;
+    for (var i = 0; i < component.length; ++i) {
+        if (component[i] != 0x2e) {
+            gotNonDot = true;
+            break;
+        }
+    }
+    if (!gotNonDot) {
+        // Special case for component of zero or more periods.  Add 3 periods.
+        result = "...";
+        for (var i = 0; i < component.length; ++i)
+            result += ".";
+    }
+    else {
+        for (var i = 0; i < component.length; ++i) {
+            var value = component[i];
+            // Check for 0-9, A-Z, a-z, (+), (-), (.), (_)
+            if (value >= 0x30 && value <= 0x39 || value >= 0x41 && value <= 0x5a ||
+                value >= 0x61 && value <= 0x7a || value == 0x2b || value == 0x2d ||
+                value == 0x2e || value == 0x5f)
+                result += String.fromCharCode(value);
+            else
+                result += "%" + (value < 16 ? "0" : "") + value.toString(16).toUpperCase();
+        }
+    }
+    return result;
+};
+
+/*
+ * Return component as a Uint8Array by decoding the escapedString according to "CCNx URI Scheme".
+ * If escapedString is "", "." or ".." then return null, which means to skip the component in the name.
+ */
+Name.fromEscapedString = function(escapedString) {
+    var component = unescape(escapedString.trim());
+
+    if (component.match(/[^.]/) == null) {
+        // Special case for component of only periods.
+        if (component.length <= 2)
+            // Zero, one or two periods is illegal.  Ignore this componenent to be
+            //   consistent with the C implementation.
+            return null;
+        else
+            // Remove 3 periods.
+            return DataUtils.toNumbersFromString(component.substr(3, component.length - 3));
+    }
+    else
+        return DataUtils.toNumbersFromString(component);
+}
+
+Name.prototype.match = function(/*Name*/ name) {
+	var i_name = this.components;
+	var o_name = name.components;
+
+	// The intrest name is longer than the name we are checking it against.
+	if (i_name.length > o_name.length)
+            return false;
+
+	// Check if at least one of given components doesn't match.
+    for (var i = 0; i < i_name.length; ++i) {
+        if (!DataUtils.arraysEqual(i_name[i], o_name[i]))
+            return false;
+    }
+
+	return true;
+};
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ * This class represents ContentObject Objects
+ */
+var ContentObject = function ContentObject(_name,_signedInfo,_content,_signature){
+	
+	
+	if (typeof _name == 'string') {
+		this.name = new Name(_name);
+	}
+	else{
+		//TODO Check the class of _name
+		this.name = _name;
+	}
+	this.signedInfo = _signedInfo;
+	
+	if (typeof _content == 'string') {
+		this.content = DataUtils.toNumbersFromString(_content);
+	} else {
+		this.content = _content;
+	}
+	
+	this.signature = _signature;
+
+	
+	this.startSIG = null;
+	this.endSIG = null;
+	
+	//this.startSignedInfo = null;
+	this.endContent = null;
+	
+	this.rawSignatureData = null;
+};
+
+ContentObject.prototype.sign = function(){
+
+	var n1 = this.encodeObject(this.name);
+	var n2 = this.encodeObject(this.signedInfo);
+	var n3 = this.encodeContent();
+	/*console.log('sign: ');
+	console.log(n1);
+	console.log(n2);
+	console.log(n3);*/
+	
+	//var n = n1.concat(n2,n3);
+	var tempBuf = new ArrayBuffer(n1.length + n2.length + n3.length);
+	var n = new Uint8Array(tempBuf);
+	//console.log(n);
+	n.set(n1, 0);
+	//console.log(n);
+	n.set(n2, n1.length);
+	//console.log(n);
+	n.set(n3, n1.length + n2.length);
+	//console.log(n);
+	
+	if(LOG>4)console.log('Signature Data is (binary) '+n);
+	
+	if(LOG>4)console.log('Signature Data is (RawString)');
+	
+	if(LOG>4)console.log( DataUtils.toString(n) );
+	
+	//var sig = DataUtils.toString(n);
+
+	
+	var rsa = new RSAKey();
+			
+	rsa.readPrivateKeyFromPEMString(globalKeyManager.privateKey);
+	
+	//var hSig = rsa.signString(sig, "sha256");
+
+	var hSig = rsa.signByteArrayWithSHA256(n);
+
+	
+	if(LOG>4)console.log('SIGNATURE SAVED IS');
+	
+	if(LOG>4)console.log(hSig);
+	
+	if(LOG>4)console.log(  DataUtils.toNumbers(hSig.trim()));
+
+	this.signature.signature = DataUtils.toNumbers(hSig.trim());
+	
+
+};
+
+ContentObject.prototype.encodeObject = function encodeObject(obj){
+	var enc = new BinaryXMLEncoder();
+ 
+	obj.to_ccnb(enc);
+	
+	var num = enc.getReducedOstream();
+
+	return num;
+
+	
+};
+
+ContentObject.prototype.encodeContent = function encodeContent(obj){
+	var enc = new BinaryXMLEncoder();
+	 
+	enc.writeElement(CCNProtocolDTags.Content, this.content);
+
+	var num = enc.getReducedOstream();
+
+	return num;
+
+	
+};
+
+ContentObject.prototype.saveRawData = function(bytes){
+	
+	var sigBits = bytes.subarray(this.startSIG, this.endSIG);
+
+	this.rawSignatureData = sigBits;
+};
+
+ContentObject.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
+
+	// TODO VALIDATE THAT ALL FIELDS EXCEPT SIGNATURE ARE PRESENT
+
+		decoder.readStartElement(this.getElementLabel());
+
+
+		if( decoder.peekStartElement(CCNProtocolDTags.Signature) ){
+			this.signature = new Signature();
+			this.signature.from_ccnb(decoder);
+		}
+		
+		//this.endSIG = decoder.offset;
+
+		this.startSIG = decoder.offset;
+
+		this.name = new Name();
+		this.name.from_ccnb(decoder);
+		
+		//this.startSignedInfo = decoder.offset;
+	
+		
+		if( decoder.peekStartElement(CCNProtocolDTags.SignedInfo) ){
+			this.signedInfo = new SignedInfo();
+			this.signedInfo.from_ccnb(decoder);
+		}
+		
+		this.content = decoder.readBinaryElement(CCNProtocolDTags.Content);
+
+		
+		//this.endContent = decoder.offset;
+		this.endSIG = decoder.offset;
+
+		
+		decoder.readEndElement();
+		
+		this.saveRawData(decoder.istream);
+};
+
+ContentObject.prototype.to_ccnb = function(/*XMLEncoder*/ encoder)  {
+
+	//TODO verify name, SignedInfo and Signature is present
+
+
+	encoder.writeStartElement(this.getElementLabel());
+
+	
+
+
+	if(null!=this.signature) this.signature.to_ccnb(encoder);
+	
+	
+	this.startSIG = encoder.offset;
+	
+
+	if(null!=this.name) this.name.to_ccnb(encoder);
+	
+	//this.endSIG = encoder.offset;
+	//this.startSignedInfo = encoder.offset;
+	
+	
+	if(null!=this.signedInfo) this.signedInfo.to_ccnb(encoder);
+
+	encoder.writeElement(CCNProtocolDTags.Content, this.content);
+
+	
+	this.endSIG = encoder.offset;
+	
+	//this.endContent = encoder.offset;
+	
+
+	encoder.writeEndElement();
+	
+	this.saveRawData(encoder.ostream);
+	
+};
+
+ContentObject.prototype.getElementLabel= function(){return CCNProtocolDTags.ContentObject;};
+
+/**
+ * Signature
+ */
+var Signature = function Signature(_witness,_signature,_digestAlgorithm) {
+	
+    this.Witness = _witness;//byte [] _witness;
+	this.signature = _signature;//byte [] _signature;
+	this.digestAlgorithm = _digestAlgorithm//String _digestAlgorithm;
+};
+
+Signature.prototype.from_ccnb =function( decoder) {
+		decoder.readStartElement(this.getElementLabel());
+		
+		if(LOG>4)console.log('STARTED DECODING SIGNATURE');
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
+			if(LOG>4)console.log('DIGIEST ALGORITHM FOUND');
+			this.digestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm); 
+		}
+		if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
+			if(LOG>4)console.log('WITNESS FOUND');
+			this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness); 
+		}
+		
+		//FORCE TO READ A SIGNATURE
+
+			if(LOG>4)console.log('SIGNATURE FOUND');
+			this.signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);
+
+		decoder.readEndElement();
+	
+};
+
+
+Signature.prototype.to_ccnb= function( encoder){
+    	
+	if (!this.validate()) {
+		throw new Error("Cannot encode: field values missing.");
+	}
+	
+	encoder.writeStartElement(this.getElementLabel());
+	
+	if ((null != this.digestAlgorithm) && (!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
+		encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
+	}
+	
+	if (null != this.Witness) {
+		// needs to handle null witness
+		encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
+	}
+
+	encoder.writeElement(CCNProtocolDTags.SignatureBits, this.signature);
+
+	encoder.writeEndElement();   		
+};
+
+Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
+
+
+Signature.prototype.validate = function() {
+		return null != this.signature;
+};
+
+
+/**
+ * SignedInfo
+ */
+var ContentType = {DATA:0, ENCR:1, GONE:2, KEY:3, LINK:4, NACK:5};
+var ContentTypeValue = {0:0x0C04C0, 1:0x10D091,2:0x18E344,3:0x28463F,4:0x2C834A,5:0x34008A};
+var ContentTypeValueReverse = {0x0C04C0:0, 0x10D091:1,0x18E344:2,0x28463F:3,0x2C834A:4,0x34008A:5};
+
+var SignedInfo = function SignedInfo(_publisher,_timestamp,_type,_locator,_freshnessSeconds,_finalBlockID){
+
+	//TODO, Check types
+
+    this.publisher = _publisher; //publisherPublicKeyDigest
+    this.timestamp=_timestamp; // CCN Time
+    this.type=_type; // ContentType
+    this.locator =_locator;//KeyLocator
+    this.freshnessSeconds =_freshnessSeconds; // Integer
+    this.finalBlockID=_finalBlockID; //byte array
+    
+    // SWT: merge setFields() method into constructor
+    this.setFields();
+
+};
+
+SignedInfo.prototype.setFields = function(){
+	//BASE64 -> RAW STRING
+	
+	//this.locator = new KeyLocator(  DataUtils.toNumbersFromString(stringCertificate)  ,KeyLocatorType.CERTIFICATE );
+	
+	var publicKeyHex = globalKeyManager.publicKey;
+
+	if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
+	if(LOG>4)console.log(publicKeyHex);
+	
+	var publicKeyBytes = DataUtils.toNumbers(globalKeyManager.publicKey) ; 
+
+	
+
+	//var stringCertificate = DataUtils.base64toString(globalKeyManager.certificate);
+	
+	//if(LOG>3)console.log('string Certificate is '+stringCertificate);
+
+	//HEX -> BYTE ARRAY
+	//var publisherkey = DataUtils.toNumbers(hex_sha256(stringCertificate));
+	
+	//if(LOG>3)console.log('publisher key is ');
+	//if(LOG>3)console.log(publisherkey);
+	
+	var publisherKeyDigest = hex_sha256_from_bytes(publicKeyBytes);
+
+	this.publisher = new PublisherPublicKeyDigest(  DataUtils.toNumbers(  publisherKeyDigest )  );
+	
+	//this.publisher = new PublisherPublicKeyDigest(publisherkey);
+
+	var d = new Date();
+	
+	var time = d.getTime();
+	
+
+    this.timestamp = new CCNTime( time );
+    
+    if(LOG>4)console.log('TIME msec is');
+
+    if(LOG>4)console.log(this.timestamp.msec);
+
+    //DATA
+	this.type = 0;//0x0C04C0;//ContentTypeValue[ContentType.DATA];
+	
+	//if(LOG>4)console.log('toNumbersFromString(stringCertificate) '+DataUtils.toNumbersFromString(stringCertificate));
+	
+	if(LOG>4)console.log('PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ');
+	if(LOG>4)console.log(publicKeyBytes);
+
+	this.locator = new KeyLocator(  publicKeyBytes  ,KeyLocatorType.KEY );
+
+	//this.locator = new KeyLocator(  DataUtils.toNumbersFromString(stringCertificate)  ,KeyLocatorType.CERTIFICATE );
+
+};
+
+SignedInfo.prototype.from_ccnb = function( decoder){
+
+		decoder.readStartElement( this.getElementLabel() );
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
+			if(LOG>4)console.log('DECODING PUBLISHER KEY');
+			this.publisher = new PublisherPublicKeyDigest();
+			this.publisher.from_ccnb(decoder);
+		}
+
+		if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
+			if(LOG>4)console.log('DECODING TIMESTAMP');
+			this.timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
+		}
+
+		if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
+			var binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte [] 
+		
+			
+			//TODO Implement type of Key Reading
+			
+			if(LOG>4)console.log('Binary Type of of Signed Info is '+binType);
+
+			this.type = binType;
+			
+			
+			//TODO Implement type of Key Reading
+			
+			
+			if (null == this.type) {
+				throw new Error("Cannot parse signedInfo type: bytes.");
+			}
+			
+		} else {
+			this.type = ContentType.DATA; // default
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
+			this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
+			if(LOG>4)console.log('FRESHNESS IN SECONDS IS '+ this.freshnessSeconds);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
+			if(LOG>4)console.log('DECODING FINAL BLOCKID');
+			this.finalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
+			if(LOG>4)console.log('DECODING KEY LOCATOR');
+			this.locator = new KeyLocator();
+			this.locator.from_ccnb(decoder);
+		}
+				
+		decoder.readEndElement();
+};
+
+SignedInfo.prototype.to_ccnb = function( encoder)  {
+		if (!this.validate()) {
+			throw new Error("Cannot encode : field values missing.");
+		}
+		encoder.writeStartElement(this.getElementLabel());
+		
+		if (null!=this.publisher) {
+			if(LOG>3) console.log('ENCODING PUBLISHER KEY' + this.publisher.publisherPublicKeyDigest);
+
+			this.publisher.to_ccnb(encoder);
+		}
+
+		if (null!=this.timestamp) {
+			encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.timestamp );
+		}
+		
+		if (null!=this.type && this.type !=0) {
+			
+			encoder.writeElement(CCNProtocolDTags.type, this.type);
+		}
+		
+		if (null!=this.freshnessSeconds) {
+			encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
+		}
+
+		if (null!=this.finalBlockID) {
+			encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.finalBlockID);
+		}
+
+		if (null!=this.locator) {
+			this.locator.to_ccnb(encoder);
+		}
+
+		encoder.writeEndElement();   		
+};
+	
+SignedInfo.prototype.valueToType = function(){
+	//for (Entry<byte [], ContentType> entry : ContentValueTypes.entrySet()) {
+		//if (Arrays.equals(value, entry.getKey()))
+			//return entry.getValue();
+		//}
+	return null;
+	
+};
+
+SignedInfo.prototype.getElementLabel = function() { 
+	return CCNProtocolDTags.SignedInfo;
+};
+
+SignedInfo.prototype.validate = function() {
+		// We don't do partial matches any more, even though encoder/decoder
+		// is still pretty generous.
+		if (null ==this.publisher || null==this.timestamp ||null== this.locator)
+			return false;
+		return true;
+};
+/*
+ * Date Format 1.2.3
+ * (c) 2007-2009 Steven Levithan <stevenlevithan.com>
+ * MIT license
+ *
+ * Includes enhancements by Scott Trenda <scott.trenda.net>
+ * and Kris Kowal <cixar.com/~kris.kowal/>
+ *
+ * Accepts a date, a mask, or a date and a mask.
+ * Returns a formatted version of the given date.
+ * The date defaults to the current date/time.
+ * The mask defaults to dateFormat.masks.default.
+ */
+
+var DateFormat = function () {
+	var	token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
+		timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
+		timezoneClip = /[^-+\dA-Z]/g,
+		pad = function (val, len) {
+			val = String(val);
+			len = len || 2;
+			while (val.length < len) val = "0" + val;
+			return val;
+		};
+
+	// Regexes and supporting functions are cached through closure
+	return function (date, mask, utc) {
+		var dF = dateFormat;
+
+		// You can't provide utc if you skip other args (use the "UTC:" mask prefix)
+		if (arguments.length == 1 && Object.prototype.toString.call(date) == "[object String]" && !/\d/.test(date)) {
+			mask = date;
+			date = undefined;
+		}
+
+		// Passing date through Date applies Date.parse, if necessary
+		date = date ? new Date(date) : new Date;
+		if (isNaN(date)) throw SyntaxError("invalid date");
+
+		mask = String(dF.masks[mask] || mask || dF.masks["default"]);
+
+		// Allow setting the utc argument via the mask
+		if (mask.slice(0, 4) == "UTC:") {
+			mask = mask.slice(4);
+			utc = true;
+		}
+
+		var	_ = utc ? "getUTC" : "get",
+			d = date[_ + "Date"](),
+			D = date[_ + "Day"](),
+			m = date[_ + "Month"](),
+			y = date[_ + "FullYear"](),
+			H = date[_ + "Hours"](),
+			M = date[_ + "Minutes"](),
+			s = date[_ + "Seconds"](),
+			L = date[_ + "Milliseconds"](),
+			o = utc ? 0 : date.getTimezoneOffset(),
+			flags = {
+				d:    d,
+				dd:   pad(d),
+				ddd:  dF.i18n.dayNames[D],
+				dddd: dF.i18n.dayNames[D + 7],
+				m:    m + 1,
+				mm:   pad(m + 1),
+				mmm:  dF.i18n.monthNames[m],
+				mmmm: dF.i18n.monthNames[m + 12],
+				yy:   String(y).slice(2),
+				yyyy: y,
+				h:    H % 12 || 12,
+				hh:   pad(H % 12 || 12),
+				H:    H,
+				HH:   pad(H),
+				M:    M,
+				MM:   pad(M),
+				s:    s,
+				ss:   pad(s),
+				l:    pad(L, 3),
+				L:    pad(L > 99 ? Math.round(L / 10) : L),
+				t:    H < 12 ? "a"  : "p",
+				tt:   H < 12 ? "am" : "pm",
+				T:    H < 12 ? "A"  : "P",
+				TT:   H < 12 ? "AM" : "PM",
+				Z:    utc ? "UTC" : (String(date).match(timezone) || [""]).pop().replace(timezoneClip, ""),
+				o:    (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
+				S:    ["th", "st", "nd", "rd"][d % 10 > 3 ? 0 : (d % 100 - d % 10 != 10) * d % 10]
+			};
+
+		return mask.replace(token, function ($0) {
+			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
+		});
+	};
+}();
+
+// Some common format strings
+DateFormat.masks = {
+	"default":      "ddd mmm dd yyyy HH:MM:ss",
+	shortDate:      "m/d/yy",
+	mediumDate:     "mmm d, yyyy",
+	longDate:       "mmmm d, yyyy",
+	fullDate:       "dddd, mmmm d, yyyy",
+	shortTime:      "h:MM TT",
+	mediumTime:     "h:MM:ss TT",
+	longTime:       "h:MM:ss TT Z",
+	isoDate:        "yyyy-mm-dd",
+	isoTime:        "HH:MM:ss",
+	isoDateTime:    "yyyy-mm-dd'T'HH:MM:ss",
+	isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
+};
+
+// Internationalization strings
+DateFormat.i18n = {
+	dayNames: [
+		"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
+		"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+	],
+	monthNames: [
+		"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+		"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
+	]
+};
+
+// For convenience...
+Date.prototype.format = function (mask, utc) {
+	return dateFormat(this, mask, utc);
+};
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ * This class represents Interest Objects
+ */
+
+// _interestLifetime is in milliseconds.
+var Interest = function Interest
+   (_name, _faceInstance, _minSuffixComponents, _maxSuffixComponents, _publisherPublicKeyDigest, _exclude, 
+    _childSelector, _answerOriginKind, _scope, _interestLifetime, _nonce) {
+		
+	this.name = _name;
+	this.faceInstance = _faceInstance;
+	this.maxSuffixComponents = _maxSuffixComponents;
+	this.minSuffixComponents = _minSuffixComponents;
+	
+	this.publisherPublicKeyDigest = _publisherPublicKeyDigest;
+	this.exclude = _exclude;
+	this.childSelector = _childSelector;
+	this.answerOriginKind = _answerOriginKind;
+	this.scope = _scope;
+	this.interestLifetime = _interestLifetime;  // milli seconds
+	this.nonce = _nonce;	
+};
+
+Interest.RECURSIVE_POSTFIX = "*";
+
+Interest.CHILD_SELECTOR_LEFT = 0;
+Interest.CHILD_SELECTOR_RIGHT = 1;
+Interest.ANSWER_CONTENT_STORE = 1;
+Interest.ANSWER_GENERATED = 2;
+Interest.ANSWER_STALE = 4;		// Stale answer OK
+Interest.MARK_STALE = 16;		// Must have scope 0.  Michael calls this a "hack"
+
+Interest.DEFAULT_ANSWER_ORIGIN_KIND = Interest.ANSWER_CONTENT_STORE | Interest.ANSWER_GENERATED;
+
+
+Interest.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
+
+		decoder.readStartElement(CCNProtocolDTags.Interest);
+
+		this.name = new Name();
+		this.name.from_ccnb(decoder);
+
+		if (decoder.peekStartElement(CCNProtocolDTags.MinSuffixComponents))
+			this.minSuffixComponents = decoder.readIntegerElement(CCNProtocolDTags.MinSuffixComponents);
+
+		if (decoder.peekStartElement(CCNProtocolDTags.MaxSuffixComponents)) 
+			this.maxSuffixComponents = decoder.readIntegerElement(CCNProtocolDTags.MaxSuffixComponents);
+			
+		if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
+			this.publisherPublicKeyDigest = new PublisherPublicKeyDigest();
+			this.publisherPublicKeyDigest.from_ccnb(decoder);
+		}
+
+		if (decoder.peekStartElement(CCNProtocolDTags.Exclude)) {
+			this.exclude = new Exclude();
+			this.exclude.from_ccnb(decoder);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.ChildSelector))
+			this.childSelector = decoder.readIntegerElement(CCNProtocolDTags.ChildSelector);
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.AnswerOriginKind))
+			this.answerOriginKind = decoder.readIntegerElement(CCNProtocolDTags.AnswerOriginKind);
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.Scope))
+			this.scope = decoder.readIntegerElement(CCNProtocolDTags.Scope);
+
+		if (decoder.peekStartElement(CCNProtocolDTags.InterestLifetime))
+			this.interestLifetime = 1000.0 * DataUtils.bigEndianToUnsignedInt
+                (decoder.readBinaryElement(CCNProtocolDTags.InterestLifetime)) / 4096;
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.Nonce))
+			this.nonce = decoder.readBinaryElement(CCNProtocolDTags.Nonce);
+		
+		decoder.readEndElement();
+};
+
+Interest.prototype.to_ccnb = function(/*XMLEncoder*/ encoder){
+		//Could check if name is present
+		
+		encoder.writeStartElement(CCNProtocolDTags.Interest);
+		
+		this.name.to_ccnb(encoder);
+	
+		if (null != this.minSuffixComponents) 
+			encoder.writeElement(CCNProtocolDTags.MinSuffixComponents, this.minSuffixComponents);	
+
+		if (null != this.maxSuffixComponents) 
+			encoder.writeElement(CCNProtocolDTags.MaxSuffixComponents, this.maxSuffixComponents);
+
+		if (null != this.publisherPublicKeyDigest)
+			this.publisherPublicKeyDigest.to_ccnb(encoder);
+		
+		if (null != this.exclude)
+			this.exclude.to_ccnb(encoder);
+		
+		if (null != this.childSelector) 
+			encoder.writeElement(CCNProtocolDTags.ChildSelector, this.childSelector);
+
+		if (this.DEFAULT_ANSWER_ORIGIN_KIND != this.answerOriginKind && this.answerOriginKind!=null) 
+			encoder.writeElement(CCNProtocolDTags.AnswerOriginKind, this.answerOriginKind);
+		
+		if (null != this.scope) 
+			encoder.writeElement(CCNProtocolDTags.Scope, this.scope);
+		
+		if (null != this.interestLifetime) 
+			encoder.writeElement(CCNProtocolDTags.InterestLifetime, 
+                DataUtils.nonNegativeIntToBigEndian((this.interestLifetime / 1000.0) * 4096));
+		
+		if (null != this.nonce)
+			encoder.writeElement(CCNProtocolDTags.Nonce, this.nonce);
+		
+		encoder.writeEndElement();
+
+};
+
+/*
+ * Return true if this.name.match(name) and the name conforms to the interest selectors.
+ */
+Interest.prototype.matches_name = function(/*Name*/ name) {
+    if (!this.name.match(name))
+        return false;
+    
+    if (this.minSuffixComponents != null &&
+        // Add 1 for the implicit digest.
+        !(name.components.length + 1 - this.name.components.length >= this.minSuffixComponents))
+        return false;
+    if (this.maxSuffixComponents != null &&
+        // Add 1 for the implicit digest.
+        !(name.components.length + 1 - this.name.components.length <= this.maxSuffixComponents))
+        return false;
+    if (this.exclude != null && name.components.length > this.name.components.length &&
+        this.exclude.matches(name.components[this.name.components.length]))
+        return false;
+    
+    return true;
+};
+
+/*
+ * Return a new Interest with the same fields as this Interest.  
+ * Note: This does NOT make a deep clone of the name, exclue or other objects.
+ */
+Interest.prototype.clone = function() {
+    return new Interest
+       (this.name, this.faceInstance, this.minSuffixComponents, this.maxSuffixComponents, 
+        this.publisherPublicKeyDigest, this.exclude, this.childSelector, this.answerOriginKind, 
+        this.scope, this.interestLifetime, this.nonce);
+};
+
+/*
+ * Handle the interest Exclude element.
+ * _values is an array where each element is either Uint8Array component or Exclude.ANY.
+ */
+var Exclude = function Exclude(_values) { 
+	this.values = (_values || []);
+}
+
+Exclude.ANY = "*";
+
+Exclude.prototype.from_ccnb = function(/*XMLDecoder*/ decoder) {
+	decoder.readStartElement(CCNProtocolDTags.Exclude);
+
+	while (true) {
+        if (decoder.peekStartElement(CCNProtocolDTags.Component))
+            this.values.push(decoder.readBinaryElement(CCNProtocolDTags.Component));
+        else if (decoder.peekStartElement(CCNProtocolDTags.Any)) {
+            decoder.readStartElement(CCNProtocolDTags.Any);
+            decoder.readEndElement();
+            this.values.push(Exclude.ANY);
+        }
+        else if (decoder.peekStartElement(CCNProtocolDTags.Bloom)) {
+            // Skip the Bloom and treat it as Any.
+            decoder.readBinaryElement(CCNProtocolDTags.Bloom);
+            this.values.push(Exclude.ANY);
+        }
+        else
+            break;
+	}
+    
+    decoder.readEndElement();
+};
+
+Exclude.prototype.to_ccnb = function(/*XMLEncoder*/ encoder)  {
+	if (this.values == null || this.values.length == 0)
+		return;
+
+	encoder.writeStartElement(CCNProtocolDTags.Exclude);
+    
+    // TODO: Do we want to order the components (except for ANY)?
+    for (var i = 0; i < this.values.length; ++i) {
+        if (this.values[i] == Exclude.ANY) {
+            encoder.writeStartElement(CCNProtocolDTags.Any);
+            encoder.writeEndElement();
+        }
+        else
+            encoder.writeElement(CCNProtocolDTags.Component, this.values[i]);
+    }
+
+	encoder.writeEndElement();
+};
+
+/*
+ * Return a string with elements separated by "," and Exclude.ANY shown as "*". 
+ */
+Exclude.prototype.to_uri = function() {
+	if (this.values == null || this.values.length == 0)
+		return "";
+
+    var result = "";
+    for (var i = 0; i < this.values.length; ++i) {
+        if (i > 0)
+            result += ",";
+        
+        if (this.values[i] == Exclude.ANY)
+            result += "*";
+        else
+            result += Name.toEscapedString(this.values[i]);
+    }
+    return result;
+};
+
+/*
+ * Return true if the component matches any of the exclude criteria.
+ */
+Exclude.prototype.matches = function(/*Uint8Array*/ component) {
+    for (var i = 0; i < this.values.length; ++i) {
+        if (this.values[i] == Exclude.ANY) {
+            var lowerBound = null;
+            if (i > 0)
+                lowerBound = this.values[i - 1];
+            
+            // Find the upper bound, possibly skipping over multiple ANY in a row.
+            var iUpperBound;
+            var upperBound = null;
+            for (iUpperBound = i + 1; iUpperBound < this.values.length; ++iUpperBound) {
+                if (this.values[iUpperBound] != Exclude.ANY) {
+                    upperBound = this.values[iUpperBound];
+                    break;
+                }
+            }
+            
+            // If lowerBound != null, we already checked component equals lowerBound on the last pass.
+            // If upperBound != null, we will check component equals upperBound on the next pass.
+            if (upperBound != null) {
+                if (lowerBound != null) {
+                    if (Exclude.compareComponents(component, lowerBound) > 0 &&
+                        Exclude.compareComponents(component, upperBound) < 0)
+                        return true;
+                }
+                else {
+                    if (Exclude.compareComponents(component, upperBound) < 0)
+                        return true;
+                }
+                
+                // Make i equal iUpperBound on the next pass.
+                i = iUpperBound - 1;
+            }
+            else {
+                if (lowerBound != null) {
+                    if (Exclude.compareComponents(component, lowerBound) > 0)
+                        return true;
+                }
+                else
+                    // this.values has only ANY.
+                    return true;
+            }
+        }
+        else {
+            if (DataUtils.arraysEqual(component, this.values[i]))
+                return true;
+        }
+    }
+    
+    return false;
+};
+
+/*
+ * Return -1 if component1 is less than component2, 1 if greater or 0 if equal.
+ * A component is less if it is shorter, otherwise if equal length do a byte comparison.
+ */
+Exclude.compareComponents = function(/*Uint8Array*/ component1, /*Uint8Array*/ component2) {
+    if (component1.length < component2.length)
+        return -1;
+    if (component1.length > component2.length)
+        return 1;
+    
+    for (var i = 0; i < component1.length; ++i) {
+        if (component1[i] < component2[i])
+            return -1;
+        if (component1[i] > component2[i])
+            return 1;
+    }
+
+    return 0;
+};
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ * This class represents Key Objects
+ */
+
+var Key = function Key(){
+    /* TODO: Port from PyCCN:
+	generateRSA()
+	privateToDER()
+	publicToDER()
+	privateToPEM()
+	publicToPEM()
+	fromDER()
+	fromPEM()
+     */
+}
+
+/**
+ * KeyLocator
+ */
+var KeyLocatorType = {
+	KEY:1,
+	CERTIFICATE:2,
+	KEYNAME:3
+};
+
+var KeyLocator = function KeyLocator(_input,_type){ 
+
+    this.type = _type;
+    
+    if (_type == KeyLocatorType.KEYNAME){
+    	if (LOG>3) console.log('KeyLocator: SET KEYNAME');
+    	this.keyName = _input;
+    }
+    else if (_type == KeyLocatorType.KEY){
+    	if (LOG>3) console.log('KeyLocator: SET KEY');
+    	this.publicKey = _input;
+    }
+    else if (_type == KeyLocatorType.CERTIFICATE){
+    	if (LOG>3) console.log('KeyLocator: SET CERTIFICATE');
+    	this.certificate = _input;
+    }
+
+};
+
+KeyLocator.prototype.from_ccnb = function(decoder) {
+
+	decoder.readStartElement(this.getElementLabel());
+
+	if (decoder.peekStartElement(CCNProtocolDTags.Key)) {
+		try {
+			var encodedKey = decoder.readBinaryElement(CCNProtocolDTags.Key);
+			// This is a DER-encoded SubjectPublicKeyInfo.
+			
+			//TODO FIX THIS, This should create a Key Object instead of keeping bytes
+
+			this.publicKey =   encodedKey;//CryptoUtil.getPublicKey(encodedKey);
+			this.type = KeyLocatorType.KEY;
+			
+
+			if(LOG>4) console.log('PUBLIC KEY FOUND: '+ this.publicKey);
+			//this.publicKey = encodedKey;
+			
+			
+		} catch (e) {
+			throw new Error("Cannot parse key: ", e);
+		} 
+
+		if (null == this.publicKey) {
+			throw new Error("Cannot parse key: ");
+		}
+
+	} else if ( decoder.peekStartElement(CCNProtocolDTags.Certificate)) {
+		try {
+			var encodedCert = decoder.readBinaryElement(CCNProtocolDTags.Certificate);
+			
+			/*
+			 * Certificates not yet working
+			 */
+			
+			//CertificateFactory factory = CertificateFactory.getInstance("X.509");
+			//this.certificate = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(encodedCert));
+			
+
+			this.certificate = encodedCert;
+			this.type = KeyLocatorType.CERTIFICATE;
+
+			if(LOG>4) console.log('CERTIFICATE FOUND: '+ this.certificate);
+			
+		} catch ( e) {
+			throw new Error("Cannot decode certificate: " +  e);
+		}
+		if (null == this.certificate) {
+			throw new Error("Cannot parse certificate! ");
+		}
+	} else  {
+		this.type = KeyLocatorType.KEYNAME;
+		
+		this.keyName = new KeyName();
+		this.keyName.from_ccnb(decoder);
+	}
+	decoder.readEndElement();
+};
+	
+
+KeyLocator.prototype.to_ccnb = function( encoder) {
+	
+	if(LOG>4) console.log('type is is ' + this.type);
+	//TODO Check if Name is missing
+	if (!this.validate()) {
+		throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
+	}
+
+	
+	//TODO FIX THIS TOO
+	encoder.writeStartElement(this.getElementLabel());
+	
+	if (this.type == KeyLocatorType.KEY) {
+		if(LOG>5)console.log('About to encode a public key' +this.publicKey);
+		encoder.writeElement(CCNProtocolDTags.Key, this.publicKey);
+		
+	} else if (this.type == KeyLocatorType.CERTIFICATE) {
+		
+		try {
+			encoder.writeElement(CCNProtocolDTags.Certificate, this.certificate);
+		} catch ( e) {
+			throw new Error("CertificateEncodingException attempting to write key locator: " + e);
+		}
+		
+	} else if (this.type == KeyLocatorType.KEYNAME) {
+		
+		this.keyName.to_ccnb(encoder);
+	}
+	encoder.writeEndElement();
+	
+};
+
+KeyLocator.prototype.getElementLabel = function() {
+	return CCNProtocolDTags.KeyLocator; 
+};
+
+KeyLocator.prototype.validate = function() {
+	return (  (null != this.keyName) || (null != this.publicKey) || (null != this.certificate)   );
+};
+
+/**
+ * KeyName is only used by KeyLocator.
+ */
+var KeyName = function KeyName() {
+	this.contentName = this.contentName;  //contentName
+	this.publisherID = this.publisherID;  //publisherID
+
+};
+
+KeyName.prototype.from_ccnb=function( decoder){
+	
+
+	decoder.readStartElement(this.getElementLabel());
+
+	this.contentName = new Name();
+	this.contentName.from_ccnb(decoder);
+	
+	if(LOG>4) console.log('KEY NAME FOUND: ');
+	
+	if ( PublisherID.peek(decoder) ) {
+		this.publisherID = new PublisherID();
+		this.publisherID.from_ccnb(decoder);
+	}
+	
+	decoder.readEndElement();
+};
+
+KeyName.prototype.to_ccnb = function( encoder) {
+	if (!this.validate()) {
+		throw new Error("Cannot encode : field values missing.");
+	}
+	
+	encoder.writeStartElement(this.getElementLabel());
+	
+	this.contentName.to_ccnb(encoder);
+	if (null != this.publisherID)
+		this.publisherID.to_ccnb(encoder);
+
+	encoder.writeEndElement();   		
+};
+	
+KeyName.prototype.getElementLabel = function() { return CCNProtocolDTags.KeyName; };
+
+KeyName.prototype.validate = function() {
+		// DKS -- do we do recursive validation?
+		// null signedInfo ok
+		return (null != this.contentName);
+};
+
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ * This class represents Publisher and PublisherType Objects
+ */
+
+
+var PublisherType = function PublisherType(_tag){
+    	this.KEY =(CCNProtocolDTags.PublisherPublicKeyDigest);
+    	this.CERTIFICATE= (CCNProtocolDTags.PublisherCertificateDigest);
+    	this.ISSUER_KEY=	(CCNProtocolDTags.PublisherIssuerKeyDigest);
+    	this.ISSUER_CERTIFICATE	=(CCNProtocolDTags.PublisherIssuerCertificateDigest);
+
+    	this.Tag = _tag;
+}; 
+
+var isTypeTagVal = function(tagVal) {
+		if ((tagVal == CCNProtocolDTags.PublisherPublicKeyDigest) ||
+			(tagVal == CCNProtocolDTags.PublisherCertificateDigest) ||
+			(tagVal == CCNProtocolDTags.PublisherIssuerKeyDigest) ||
+			(tagVal == CCNProtocolDTags.PublisherIssuerCertificateDigest)) {
+			return true;
+		}
+		return false;
+};
+
+
+
+
+var PublisherID = function PublisherID() {
+
+	this.PUBLISHER_ID_DIGEST_ALGORITHM = "SHA-256";
+	this.PUBLISHER_ID_LEN = 256/8;
+    
+	//TODO, implement publisherID creation and key creation
+
+    //TODO implement generatePublicKeyDigest
+    this.publisherID =null;//= generatePublicKeyDigest(key);//ByteArray
+    
+    //TODO implement generate key
+    //CryptoUtil.generateKeyID(PUBLISHER_ID_DIGEST_ALGORITHM, key);
+    this.publisherType = null;//isIssuer ? PublisherType.ISSUER_KEY : PublisherType.KEY;//publisher Type
+    
+};
+
+
+PublisherID.prototype.from_ccnb = function(decoder) {
+		
+		// We have a choice here of one of 4 binary element types.
+		var nextTag = decoder.peekStartElementAsLong();
+		
+		if (null == nextTag) {
+			throw new Error("Cannot parse publisher ID.");
+		} 
+		
+		this.publisherType = new PublisherType(nextTag); 
+		
+		if (!isTypeTagVal(nextTag)) {
+			throw new Error("Invalid publisher ID, got unexpected type: " + nextTag);
+		}
+		this.publisherID = decoder.readBinaryElement(nextTag);
+		if (null == this.publisherID) {
+			throw new ContentDecodingException(new Error("Cannot parse publisher ID of type : " + nextTag + "."));
+		}
+};
+
+PublisherID.prototype.to_ccnb = function(encoder) {
+	if (!this.validate()) {
+		throw new Error("Cannot encode " + this.getClass().getName() + ": field values missing.");
+	}
+
+	encoder.writeElement(this.getElementLabel(), this.publisherID);
+};
+	
+PublisherID.peek = function(/* XMLDecoder */ decoder) {
+
+		//Long
+		var nextTag = decoder.peekStartElementAsLong();
+		
+		if (null == nextTag) {
+			// on end element
+			return false;
+		}
+		return (isTypeTagVal(nextTag));
+	};
+
+PublisherID.prototype.getElementLabel = function() { 
+	return this.publisherType.Tag;
+};
+
+PublisherID.prototype.validate = function(){
+	return ((null != id() && (null != type())));
+};
+
+
+
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ * This class represents PublisherPublicKeyDigest Objects
+ */
+var PublisherPublicKeyDigest = function PublisherPublicKeyDigest(_pkd){ 
+	
+ 	 //this.PUBLISHER_ID_LEN = 256/8;
+	 this.PUBLISHER_ID_LEN = 512/8;
+ 	 
+
+	 this.publisherPublicKeyDigest = _pkd;
+ 	 //if( typeof _pkd == "object") this.publisherPublicKeyDigest = _pkd; // Byte Array
+ 	 //else if( typeof _pkd == "PublicKey") ;//TODO...
+    
+};
+
+PublisherPublicKeyDigest.prototype.from_ccnb = function( decoder) {		
+
+		this.publisherPublicKeyDigest = decoder.readBinaryElement(this.getElementLabel());
+		
+		if(LOG>4)console.log('Publisher public key digest is ' + this.publisherPublicKeyDigest);
+
+		if (null == this.publisherPublicKeyDigest) {
+			throw new Error("Cannot parse publisher key digest.");
+		}
+		
+		//TODO check if the length of the PublisherPublicKeyDigest is correct ( Security reason)
+
+		if (this.publisherPublicKeyDigest.length != this.PUBLISHER_ID_LEN) {
+			if (LOG > 0)
+                console.log('LENGTH OF PUBLISHER ID IS WRONG! Expected ' + this.PUBLISHER_ID_LEN + ", got " + this.publisherPublicKeyDigest.length);
+			
+			//this.publisherPublicKeyDigest = new PublisherPublicKeyDigest(this.PublisherPublicKeyDigest).PublisherKeyDigest;		
+		}
+	};
+
+PublisherPublicKeyDigest.prototype.to_ccnb= function( encoder) {
+		//TODO Check that the ByteArray for the key is present
+		if (!this.validate()) {
+			throw new Error("Cannot encode : field values missing.");
+		}
+		if(LOG>3) console.log('PUBLISHER KEY DIGEST IS'+this.publisherPublicKeyDigest);
+		encoder.writeElement(this.getElementLabel(), this.publisherPublicKeyDigest);
+};
+	
+PublisherPublicKeyDigest.prototype.getElementLabel = function() { return CCNProtocolDTags.PublisherPublicKeyDigest; };
+
+PublisherPublicKeyDigest.prototype.validate =function() {
+		return (null != this.publisherPublicKeyDigest);
+};
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ * This class represents Face Instances
+ */
+
+var NetworkProtocol = { TCP:6, UDP:17};
+
+var FaceInstance  = function FaceInstance(
+	    _action,
+		_publisherPublicKeyDigest,
+		_faceID,
+		_ipProto,
+		_host,
+		_port,
+		_multicastInterface,
+		_multicastTTL,
+		_freshnessSeconds){
+	
+
+	this.action = _action;
+	this.publisherPublicKeyDigest = _publisherPublicKeyDigest;
+	this.faceID = _faceID;
+	this.ipProto = _ipProto;
+	this.host = _host;
+	this.Port = _port;
+	this.multicastInterface =_multicastInterface;
+	this.multicastTTL =_multicastTTL;
+	this.freshnessSeconds = _freshnessSeconds;
+	
+	//action           ::= ("newface" | "destroyface" | "queryface")
+	//publisherPublicKeyDigest ::= SHA-256 digest
+	//faceID           ::= nonNegativeInteger
+	//ipProto          ::= nonNegativeInteger [IANA protocol number, 6=TCP, 17=UDP]
+	//Host             ::= textual representation of numeric IPv4 or IPv6 address
+	//Port             ::= nonNegativeInteger [1..65535]
+	//MulticastInterface ::= textual representation of numeric IPv4 or IPv6 address
+	//MulticastTTL     ::= nonNegativeInteger [1..255]
+	//freshnessSeconds ::= nonNegativeInteger
+
+};
+
+/**
+ * Used by NetworkObject to decode the object from a network stream.
+ */
+FaceInstance.prototype.from_ccnb = function(//XMLDecoder 
+	decoder) {
+
+	decoder.readStartElement(this.getElementLabel());
+	
+	if (decoder.peekStartElement(CCNProtocolDTags.Action)) {
+		
+		this.action = decoder.readUTF8Element(CCNProtocolDTags.Action);
+		
+	}
+	if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
+		
+		this.publisherPublicKeyDigest = new PublisherPublicKeyDigest();
+		this.publisherPublicKeyDigest.from_ccnb(decoder);
+		
+	}
+	if (decoder.peekStartElement(CCNProtocolDTags.FaceID)) {
+		
+		this.faceID = decoder.readIntegerElement(CCNProtocolDTags.FaceID);
+		
+	}
+	if (decoder.peekStartElement(CCNProtocolDTags.IPProto)) {
+		
+		//int
+		var pI = decoder.readIntegerElement(CCNProtocolDTags.IPProto);
+		
+		this.ipProto = null;
+		
+		if (NetworkProtocol.TCP == pI) {
+			
+			this.ipProto = NetworkProtocol.TCP;
+			
+		} else if (NetworkProtocol.UDP == pI) {
+			
+			this.ipProto = NetworkProtocol.UDP;
+			
+		} else {
+			
+			throw new Error("FaceInstance.decoder.  Invalid " + 
+					CCNProtocolDTags.tagToString(CCNProtocolDTags.IPProto) + " field: " + pI);
+			
+		}
+	}
+	
+	if (decoder.peekStartElement(CCNProtocolDTags.Host)) {
+		
+		this.host = decoder.readUTF8Element(CCNProtocolDTags.Host);
+		
+	}
+	
+	if (decoder.peekStartElement(CCNProtocolDTags.Port)) {
+		this.Port = decoder.readIntegerElement(CCNProtocolDTags.Port); 
+	}
+	
+	if (decoder.peekStartElement(CCNProtocolDTags.MulticastInterface)) {
+		this.multicastInterface = decoder.readUTF8Element(CCNProtocolDTags.MulticastInterface); 
+	}
+	
+	if (decoder.peekStartElement(CCNProtocolDTags.MulticastTTL)) {
+		this.multicastTTL = decoder.readIntegerElement(CCNProtocolDTags.MulticastTTL); 
+	}
+	
+	if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
+		this.freshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds); 
+	}
+	decoder.readEndElement();
+}
+
+/**
+ * Used by NetworkObject to encode the object to a network stream.
+ */
+FaceInstance.prototype.to_ccnb = function(//XMLEncoder
+	encoder){
+
+	//if (!this.validate()) {
+		//throw new Error("Cannot encode : field values missing.");
+		//throw new Error("")
+	//}
+	encoder.writeStartElement(this.getElementLabel());
+	
+	if (null != this.action && this.action.length != 0)
+		encoder.writeElement(CCNProtocolDTags.Action, this.action);	
+	
+	if (null != this.publisherPublicKeyDigest) {
+		this.publisherPublicKeyDigest.to_ccnb(encoder);
+	}
+	if (null != this.faceID) {
+		encoder.writeElement(CCNProtocolDTags.FaceID, this.faceID);
+	}
+	if (null != this.ipProto) {
+		//encoder.writeElement(CCNProtocolDTags.IPProto, this.IpProto.value());
+		encoder.writeElement(CCNProtocolDTags.IPProto, this.ipProto);
+	}
+	if (null != this.host && this.host.length != 0) {
+		encoder.writeElement(CCNProtocolDTags.Host, this.host);	
+	}
+	if (null != this.Port) {
+		encoder.writeElement(CCNProtocolDTags.Port, this.Port);
+	}
+	if (null != this.multicastInterface && this.multicastInterface.length != 0) {
+		encoder.writeElement(CCNProtocolDTags.MulticastInterface, this.multicastInterface);
+	}
+	if (null !=  this.multicastTTL) {
+		encoder.writeElement(CCNProtocolDTags.MulticastTTL, this.multicastTTL);
+	}
+	if (null != this.freshnessSeconds) {
+		encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.freshnessSeconds);
+	}
+	encoder.writeEndElement();   			
+}
+
+
+FaceInstance.prototype.getElementLabel= function(){return CCNProtocolDTags.FaceInstance;};
+
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ * This class represents Forwarding Entries
+ */
+
+var ForwardingEntry = function ForwardingEntry(
+                                               //ActionType 
+		_action, 
+		//Name 
+		_prefixName, 
+		//PublisherPublicKeyDigest
+		_ccndId, 
+		//Integer 
+		_faceID, 
+		//Integer 
+		_flags, 
+		//Integer 
+		_lifetime){
+		
+		
+	
+		//String
+	this.action = _action;
+		//Name\
+	this.prefixName = _prefixName;
+		//PublisherPublicKeyDigest 
+	this.ccndID = _ccndId;
+		//Integer		
+	this.faceID = _faceID;
+		//Integer		
+	this.flags = _flags;
+		//Integer 		
+	this.lifetime = _lifetime;  // in seconds
+
+};
+
+ForwardingEntry.prototype.from_ccnb =function(
+	//XMLDecoder 
+	decoder) 
+	//throws ContentDecodingException
+	{
+			decoder.readStartElement(this.getElementLabel());
+			if (decoder.peekStartElement(CCNProtocolDTags.Action)) {
+				this.action = decoder.readUTF8Element(CCNProtocolDTags.Action); 
+			}
+			if (decoder.peekStartElement(CCNProtocolDTags.Name)) {
+				this.prefixName = new Name();
+				this.prefixName.from_ccnb(decoder) ;
+			}
+			if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
+				this.CcndId = new PublisherPublicKeyDigest();
+				this.CcndId.from_ccnb(decoder);
+			}
+			if (decoder.peekStartElement(CCNProtocolDTags.FaceID)) {
+				this.faceID = decoder.readIntegerElement(CCNProtocolDTags.FaceID); 
+			}
+			if (decoder.peekStartElement(CCNProtocolDTags.ForwardingFlags)) {
+				this.flags = decoder.readIntegerElement(CCNProtocolDTags.ForwardingFlags); 
+			}
+			if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
+				this.lifetime = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds); 
+			}
+			decoder.readEndElement();
+		};
+
+		/**
+		 * Used by NetworkObject to encode the object to a network stream.
+		 */
+ForwardingEntry.prototype.to_ccnb =function(
+	//XMLEncoder 
+encoder) 
+{
+
+
+			//if (!validate()) {
+				//throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
+			//}
+			encoder.writeStartElement(this.getElementLabel());
+			if (null != this.action && this.action.length != 0)
+				encoder.writeElement(CCNProtocolDTags.Action, this.action);	
+			if (null != this.prefixName) {
+				this.prefixName.to_ccnb(encoder);
+			}
+			if (null != this.CcndId) {
+				this.CcndId.to_ccnb(encoder);
+			}
+			if (null != this.faceID) {
+				encoder.writeElement(CCNProtocolDTags.FaceID, this.faceID);
+			}
+			if (null != this.flags) {
+				encoder.writeElement(CCNProtocolDTags.ForwardingFlags, this.flags);
+			}
+			if (null != this.lifetime) {
+				encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.lifetime);
+			}
+			encoder.writeEndElement();   			
+		};
+
+ForwardingEntry.prototype.getElementLabel = function() { return CCNProtocolDTags.ForwardingEntry; }
+/**
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ * Encapsulate an Uint8Array and support dynamic reallocation.
+ */
+
+/*
+ * Create a DynamicUint8Array where this.array is a Uint8Array of size length.
+ * If length is not supplied, use a default initial length.
+ * The methods will update this.length.
+ * To access the array, use this.array or call subarray.
+ */
+var DynamicUint8Array = function DynamicUint8Array(length) {
+	if (!length)
+        length = 16;
+    
+    this.array = new Uint8Array(length);
+    this.length = length;
+};
+
+/*
+ * Ensure that this.array has the length, reallocate and copy if necessary.
+ * Update this.length which may be greater than length.
+ */
+DynamicUint8Array.prototype.ensureLength = function(length) {
+    if (this.array.length >= length)
+        return;
+    
+    // See if double is enough.
+    var newLength = this.array.length * 2;
+    if (length > newLength)
+        // The needed length is much greater, so use it.
+        newLength = length;
+    
+    var newArray = new Uint8Array(newLength);
+    newArray.set(this.array);
+    this.array = newArray;
+    this.length = newLength;
+};
+
+/*
+ * Call this.array.set(value, offset), reallocating if necessary. 
+ */
+DynamicUint8Array.prototype.set = function(value, offset) {
+    this.ensureLength(value.length + offset);
+    this.array.set(value, offset);
+};
+
+/*
+ * Return this.array.subarray(begin, end);
+ */
+DynamicUint8Array.prototype.subarray = function(begin, end) {
+    return this.array.subarray(begin, end);
+}
+/**
+ * This class is used to encode ccnb binary elements (blob, type/value pairs).
+ * 
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ */
+
+var XML_EXT = 0x00; 
+	
+var XML_TAG = 0x01; 
+	
+var XML_DTAG = 0x02; 
+	
+var XML_ATTR = 0x03; 
+ 
+var XML_DATTR = 0x04; 
+	
+var XML_BLOB = 0x05; 
+	
+var XML_UDATA = 0x06; 
+	
+var XML_CLOSE = 0x0;
+
+var XML_SUBTYPE_PROCESSING_INSTRUCTIONS = 16; 
+
+
+var XML_TT_BITS = 3;
+var XML_TT_MASK = ((1 << XML_TT_BITS) - 1);
+var XML_TT_VAL_BITS = XML_TT_BITS + 1;
+var XML_TT_VAL_MASK = ((1 << (XML_TT_VAL_BITS)) - 1);
+var XML_REG_VAL_BITS = 7;
+var XML_REG_VAL_MASK = ((1 << XML_REG_VAL_BITS) - 1);
+var XML_TT_NO_MORE = (1 << XML_REG_VAL_BITS); // 0x80
+var BYTE_MASK = 0xFF;
+var LONG_BYTES = 8;
+var LONG_BITS = 64;
+	
+var bits_11 = 0x0000007FF;
+var bits_18 = 0x00003FFFF;
+var bits_32 = 0x0FFFFFFFF;
+
+
+var BinaryXMLEncoder = function BinaryXMLEncoder(){
+	this.ostream = new DynamicUint8Array(100);
+	this.offset =0;
+	this.CODEC_NAME = "Binary";
+};
+
+/*
+ * Encode utf8Content as utf8.
+ */
+BinaryXMLEncoder.prototype.writeUString = function(/*String*/ utf8Content) {
+	this.encodeUString(utf8Content, XML_UDATA);
+};
+
+
+BinaryXMLEncoder.prototype.writeBlob = function(
+		/*Uint8Array*/ binaryContent
+		) {
+	
+	if(LOG >3) console.log(binaryContent);
+	
+	this.encodeBlob(binaryContent, binaryContent.length);
+};
+
+
+BinaryXMLEncoder.prototype.writeStartElement = function(
+	/*String*/ tag, 
+	/*TreeMap<String,String>*/ attributes
+	) {
+
+	/*Long*/ var dictionaryVal = tag; //stringToTag(tag);
+	
+	if (null == dictionaryVal) {
+		this.encodeUString(tag, XML_TAG);
+	} else {
+		this.encodeTypeAndVal(XML_DTAG, dictionaryVal);
+	}
+	
+	if (null != attributes) {
+		this.writeAttributes(attributes); 
+	}
+};
+
+
+BinaryXMLEncoder.prototype.writeEndElement = function() {
+    this.ostream.ensureLength(this.offset + 1);
+	this.ostream.array[this.offset] = XML_CLOSE;
+	this.offset += 1;
+}
+
+
+BinaryXMLEncoder.prototype.writeAttributes = function(/*TreeMap<String,String>*/ attributes) {
+	if (null == attributes) {
+		return;
+	}
+
+	// the keySet of a TreeMap is sorted.
+
+	for(var i=0; i<attributes.length;i++){
+		var strAttr = attributes[i].k;
+		var strValue = attributes[i].v;
+
+		var dictionaryAttr = stringToTag(strAttr);
+		if (null == dictionaryAttr) {
+			// not in dictionary, encode as attr
+			// compressed format wants length of tag represented as length-1
+			// to save that extra bit, as tag cannot be 0 length.
+			// encodeUString knows to do that.
+			this.encodeUString(strAttr, XML_ATTR);
+		} else {
+			this.encodeTypeAndVal(XML_DATTR, dictionaryAttr);
+		}
+		// Write value
+		this.encodeUString(strValue);
+		
+	}
+}
+
+
+//returns a string
+stringToTag = function(/*long*/ tagVal) {
+	if ((tagVal >= 0) && (tagVal < CCNProtocolDTagsStrings.length)) {
+		return CCNProtocolDTagsStrings[tagVal];
+	} else if (tagVal == CCNProtocolDTags.CCNProtocolDataUnit) {
+		return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT;
+	}
+	return null;
+};
+
+//returns a Long
+tagToString =  function(/*String*/ tagName) {
+	// the slow way, but right now we don't care.... want a static lookup for the forward direction
+	for (var i=0; i < CCNProtocolDTagsStrings.length; ++i) {
+		if ((null != CCNProtocolDTagsStrings[i]) && (CCNProtocolDTagsStrings[i] == tagName)) {
+			return i;
+		}
+	}
+	if (CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT == tagName) {
+		return CCNProtocolDTags.CCNProtocolDataUnit;
+	}
+	return null;
+};
+
+/*
+ * If Content is a string, then encode as utf8 and write UDATA.
+ */
+BinaryXMLEncoder.prototype.writeElement = function(
+		//long 
+		tag, 
+		//byte[] 
+		Content,
+		//TreeMap<String, String> 
+		attributes
+		) {
+	this.writeStartElement(tag, attributes);
+	// Will omit if 0-length
+	
+	if(typeof Content === 'number') {
+		if(LOG>4) console.log('GOING TO WRITE THE NUMBER .charCodeAt(0) ' + Content.toString().charCodeAt(0) );
+		if(LOG>4) console.log('GOING TO WRITE THE NUMBER ' + Content.toString() );
+		if(LOG>4) console.log('type of number is ' + typeof Content.toString() );
+		
+		this.writeUString(Content.toString());
+		//whatever
+	}
+	else if(typeof Content === 'string'){
+		if(LOG>4) console.log('GOING TO WRITE THE STRING  ' + Content );
+		if(LOG>4) console.log('type of STRING is ' + typeof Content );
+		
+		this.writeUString(Content);
+	}
+	else{
+		if(LOG>4) console.log('GOING TO WRITE A BLOB  ' + Content );
+
+		this.writeBlob(Content);
+	}
+	
+	this.writeEndElement();
+}
+
+
+
+var TypeAndVal = function TypeAndVal(_type,_val) {
+	this.type = _type;
+	this.val = _val;
+	
+};
+
+
+BinaryXMLEncoder.prototype.encodeTypeAndVal = function(
+		//int
+		type, 
+		//long 
+		val
+		) {
+	
+	if(LOG>4) console.log('Encoding type '+ type+ ' and value '+ val);
+	
+	if(LOG>4) console.log('OFFSET IS ' + this.offset);
+	
+	if ((type > XML_UDATA) || (type < 0) || (val < 0)) {
+		throw new Error("Tag and value must be positive, and tag valid.");
+	}
+	
+	// Encode backwards. Calculate how many bytes we need:
+	var numEncodingBytes = this.numEncodingBytes(val);
+	this.ostream.ensureLength(this.offset + numEncodingBytes);
+
+	// Bottom 4 bits of val go in last byte with tag.
+	this.ostream.array[this.offset + numEncodingBytes - 1] = 
+		//(byte)
+			(BYTE_MASK &
+					(((XML_TT_MASK & type) | 
+					 ((XML_TT_VAL_MASK & val) << XML_TT_BITS))) |
+					 XML_TT_NO_MORE); // set top bit for last byte
+	val = val >>> XML_TT_VAL_BITS;
+	
+	// Rest of val goes into preceding bytes, 7 bits per byte, top bit
+	// is "more" flag.
+	var i = this.offset + numEncodingBytes - 2;
+	while ((0 != val) && (i >= this.offset)) {
+		this.ostream.array[i] = //(byte)
+				(BYTE_MASK & (val & XML_REG_VAL_MASK)); // leave top bit unset
+		val = val >>> XML_REG_VAL_BITS;
+		--i;
+	}
+	if (val != 0) {
+		throw new Error( "This should not happen: miscalculated encoding");
+		//Log.warning(Log.FAC_ENCODING, "This should not happen: miscalculated encoding length, have " + val + " left.");
+	}
+	this.offset+= numEncodingBytes;
+	
+	return numEncodingBytes;
+};
+
+/*
+ * Encode ustring as utf8.
+ */
+BinaryXMLEncoder.prototype.encodeUString = function(
+		//String 
+		ustring, 
+		//byte 
+		type) {
+	
+	if (null == ustring)
+		return;
+	if (type == XML_TAG || type == XML_ATTR && ustring.length == 0)
+		return;
+	
+	if(LOG>3) console.log("The string to write is ");
+	if(LOG>3) console.log(ustring);
+
+	var strBytes = DataUtils.stringToUtf8Array(ustring);
+	
+	this.encodeTypeAndVal(type, 
+						(((type == XML_TAG) || (type == XML_ATTR)) ?
+								(strBytes.length-1) :
+								strBytes.length));
+	
+	if(LOG>3) console.log("THE string to write is ");
+	
+	if(LOG>3) console.log(strBytes);
+	
+	this.writeString(strBytes);
+	this.offset+= strBytes.length;
+};
+
+
+
+BinaryXMLEncoder.prototype.encodeBlob = function(
+		//Uint8Array 
+		blob, 
+		//int 
+		length) {
+
+
+	if (null == blob)
+		return;
+	
+	if(LOG>4) console.log('LENGTH OF XML_BLOB IS '+length);
+	
+	/*blobCopy = new Array(blob.Length);
+	
+	for (i = 0; i < blob.length; i++) //in InStr.ToCharArray())
+	{
+		blobCopy[i] = blob[i];
+	}*/
+
+	this.encodeTypeAndVal(XML_BLOB, length);
+
+	this.writeBlobArray(blob);
+	this.offset += length;
+};
+
+var ENCODING_LIMIT_1_BYTE = ((1 << (XML_TT_VAL_BITS)) - 1);
+var ENCODING_LIMIT_2_BYTES = ((1 << (XML_TT_VAL_BITS + XML_REG_VAL_BITS)) - 1);
+var ENCODING_LIMIT_3_BYTES = ((1 << (XML_TT_VAL_BITS + 2 * XML_REG_VAL_BITS)) - 1);
+
+BinaryXMLEncoder.prototype.numEncodingBytes = function(
+		//long
+		x) {
+	if (x <= ENCODING_LIMIT_1_BYTE) return (1);
+	if (x <= ENCODING_LIMIT_2_BYTES) return (2);
+	if (x <= ENCODING_LIMIT_3_BYTES) return (3);
+	
+	var numbytes = 1;
+	
+	// Last byte gives you XML_TT_VAL_BITS
+	// Remainder each give you XML_REG_VAL_BITS
+	x = x >>> XML_TT_VAL_BITS;
+	while (x != 0) {
+        numbytes++;
+		x = x >>> XML_REG_VAL_BITS;
+	}
+	return (numbytes);
+};
+
+BinaryXMLEncoder.prototype.writeDateTime = function(
+		//String 
+		tag, 
+		//CCNTime 
+		dateTime) {
+	
+	if(LOG>4)console.log('ENCODING DATE with LONG VALUE');
+	if(LOG>4)console.log(dateTime.msec);
+	
+	//var binarydate = DataUtils.unsignedLongToByteArray( Math.round((dateTime.msec/1000) * 4096)  );
+	
+
+	//parse to hex
+	var binarydate =  Math.round((dateTime.msec/1000) * 4096).toString(16)  ;
+
+	//HACK
+	var binarydate =  DataUtils.toNumbers( '0'.concat(binarydate,'0')) ;
+
+	
+	if(LOG>4)console.log('ENCODING DATE with BINARY VALUE');
+	if(LOG>4)console.log(binarydate);
+	if(LOG>4)console.log('ENCODING DATE with BINARY VALUE(HEX)');
+	if(LOG>4)console.log(DataUtils.toHex(binarydate));
+	
+	this.writeElement(tag, binarydate);
+};
+
+// This does not update this.offset.
+BinaryXMLEncoder.prototype.writeString = function(input) {
+	
+    if(typeof input === 'string'){
+		//console.log('went here');
+    	if(LOG>4) console.log('GOING TO WRITE A STRING');
+    	if(LOG>4) console.log(input);
+        
+        this.ostream.ensureLength(this.offset + input.length);
+		for (var i = 0; i < input.length; i++) {
+			if(LOG>4) console.log('input.charCodeAt(i)=' + input.charCodeAt(i));
+		    this.ostream.array[this.offset + i] = (input.charCodeAt(i));
+		}
+	}
+    else{
+		if(LOG>4) console.log('GOING TO WRITE A STRING IN BINARY FORM');
+		if(LOG>4) console.log(input);
+		
+		this.writeBlobArray(input);
+    }
+    /*
+	else if(typeof input === 'object'){
+		
+	}	
+	*/
+};
+
+
+BinaryXMLEncoder.prototype.writeBlobArray = function(
+		//Uint8Array 
+		blob) {
+	
+	if(LOG>4) console.log('GOING TO WRITE A BLOB');
+    
+	this.ostream.set(blob, this.offset);
+};
+
+
+BinaryXMLEncoder.prototype.getReducedOstream = function() {
+	return this.ostream.subarray(0, this.offset);
+};
+
+/**
+ * This class is used to decode ccnb binary elements (blob, type/value pairs).
+ * 
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ */
+
+var XML_EXT = 0x00; 
+	
+var XML_TAG = 0x01; 
+	
+var XML_DTAG = 0x02; 
+	
+var XML_ATTR = 0x03; 
+ 
+var XML_DATTR = 0x04; 
+	
+var XML_BLOB = 0x05; 
+	
+var XML_UDATA = 0x06; 
+	
+var XML_CLOSE = 0x0;
+
+var XML_SUBTYPE_PROCESSING_INSTRUCTIONS = 16; 
+	
+
+var XML_TT_BITS = 3;
+var XML_TT_MASK = ((1 << XML_TT_BITS) - 1);
+var XML_TT_VAL_BITS = XML_TT_BITS + 1;
+var XML_TT_VAL_MASK = ((1 << (XML_TT_VAL_BITS)) - 1);
+var XML_REG_VAL_BITS = 7;
+var XML_REG_VAL_MASK = ((1 << XML_REG_VAL_BITS) - 1);
+var XML_TT_NO_MORE = (1 << XML_REG_VAL_BITS); // 0x80
+var BYTE_MASK = 0xFF;
+var LONG_BYTES = 8;
+var LONG_BITS = 64;
+	
+var bits_11 = 0x0000007FF;
+var bits_18 = 0x00003FFFF;
+var bits_32 = 0x0FFFFFFFF;
+
+
+
+//returns a string
+tagToString = function(/*long*/ tagVal) {
+	if ((tagVal >= 0) && (tagVal < CCNProtocolDTagsStrings.length)) {
+		return CCNProtocolDTagsStrings[tagVal];
+	} else if (tagVal == CCNProtocolDTags.CCNProtocolDataUnit) {
+		return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT;
+	}
+	return null;
+};
+
+//returns a Long
+stringToTag =  function(/*String*/ tagName) {
+	// the slow way, but right now we don't care.... want a static lookup for the forward direction
+	for (var i=0; i < CCNProtocolDTagsStrings.length; ++i) {
+		if ((null != CCNProtocolDTagsStrings[i]) && (CCNProtocolDTagsStrings[i] == tagName)) {
+			return i;
+		}
+	}
+	if (CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT == tagName) {
+		return CCNProtocolDTags.CCNProtocolDataUnit;
+	}
+	return null;
+};
+
+//console.log(stringToTag(64));
+var BinaryXMLDecoder = function BinaryXMLDecoder(istream){
+	var MARK_LEN=512;
+	var DEBUG_MAX_LEN =  32768;
+	
+	this.istream = istream;
+	this.offset = 0;
+};
+
+BinaryXMLDecoder.prototype.initializeDecoding = function() {
+		//if (!this.istream.markSupported()) {
+			//throw new IllegalArgumentException(this.getClass().getName() + ": input stream must support marking!");
+		//}
+}
+
+BinaryXMLDecoder.prototype.readStartDocument = function(){
+		// Currently no start document in binary encoding.
+	}
+
+BinaryXMLDecoder.prototype.readEndDocument = function() {
+		// Currently no end document in binary encoding.
+	};
+
+BinaryXMLDecoder.prototype.readStartElement = function(
+		//String 
+		startTag,
+		//TreeMap<String, String> 
+		attributes) {
+	
+		
+		//NOT SURE
+		//if(typeof startTag == 'number')
+			//startTag = tagToString(startTag);
+		
+			//TypeAndVal 
+			var tv = this.decodeTypeAndVal();
+			
+			if (null == tv) {
+				throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got something not a tag."));
+			}
+			
+			//String 
+			var decodedTag = null;
+			//console.log(tv);
+			//console.log(typeof tv);
+			
+			//console.log(XML_TAG);
+			if (tv.type() == XML_TAG) {
+				//console.log('got here');
+				//Log.info(Log.FAC_ENCODING, "Unexpected: got tag in readStartElement; looking for tag " + startTag + " got length: " + (int)tv.val()+1);
+				// Tag value represents length-1 as tags can never be empty.
+				var valval ;
+				if(typeof tv.val() == 'string'){
+					valval = (parseInt(tv.val())) + 1;
+				}
+				else
+					valval = (tv.val())+ 1;
+				
+				//console.log('valval is ' +valval);
+				
+				decodedTag = this.decodeUString(valval);
+				
+			} else if (tv.type() == XML_DTAG) {
+				//console.log('gothere');
+				//console.log(tv.val());
+				//decodedTag = tagToString(tv.val());
+				//console.log()
+				decodedTag = tv.val();
+			}
+			
+			//console.log(decodedTag);
+			//console.log('startTag is '+startTag);
+			
+			
+			if ((null ==  decodedTag) || decodedTag != startTag ) {
+				console.log('expecting '+ startTag + ' but got '+ decodedTag);
+				throw new ContentDecodingException(new Error("Expected start element: " + startTag + " got: " + decodedTag + "(" + tv.val() + ")"));
+			}
+			
+			// DKS: does not read attributes out of stream if caller doesn't
+			// ask for them. Should possibly peek and skip over them regardless.
+			// TODO: fix this
+			if (null != attributes) {
+				readAttributes(attributes); 
+			}
+	}
+	
+
+BinaryXMLDecoder.prototype.readAttributes = function(
+	// array of [attributeName, attributeValue] 
+	attributes) {
+	
+	if (null == attributes) {
+		return;
+	}
+
+	try {
+		// Now need to get attributes.
+		//TypeAndVal 
+		var nextTV = this.peekTypeAndVal();
+
+		while ((null != nextTV) && ((XML_ATTR == nextTV.type()) ||
+				(XML_DATTR == nextTV.type()))) {
+
+			// Decode this attribute. First, really read the type and value.
+			//this.TypeAndVal 
+			var thisTV = this.decodeTypeAndVal();
+
+			//String 
+			var attributeName = null;
+			if (XML_ATTR == thisTV.type()) {
+				// Tag value represents length-1 as attribute names cannot be empty.
+				var valval ;
+				if(typeof thisTV.val() == 'string'){
+					valval = (parseInt(thisTV.val())) + 1;
+				}
+				else
+					valval = (thisTV.val())+ 1;
+				
+				attributeName = this.decodeUString(valval);
+
+			} else if (XML_DATTR == thisTV.type()) {
+				// DKS TODO are attributes same or different dictionary?
+				attributeName = tagToString(thisTV.val());
+				if (null == attributeName) {
+					throw new ContentDecodingException(new Error("Unknown DATTR value" + thisTV.val()));
+				}
+			}
+			// Attribute values are always UDATA
+			//String
+			var attributeValue = this.decodeUString();
+
+			//
+			attributes.push([attributeName, attributeValue]);
+
+			nextTV = this.peekTypeAndVal();
+		}
+	} catch ( e) {
+		throw new ContentDecodingException(new Error("readStartElement", e));
+	}
+};
+
+//returns a string
+BinaryXMLDecoder.prototype.peekStartElementAsString = function() {
+	//this.istream.mark(MARK_LEN);
+
+	//String 
+	var decodedTag = null;
+	var previousOffset = this.offset;
+	try {
+		// Have to distinguish genuine errors from wrong tags. Could either use
+		// a special exception subtype, or redo the work here.
+		//this.TypeAndVal 
+		var tv = this.decodeTypeAndVal();
+
+		if (null != tv) {
+
+			if (tv.type() == XML_TAG) {
+				/*if (tv.val()+1 > DEBUG_MAX_LEN) {
+					throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!")(;
+				}*/
+
+				// Tag value represents length-1 as tags can never be empty.
+				var valval ;
+				if(typeof tv.val() == 'string'){
+					valval = (parseInt(tv.val())) + 1;
+				}
+				else
+					valval = (tv.val())+ 1;
+				
+				decodedTag = this.decodeUString(valval);
+				
+				//Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
+
+			} else if (tv.type() == XML_DTAG) {
+				decodedTag = tagToString(tv.val());					
+			}
+
+		} // else, not a type and val, probably an end element. rewind and return false.
+
+	} catch ( e) {
+
+	} finally {
+		try {
+			this.offset = previousOffset;
+		} catch ( e) {
+			Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
+			throw new ContentDecodingException(new Error("Cannot reset stream! " + e.getMessage(), e));
+		}
+	}
+	return decodedTag;
+};
+
+BinaryXMLDecoder.prototype.peekStartElement = function(
+		//String 
+		startTag) {
+	//String 
+	if(typeof startTag == 'string'){
+		var decodedTag = this.peekStartElementAsString();
+		
+		if ((null !=  decodedTag) && decodedTag == startTag) {
+			return true;
+		}
+		return false;
+	}
+	else if(typeof startTag == 'number'){
+		var decodedTag = this.peekStartElementAsLong();
+		if ((null !=  decodedTag) && decodedTag == startTag) {
+			return true;
+		}
+		return false;
+	}
+	else{
+		throw new ContentDecodingException(new Error("SHOULD BE STRING OR NUMBER"));
+	}
+}
+//returns Long
+BinaryXMLDecoder.prototype.peekStartElementAsLong = function() {
+		//this.istream.mark(MARK_LEN);
+
+		//Long
+		var decodedTag = null;
+		
+		var previousOffset = this.offset;
+		
+		try {
+			// Have to distinguish genuine errors from wrong tags. Could either use
+			// a special exception subtype, or redo the work here.
+			//this.TypeAndVal
+			var tv = this.decodeTypeAndVal();
+
+			if (null != tv) {
+
+				if (tv.type() == XML_TAG) {
+					if (tv.val()+1 > DEBUG_MAX_LEN) {
+						throw new ContentDecodingException(new Error("Decoding error: length " + tv.val()+1 + " longer than expected maximum length!"));
+					}
+
+					var valval ;
+					if(typeof tv.val() == 'string'){
+						valval = (parseInt(tv.val())) + 1;
+					}
+					else
+						valval = (tv.val())+ 1;
+					
+					// Tag value represents length-1 as tags can never be empty.
+					//String 
+					var strTag = this.decodeUString(valval);
+					
+					decodedTag = stringToTag(strTag);
+					
+					//Log.info(Log.FAC_ENCODING, "Unexpected: got text tag in peekStartElement; length: " + valval + " decoded tag = " + decodedTag);
+					
+				} else if (tv.type() == XML_DTAG) {
+					decodedTag = tv.val();					
+				}
+
+			} // else, not a type and val, probably an end element. rewind and return false.
+
+		} catch ( e) {
+			
+		} finally {
+			try {
+				//this.istream.reset();
+				this.offset = previousOffset;
+			} catch ( e) {
+				Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
+				throw new Error("Cannot reset stream! " + e.getMessage(), e);
+			}
+		}
+		return decodedTag;
+	};
+
+
+// returns a byte[]
+BinaryXMLDecoder.prototype.readBinaryElement = function(
+		//long 
+		startTag,
+		//TreeMap<String, String> 
+		attributes){
+	//byte [] 
+	var blob = null;
+	
+	this.readStartElement(startTag, attributes);
+	blob = this.readBlob();	
+
+	return blob;
+};
+	
+	
+BinaryXMLDecoder.prototype.readEndElement = function(){
+			if(LOG>4)console.log('this.offset is '+this.offset);
+			
+			var next = this.istream[this.offset]; 
+			
+			this.offset++;
+			//read();
+			
+			if(LOG>4)console.log('XML_CLOSE IS '+XML_CLOSE);
+			if(LOG>4)console.log('next is '+next);
+			
+			if (next != XML_CLOSE) {
+				console.log("Expected end element, got: " + next);
+				throw new ContentDecodingException(new Error("Expected end element, got: " + next));
+			}
+	};
+
+
+//String	
+BinaryXMLDecoder.prototype.readUString = function(){
+			//String 
+			var ustring = this.decodeUString();	
+			this.readEndElement();
+			return ustring;
+
+	};
+	
+
+//returns a uint8array
+BinaryXMLDecoder.prototype.readBlob = function() {
+			//uint8array
+			
+			var blob = this.decodeBlob();	
+			this.readEndElement();
+			return blob;
+
+	};
+
+
+//CCNTime
+BinaryXMLDecoder.prototype.readDateTime = function(
+	//long 
+	startTag)  {
+	//byte [] 
+	
+	var byteTimestamp = this.readBinaryElement(startTag);
+
+	//var lontimestamp = DataUtils.byteArrayToUnsignedLong(byteTimestamp);
+
+	byteTimestamp = DataUtils.toHex(byteTimestamp);
+	
+	
+	byteTimestamp = parseInt(byteTimestamp, 16);
+
+	var lontimestamp = (byteTimestamp/ 4096) * 1000;
+
+	//if(lontimestamp<0) lontimestamp =  - lontimestamp;
+
+	if(LOG>3) console.log('DECODED DATE WITH VALUE');
+	if(LOG>3) console.log(lontimestamp);
+	
+
+	//CCNTime 
+	var timestamp = new CCNTime(lontimestamp);
+	//timestamp.setDateBinary(byteTimestamp);
+	
+	if (null == timestamp) {
+		throw new ContentDecodingException(new Error("Cannot parse timestamp: " + DataUtils.printHexBytes(byteTimestamp)));
+	}		
+	return timestamp;
+};
+
+BinaryXMLDecoder.prototype.decodeTypeAndVal = function() {
+	
+	/*int*/var type = -1;
+	/*long*/var val = 0;
+	/*boolean*/var more = true;
+
+	do {
+		
+		var next = this.istream[this.offset ];
+		
+		
+		if (next < 0) {
+			return null; 
+		}
+
+		if ((0 == next) && (0 == val)) {
+			return null;
+		}
+		
+		more = (0 == (next & XML_TT_NO_MORE));
+		
+		if  (more) {
+			val = val << XML_REG_VAL_BITS;
+			val |= (next & XML_REG_VAL_MASK);
+		} else {
+
+			type = next & XML_TT_MASK;
+			val = val << XML_TT_VAL_BITS;
+			val |= ((next >>> XML_TT_BITS) & XML_TT_VAL_MASK);
+		}
+		
+		this.offset++;
+		
+	} while (more);
+	
+	if(LOG>3)console.log('TYPE is '+ type + ' VAL is '+ val);
+
+	return new TypeAndVal(type, val);
+};
+
+
+
+//TypeAndVal
+BinaryXMLDecoder.peekTypeAndVal = function() {
+	//TypeAndVal 
+	var tv = null;
+	
+	//this.istream.mark(LONG_BYTES*2);		
+	
+	var previousOffset = this.offset;
+	
+	try {
+		tv = this.decodeTypeAndVal();
+	} finally {
+		//this.istream.reset();
+		this.offset = previousOffset;
+	}
+	
+	return tv;
+};
+
+
+//Uint8Array
+BinaryXMLDecoder.prototype.decodeBlob = function(
+		//int 
+		blobLength) {
+	
+	if(null == blobLength){
+		//TypeAndVal
+		var tv = this.decodeTypeAndVal();
+
+		var valval ;
+		
+		if(typeof tv.val() == 'string'){
+			valval = (parseInt(tv.val()));
+		}
+		else
+			valval = (tv.val());
+		
+		//console.log('valval here is ' + valval);
+		return  this.decodeBlob(valval);
+	}
+	
+	//
+	//Uint8Array
+	var bytes = this.istream.subarray(this.offset, this.offset+ blobLength);
+	this.offset += blobLength;
+	
+	return bytes;
+};
+
+//String
+BinaryXMLDecoder.prototype.decodeUString = function(
+		//int 
+		byteLength) {
+	if(null == byteLength ){
+		var tempStreamPosition = this.offset;
+			
+		//TypeAndVal 
+		var tv = this.decodeTypeAndVal();
+		
+		if(LOG>3)console.log('TV is '+tv);
+		if(LOG>3)console.log(tv);
+		
+		if(LOG>3)console.log('Type of TV is '+typeof tv);
+	
+		if ((null == tv) || (XML_UDATA != tv.type())) { // if we just have closers left, will get back null
+			//if (Log.isLoggable(Log.FAC_ENCODING, Level.FINEST))
+				//Log.finest(Log.FAC_ENCODING, "Expected UDATA, got " + ((null == tv) ? " not a tag " : tv.type()) + ", assuming elided 0-length blob.");
+			
+			this.offset = tempStreamPosition;
+			
+			return "";
+		}
+			
+		return this.decodeUString(tv.val());
+	}
+	else{
+		//uint8array 
+		var stringBytes = this.decodeBlob(byteLength);
+		
+		//return DataUtils.getUTF8StringFromBytes(stringBytes);
+		return  DataUtils.toString(stringBytes);
+		
+	}
+};
+
+//OBject containg a pair of type and value
+var TypeAndVal = function TypeAndVal(_type,_val) {
+	this.t = _type;
+	this.v = _val;
+};
+
+TypeAndVal.prototype.type = function(){
+	return this.t;
+};
+
+TypeAndVal.prototype.val = function(){
+	return this.v;
+};
+
+
+
+
+BinaryXMLDecoder.prototype.readIntegerElement =function(
+	//String 
+	startTag) {
+
+	//String 
+	if(LOG>4) console.log('READING INTEGER '+ startTag);
+	if(LOG>4) console.log('TYPE OF '+ typeof startTag);
+	
+	var strVal = this.readUTF8Element(startTag);
+	
+	return parseInt(strVal);
+};
+
+
+BinaryXMLDecoder.prototype.readUTF8Element =function(
+			//String 
+			startTag,
+			//TreeMap<String, String> 
+			attributes) {
+			//throws Error where name == "ContentDecodingException" 
+
+		this.readStartElement(startTag, attributes); // can't use getElementText, can't get attributes
+		//String 
+		var strElementText = this.readUString();
+		return strElementText;
+};
+
+
+/* 
+ * Set the offset into the input, used for the next read.
+ */
+BinaryXMLDecoder.prototype.seek = function(
+        //int
+        offset) {
+    this.offset = offset;
+}
+
+/*
+ * Call with: throw new ContentDecodingException(new Error("message")).
+ */
+function ContentDecodingException(error) {
+    this.message = error.message;
+    // Copy lineNumber, etc. from where new Error was called.
+    for (var prop in error)
+        this[prop] = error[prop];
+}
+ContentDecodingException.prototype = new Error();
+ContentDecodingException.prototype.name = "ContentDecodingException";
+
+/**
+ * This class uses BinaryXMLDecoder to follow the structure of a ccnb binary element to 
+ * determine its end.
+ * 
+ * @author: Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+
+var BinaryXMLStructureDecoder = function BinaryXMLDecoder() {
+    this.gotElementEnd = false;
+	this.offset = 0;
+    this.level = 0;
+    this.state = BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;
+    this.headerLength = 0;
+    this.useHeaderBuffer = false;
+    this.headerBuffer = new DynamicUint8Array(5);
+    this.nBytesToRead = 0;
+};
+
+BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE = 0;
+BinaryXMLStructureDecoder.READ_BYTES = 1;
+
+/*
+ * Continue scanning input starting from this.offset.  If found the end of the element
+ *   which started at offset 0 then return true, else false.
+ * If this returns false, you should read more into input and call again.
+ * You have to pass in input each time because the array could be reallocated.
+ * This throws an exception for badly formed ccnb.
+ */
+BinaryXMLStructureDecoder.prototype.findElementEnd = function(
+    // Uint8Array
+    input)
+{
+    if (this.gotElementEnd)
+        // Someone is calling when we already got the end.
+        return true;
+    
+    var decoder = new BinaryXMLDecoder(input);
+    
+    while (true) {
+        if (this.offset >= input.length)
+            // All the cases assume we have some input.
+            return false;
+        
+        switch (this.state) {
+            case BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE:               
+                // First check for XML_CLOSE.
+                if (this.headerLength == 0 && input[this.offset] == XML_CLOSE) {
+                    ++this.offset;
+                    // Close the level.
+                    --this.level;
+                    if (this.level == 0)
+                        // Finished.
+                        return true;
+                    if (this.level < 0)
+                        throw new Error("BinaryXMLStructureDecoder: Unexepected close tag at offset " +
+                            (this.offset - 1));
+                    
+                    // Get ready for the next header.
+                    this.startHeader();
+                    break;
+                }
+                
+                var startingHeaderLength = this.headerLength;
+                while (true) {
+                    if (this.offset >= input.length) {
+                        // We can't get all of the header bytes from this input. Save in headerBuffer.
+                        this.useHeaderBuffer = true;
+                        var nNewBytes = this.headerLength - startingHeaderLength;
+                        this.headerBuffer.set
+                            (input.subarray(this.offset - nNewBytes, nNewBytes), startingHeaderLength);
+                        
+                        return false;
+                    }
+                    var headerByte = input[this.offset++];
+                    ++this.headerLength;
+                    if (headerByte & XML_TT_NO_MORE)
+                        // Break and read the header.
+                        break;
+                }
+                
+                var typeAndVal;
+                if (this.useHeaderBuffer) {
+                    // Copy the remaining bytes into headerBuffer.
+                    nNewBytes = this.headerLength - startingHeaderLength;
+                    this.headerBuffer.set
+                        (input.subarray(this.offset - nNewBytes, nNewBytes), startingHeaderLength);
+
+                    typeAndVal = new BinaryXMLDecoder(this.headerBuffer.array).decodeTypeAndVal();
+                }
+                else {
+                    // We didn't have to use the headerBuffer.
+                    decoder.seek(this.offset - this.headerLength);
+                    typeAndVal = decoder.decodeTypeAndVal();
+                }
+                
+                if (typeAndVal == null)
+                    throw new Error("BinaryXMLStructureDecoder: Can't read header starting at offset " +
+                        (this.offset - this.headerLength));
+                
+                // Set the next state based on the type.
+                var type = typeAndVal.t;
+                if (type == XML_DATTR)
+                    // We already consumed the item. READ_HEADER_OR_CLOSE again.
+                    // ccnb has rules about what must follow an attribute, but we are just scanning.
+                    this.startHeader();
+                else if (type == XML_DTAG || type == XML_EXT) {
+                    // Start a new level and READ_HEADER_OR_CLOSE again.
+                    ++this.level;
+                    this.startHeader();
+                }
+                else if (type == XML_TAG || type == XML_ATTR) {
+                    if (type == XML_TAG)
+                        // Start a new level and read the tag.
+                        ++this.level;
+                    // Minimum tag or attribute length is 1.
+                    this.nBytesToRead = typeAndVal.v + 1;
+                    this.state = BinaryXMLStructureDecoder.READ_BYTES;
+                    // ccnb has rules about what must follow an attribute, but we are just scanning.
+                }
+                else if (type == XML_BLOB || type == XML_UDATA) {
+                    this.nBytesToRead = typeAndVal.v;
+                    this.state = BinaryXMLStructureDecoder.READ_BYTES;
+                }
+                else
+                    throw new Error("BinaryXMLStructureDecoder: Unrecognized header type " + type);
+                break;
+            
+            case BinaryXMLStructureDecoder.READ_BYTES:
+                var nRemainingBytes = input.length - this.offset;
+                if (nRemainingBytes < this.nBytesToRead) {
+                    // Need more.
+                    this.offset += nRemainingBytes;
+                    this.nBytesToRead -= nRemainingBytes;
+                    return false;
+                }
+                // Got the bytes.  Read a new header or close.
+                this.offset += this.nBytesToRead;
+                this.startHeader();
+                break;
+            
+            default:
+                // We don't expect this to happen.
+                throw new Error("BinaryXMLStructureDecoder: Unrecognized state " + this.state);
+        }
+    }
+};
+
+/*
+ * Set the state to READ_HEADER_OR_CLOSE and set up to start reading the header
+ */
+BinaryXMLStructureDecoder.prototype.startHeader = function() {
+    this.headerLength = 0;
+    this.useHeaderBuffer = false;
+    this.state = BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;    
+}
+
+/*
+ *  Set the offset into the input, used for the next read.
+ */
+BinaryXMLStructureDecoder.prototype.seek = function(
+        //int
+        offset) {
+    this.offset = offset;
+}
+/**
+ * This class contains utilities to help parse the data
+ * author: Meki Cheraoui, Jeff Thompson
+ * See COPYING for copyright and distribution information.
+ */
+ 
+var DataUtils = function DataUtils(){
+	
+	
+};
+
+
+/*
+ * NOTE THIS IS CURRENTLY NOT BEHING USED
+ * 
+ */
+
+DataUtils.keyStr = "ABCDEFGHIJKLMNOP" +
+               "QRSTUVWXYZabcdef" +
+               "ghijklmnopqrstuv" +
+               "wxyz0123456789+/" +
+               "=";
+
+               
+/**
+ * Raw String to Base 64
+ */
+DataUtils.stringtoBase64=function stringtoBase64(input) {
+     input = escape(input);
+     var output = "";
+     var chr1, chr2, chr3 = "";
+     var enc1, enc2, enc3, enc4 = "";
+     var i = 0;
+
+     do {
+        chr1 = input.charCodeAt(i++);
+        chr2 = input.charCodeAt(i++);
+        chr3 = input.charCodeAt(i++);
+
+        enc1 = chr1 >> 2;
+        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
+        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
+        enc4 = chr3 & 63;
+
+        if (isNaN(chr2)) {
+           enc3 = enc4 = 64;
+        } else if (isNaN(chr3)) {
+           enc4 = 64;
+        }
+
+        output = output +
+           DataUtils.keyStr.charAt(enc1) +
+           DataUtils.keyStr.charAt(enc2) +
+           DataUtils.keyStr.charAt(enc3) +
+           DataUtils.keyStr.charAt(enc4);
+        chr1 = chr2 = chr3 = "";
+        enc1 = enc2 = enc3 = enc4 = "";
+     } while (i < input.length);
+
+     return output;
+  }
+
+/**
+ * Base 64 to Raw String 
+ */
+DataUtils.base64toString = function base64toString(input) {
+     var output = "";
+     var chr1, chr2, chr3 = "";
+     var enc1, enc2, enc3, enc4 = "";
+     var i = 0;
+
+     // remove all characters that are not A-Z, a-z, 0-9, +, /, or =
+     var base64test = /[^A-Za-z0-9\+\/\=]/g;
+     /* Test for invalid characters. */
+     if (base64test.exec(input)) {
+        alert("There were invalid base64 characters in the input text.\n" +
+              "Valid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\n" +
+              "Expect errors in decoding.");
+     }
+     
+     input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
+
+     do {
+        enc1 = DataUtils.keyStr.indexOf(input.charAt(i++));
+        enc2 = DataUtils.keyStr.indexOf(input.charAt(i++));
+        enc3 = DataUtils.keyStr.indexOf(input.charAt(i++));
+        enc4 = DataUtils.keyStr.indexOf(input.charAt(i++));
+
+        chr1 = (enc1 << 2) | (enc2 >> 4);
+        chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
+        chr3 = ((enc3 & 3) << 6) | enc4;
+
+        output = output + String.fromCharCode(chr1);
+
+        if (enc3 != 64) {
+           output = output + String.fromCharCode(chr2);
+        }
+        if (enc4 != 64) {
+           output = output + String.fromCharCode(chr3);
+        }
+
+        chr1 = chr2 = chr3 = "";
+        enc1 = enc2 = enc3 = enc4 = "";
+
+     } while (i < input.length);
+
+     return unescape(output);
+  };
+
+//byte [] 
+
+/**
+ * NOT WORKING!!!!!
+ * 
+ * Unsiged Long Number to Byte Array
+ */
+	
+ /*
+DataUtils.unsignedLongToByteArray= function( value) {
+	
+	if(LOG>4)console.log('INPUT IS '+value);
+	
+	if( 0 == value )
+		return [0];
+
+	if( 0 <= value && value <= 0x00FF ) {
+		//byte [] 
+		var bb = new Array(1);
+		bb[0] = (value & 0x00FF);
+		return bb;
+	}
+
+	if(LOG>4) console.log('type of value is '+typeof value);
+	if(LOG>4) console.log('value is '+value);
+	//byte [] 
+	var out = null;
+	//int
+	var offset = -1;
+	for(var i = 7; i >=0; --i) {
+		//byte
+		console.log(i);
+		console.log('value is '+value);
+		console.log('(value >> (i * 8)) '+ (value >> (i * 8))  );
+		console.log(' ((value >> (i * 8)) & 0xFF) '+ ((value >> (i * 8)) & 0xFF)  );
+
+		var b = ((value >> (i * 8)) & 0xFF)  ;
+		
+		if(LOG>4) console.log('b is '+b);
+		
+		if( out == null && b != 0 ) {
+			//out = new byte[i+1];
+			out = new Array(i+1);
+			offset = i;
+		}
+		
+		if( out != null )
+			out[ offset - i ] = b;
+	}
+	if(LOG>4)console.log('OUTPUT IS ');
+	if(LOG>4)console.log(out);
+	return out;
+}
+*/
+	
+/**
+ * NOT WORKING!!!!!
+ * 
+ * Unsiged Long Number to Byte Array
+ *//*
+DataUtils.byteArrayToUnsignedLong = function(//final byte [] 
+	src) {
+		if(LOG>4) console.log('INPUT IS ');
+		if(LOG>4) console.log(src);
+		
+		var value = 0;
+		for(var i = 0; i < src.length; i++) {
+			value = value << 8;
+			// Java will assume the byte is signed, so extend it and trim it.
+			
+			
+			var b = ((src[i]) & 0xFF );
+			value |= b;
+		}
+		
+		if(LOG>4) console.log('OUTPUT IS ');
+		
+		if(LOG>4) console.log(value);
+
+		return value;
+	}*/
+
+
+/**
+ * Hex String to Byte Array
+ */
+	//THIS IS NOT WORKING
+/*
+DataUtils.HexStringtoByteArray = function(str) {
+    var byteArray = [];
+    for (var i = 0; i < str.length; i++)
+        if (str.charCodeAt(i) <= 0x7F)
+            byteArray.push(str.charCodeAt(i));
+        else {
+            var h = encodeURIComponent(str.charAt(i)).substr(1).split('%');
+            for (var j = 0; j < h.length; j++)
+                byteArray.push(parseInt(h[j], 16));
+        }
+    return byteArray;
+};
+*/
+
+/**
+ * Uint8Array to Hex String
+ */
+//http://ejohn.org/blog/numbers-hex-and-colors/
+DataUtils.toHex = function(args){
+	if (LOG>4) console.log('ABOUT TO CONVERT '+ args);
+	//console.log(args);
+  	var ret = "";
+  	for ( var i = 0; i < args.length; i++ )
+    	ret += (args[i] < 16 ? "0" : "") + args[i].toString(16);
+  	if (LOG>4) console.log('Converted to: ' + ret);
+  	return ret; //.toUpperCase();
+}
+
+/**
+ * Raw string to hex string.
+ */
+DataUtils.stringToHex = function(args){
+	var ret = "";
+	for (var i = 0; i < args.length; ++i) {
+		var value = args.charCodeAt(i);
+		ret += (value < 16 ? "0" : "") + value.toString(16);
+	}
+	return ret;
+}
+
+/**
+ * Uint8Array to raw string.
+ */
+DataUtils.toString = function(args){
+  //console.log(arguments);
+  var ret = "";
+  for ( var i = 0; i < args.length; i++ )
+    ret += String.fromCharCode(args[i]);
+  return ret;
+}
+
+/**
+ * Hex String to Uint8Array.
+ */
+DataUtils.toNumbers = function(str) {
+	if (typeof str == 'string') {
+		var ret = new Uint8Array(Math.floor(str.length / 2));
+        var i = 0;
+		str.replace(/(..)/g, function(str) {
+		    ret[i++] = parseInt(str, 16);
+		});
+		return ret;
+    }
+}
+
+/**
+ * Hex String to raw string.
+ */
+DataUtils.hexToRawString = function(str) {
+    if(typeof str =='string') {
+		var ret = "";
+		str.replace(/(..)/g, function(s) {
+			ret += String.fromCharCode(parseInt(s, 16));
+		});
+		return ret;
+    }
+}
+
+/**
+ * Raw String to Uint8Array.
+ */
+DataUtils.toNumbersFromString = function(str) {
+	var bytes = new Uint8Array(str.length);
+	for(var i=0;i<str.length;i++)
+		bytes[i] = str.charCodeAt(i);
+	return bytes;
+}
+
+/*
+ * Encode str as utf8 and return as Uint8Array.
+ * TODO: Use TextEncoder when available.
+ */
+DataUtils.stringToUtf8Array = function(str) {
+    return DataUtils.toNumbersFromString(str2rstr_utf8(str));
+}
+
+/*
+ * arrays is an array of Uint8Array. Return a new Uint8Array which is the concatenation of all.
+ */
+DataUtils.concatArrays = function(arrays) {
+    var totalLength = 0;
+	for (var i = 0; i < arrays.length; ++i)
+        totalLength += arrays[i].length;
+    
+    var result = new Uint8Array(totalLength);
+    var offset = 0;
+	for (var i = 0; i < arrays.length; ++i) {
+        result.set(arrays[i], offset);
+        offset += arrays[i].length;
+    }
+    return result;
+    
+}
+ 
+// TODO: Take Uint8Array and use TextDecoder when available.
+DataUtils.decodeUtf8 = function (utftext) {
+		var string = "";
+		var i = 0;
+		var c = 0;
+        var c1 = 0;
+        var c2 = 0;
+ 
+		while ( i < utftext.length ) {
+ 
+			c = utftext.charCodeAt(i);
+ 
+			if (c < 128) {
+				string += String.fromCharCode(c);
+				i++;
+			}
+			else if((c > 191) && (c < 224)) {
+				c2 = utftext.charCodeAt(i+1);
+				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
+				i += 2;
+			}
+			else {
+				c2 = utftext.charCodeAt(i+1);
+				var c3 = utftext.charCodeAt(i+2);
+				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
+				i += 3;
+			}
+ 
+		}
+ 
+		return string;
+	};
+
+//NOT WORKING
+/*
+DataUtils.getUTF8StringFromBytes = function(bytes) {
+	
+	bytes = toString(bytes);
+
+    var ix = 0;
+ 
+    if( bytes.slice(0,3) == "\xEF\xBB\xBF") {
+        ix = 3;
+    }
+ 
+    var string = "";
+    for( ; ix < bytes.length; ix++ ) {
+        var byte1 = bytes[ix].charCodeAt(0);
+        if( byte1 < 0x80 ) {
+            string += String.fromCharCode(byte1);
+        } else if( byte1 >= 0xC2 && byte1 < 0xE0 ) {
+            var byte2 = bytes[++ix].charCodeAt(0);
+            string += String.fromCharCode(((byte1&0x1F)<<6) + (byte2&0x3F));
+        } else if( byte1 >= 0xE0 && byte1 < 0xF0 ) {
+            var byte2 = bytes[++ix].charCodeAt(0);
+            var byte3 = bytes[++ix].charCodeAt(0);
+            string += String.fromCharCode(((byte1&0xFF)<<12) + ((byte2&0x3F)<<6) + (byte3&0x3F));
+        } else if( byte1 >= 0xF0 && byte1 < 0xF5) {
+            var byte2 = bytes[++ix].charCodeAt(0);
+            var byte3 = bytes[++ix].charCodeAt(0);
+            var byte4 = bytes[++ix].charCodeAt(0);
+            var codepoint = ((byte1&0x07)<<18) + ((byte2&0x3F)<<12)+ ((byte3&0x3F)<<6) + (byte4&0x3F);
+            codepoint -= 0x10000;
+            string += String.fromCharCode(
+                (codepoint>>10) + 0xD800,
+                (codepoint&0x3FF) + 0xDC00
+            );
+        }
+    }
+ 
+    return string;
+}*/
+
+/**
+ * Return true if a1 and a2 are the same length with equal elements.
+ */
+DataUtils.arraysEqual = function(a1, a2){
+    if (a1.length != a2.length)
+        return false;
+    
+    for (var i = 0; i < a1.length; ++i) {
+        if (a1[i] != a2[i])
+            return false;
+    }
+
+    return true;
+};
+
+/*
+ * Convert the big endian Uint8Array to an unsigned int.
+ * Don't check for overflow.
+ */
+DataUtils.bigEndianToUnsignedInt = function(bytes) {
+    var result = 0;
+    for (var i = 0; i < bytes.length; ++i) {
+        result <<= 8;
+        result += bytes[i];
+    }
+    return result;
+};
+
+/*
+ * Convert the int value to a new big endian Uint8Array and return.
+ * If value is 0 or negative, return Uint8Array(0). 
+ */
+DataUtils.nonNegativeIntToBigEndian = function(value) {
+    value = Math.round(value);
+    if (value <= 0)
+        return new Uint8Array(0);
+    
+    // Assume value is not over 64 bits.
+    var size = 8;
+    var result = new Uint8Array(size);
+    var i = 0;
+    while (value != 0) {
+        ++i;
+        result[size - i] = value & 0xff;
+        value >>= 8;
+    }
+    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
+ * See COPYING for copyright and distribution information.
+ */
+
+function encodeToHexInterest(interest){
+    return DataUtils.toHex(encodeToBinaryInterest(interest));
+}
+
+
+function encodeToBinaryInterest(interest) {
+	var enc = new BinaryXMLEncoder();
+	interest.to_ccnb(enc);
+	
+	return enc.getReducedOstream();
+}
+
+
+function encodeToHexContentObject(co){
+    return DataUtils.toHex(encodeToBinaryContentObject(co));
+}
+
+function encodeToBinaryContentObject(co){
+	var enc = new BinaryXMLEncoder();
+	co.to_ccnb(enc);
+
+	return enc.getReducedOstream();
+}
+
+function encodeForwardingEntry(co){
+	var enc = new BinaryXMLEncoder();
+ 
+	co.to_ccnb(enc);
+	
+	var bytes = enc.getReducedOstream();
+
+	return bytes;
+
+	
+}
+
+
+
+function decodeHexFaceInstance(result){
+	
+	var numbers = DataUtils.toNumbers(result);
+			
+	
+	var decoder = new BinaryXMLDecoder(numbers);
+	
+	if(LOG>3)console.log('DECODING HEX FACE INSTANCE  \n'+numbers);
+
+	var faceInstance = new FaceInstance();
+
+	faceInstance.from_ccnb(decoder);
+
+	return faceInstance;
+	
+}
+
+
+
+function decodeHexInterest(result){
+	var numbers = DataUtils.toNumbers(result);	
+	
+	var decoder = new BinaryXMLDecoder(numbers);
+	
+	if(LOG>3)console.log('DECODING HEX INTERST  \n'+numbers);
+
+	var interest = new Interest();
+
+	interest.from_ccnb(decoder);
+
+	return interest;
+	
+}
+
+
+
+function decodeHexContentObject(result){
+	var numbers = DataUtils.toNumbers(result);
+	
+	var decoder = new BinaryXMLDecoder(numbers);
+	
+	if(LOG>3)console.log('DECODED HEX CONTENT OBJECT \n'+numbers);
+	
+	var co = new ContentObject();
+
+	co.from_ccnb(decoder);
+
+	return co;
+	
+}
+
+
+
+function decodeHexForwardingEntry(result){
+	var numbers = DataUtils.toNumbers(result);
+
+	var decoder = new BinaryXMLDecoder(numbers);
+	
+	if(LOG>3)console.log('DECODED HEX FORWARDING ENTRY \n'+numbers);
+	
+	var forwardingEntry = new ForwardingEntry();
+
+	forwardingEntry.from_ccnb(decoder);
+
+	return forwardingEntry;
+	
+}
+
+/*
+ * Decode the Uint8Array which holds SubjectPublicKeyInfo and return an RSAKey.
+ */
+function decodeSubjectPublicKeyInfo(array) {
+    var hex = DataUtils.toHex(array).toLowerCase();
+    var a = _x509_getPublicKeyHexArrayFromCertHex(hex, _x509_getSubjectPublicKeyPosFromCertHex(hex, 0));
+    var rsaKey = new RSAKey();
+    rsaKey.setPublic(a[0], a[1]);
+    return rsaKey;
+}
+
+/* Return a user friendly HTML string with the contents of co.
+   This also outputs to console.log.
+ */
+function contentObjectToHtml(/* ContentObject */ co) {
+    var output ="";
+			
+    if(co==-1)
+	output+= "NO CONTENT FOUND"
+    else if (co==-2)
+	output+= "CONTENT NAME IS EMPTY"
+    else{
+	if(co.name!=null && co.name.components!=null){
+	    output+= "NAME: " + co.name.to_uri();
+        
+	    output+= "<br />";
+	    output+= "<br />";
+	}
+	
+	if(co.content !=null){
+	    output += "CONTENT(ASCII): "+ DataUtils.toString(co.content);
+	    
+	    output+= "<br />";
+	    output+= "<br />";
+	}
+	if(co.content !=null){
+	    output += "CONTENT(hex): "+ DataUtils.toHex(co.content);
+	    
+	    output+= "<br />";
+	    output+= "<br />";
+	}
+	if(co.signature !=null && co.signature.signature!=null){
+	    output += "SIGNATURE(hex): "+ DataUtils.toHex(co.signature.signature);
+	    
+	    output+= "<br />";
+	    output+= "<br />";
+	}
+	if(co.signedInfo !=null && co.signedInfo.publisher!=null && co.signedInfo.publisher.publisherPublicKeyDigest!=null){
+	    output += "Publisher Public Key Digest(hex): "+ DataUtils.toHex(co.signedInfo.publisher.publisherPublicKeyDigest);
+	    
+	    output+= "<br />";
+	    output+= "<br />";
+	}
+	if(co.signedInfo !=null && co.signedInfo.timestamp!=null){
+	    var d = new Date();
+	    d.setTime( co.signedInfo.timestamp.msec );
+	    
+	    var bytes = [217, 185, 12, 225, 217, 185, 12, 225];
+	    
+	    output += "TimeStamp: "+d;
+	    output+= "<br />";
+	    output += "TimeStamp(number): "+ co.signedInfo.timestamp.msec;
+	    
+	    output+= "<br />";
+	}
+	if(co.signedInfo !=null && co.signedInfo.finalBlockID!=null){
+	    output += "FinalBlockID: "+ DataUtils.toHex(co.signedInfo.finalBlockID);
+	    output+= "<br />";
+	}
+	if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.certificate!=null){
+	    var certificateHex = DataUtils.toHex(co.signedInfo.locator.certificate).toLowerCase();
+	    var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
+	    var input = DataUtils.toString(co.rawSignatureData);
+	    
+	    output += "Hex Certificate: "+ certificateHex ;
+	    
+	    output+= "<br />";
+	    output+= "<br />";
+	    
+	    var x509 = new X509();
+	    x509.readCertHex(certificateHex);
+	    output += "Public key (hex) modulus: " + x509.subjectPublicKeyRSA.n.toString(16) + "<br/>";
+	    output += "exponent: " + x509.subjectPublicKeyRSA.e.toString(16) + "<br/>";
+	    output += "<br/>";
+	    
+	    var result = x509.subjectPublicKeyRSA.verifyByteArray(co.rawSignatureData, null, signature);
+	    if(LOG>2) console.log('result is '+result);
+	    
+	    var n = x509.subjectPublicKeyRSA.n;
+	    var e =  x509.subjectPublicKeyRSA.e;
+	    
+	    if(LOG>2) console.log('PUBLIC KEY n after is ');
+	    if(LOG>2) console.log(n);
+
+	    if(LOG>2) console.log('EXPONENT e after is ');
+	    if(LOG>2) console.log(e);
+	    
+	    if(result)
+            output += 'SIGNATURE VALID';
+	    else
+            output += 'SIGNATURE INVALID';
+	    
+	    //output += "VALID: "+ toHex(co.signedInfo.locator.publicKey);
+	    
+	    output+= "<br />";
+	    output+= "<br />";
+	    
+	    //if(LOG>4) console.log('str'[1]);
+	}
+	if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.publicKey!=null){
+	    var publickeyHex = DataUtils.toHex(co.signedInfo.locator.publicKey).toLowerCase();
+	    var publickeyString = DataUtils.toString(co.signedInfo.locator.publicKey);
+	    var signature = DataUtils.toHex(co.signature.signature).toLowerCase();
+	    var input = DataUtils.toString(co.rawSignatureData);
+	    
+	    var wit = null;
+	    var witHex = "";
+		if (co.signature.Witness != null) {
+			wit = new Witness();
+			wit.decode(co.signature.Witness);
+			witHex = DataUtils.toHex(co.signature.Witness);
+		}
+	    
+	    output += "Public key: " + publickeyHex;
+	    
+	    output+= "<br />";
+	    output+= "<br />";
+	    
+	    if(LOG>2) console.log(" ContentName + SignedInfo + Content = "+input);
+	    if(LOG>2) console.log(" PublicKeyHex = "+publickeyHex );
+	    if(LOG>2) console.log(" PublicKeyString = "+publickeyString );
+	    
+	    if(LOG>2) console.log(" Signature "+signature );
+	    if(LOG>2) console.log(" Witness "+witHex );
+	    
+	    if(LOG>2) console.log(" Signature NOW IS" );
+	    
+	    if(LOG>2) console.log(co.signature.signature);
+	   
+	    var rsakey = decodeSubjectPublicKeyInfo(co.signedInfo.locator.publicKey);
+
+	    output += "Public key (hex) modulus: " + rsakey.n.toString(16) + "<br/>";
+	    output += "exponent: " + rsakey.e.toString(16) + "<br/>";
+	    output += "<br/>";
+	   	    
+	    var result = rsakey.verifyByteArray(co.rawSignatureData, wit, signature);
+	    // var result = rsakey.verifyString(input, signature);
+	    
+	    if(LOG>2) console.log('PUBLIC KEY n after is ');
+	    if(LOG>2) console.log(rsakey.n);
+
+	    if(LOG>2) console.log('EXPONENT e after is ');
+	    if(LOG>2) console.log(rsakey.e);
+	    
+	    if(result)
+			output += 'SIGNATURE VALID';
+	    else
+			output += 'SIGNATURE INVALID';
+	    
+	    //output += "VALID: "+ toHex(co.signedInfo.locator.publicKey);
+	    
+	    output+= "<br />";
+	    output+= "<br />";
+	    
+	    //if(LOG>4) console.log('str'[1]);
+	}
+    }
+
+    return output;
+}
+
+
+/**
+ * @author: Meki Cheraoui
+ * See COPYING for copyright and distribution information.
+ */
+
+var KeyManager = function KeyManager(){
+
+	
+//Certificate
+
+this.certificate = 'MIIBmzCCAQQCCQC32FyQa61S7jANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwd'+
+
+'heGVsY2R2MB4XDTEyMDQyODIzNDQzN1oXDTEyMDUyODIzNDQzN1owEjEQMA4GA1'+
+
+'UEAxMHYXhlbGNkdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4X0wp9goq'+
+
+'xuECxdULcr2IHr9Ih4Iaypg0Wy39URIup8/CLzQmdsh3RYqd55hqonu5VTTpH3i'+
+
+'MLx6xZDVJAZ8OJi7pvXcQ2C4Re2kjL2c8SanI0RfDhlS1zJadfr1VhRPmpivcYa'+
+
+'wJ4aFuOLAi+qHFxtN7lhcGCgpW1OV60oXd58CAwEAATANBgkqhkiG9w0BAQUFAA'+
+
+'OBgQDLOrA1fXzSrpftUB5Ro6DigX1Bjkf7F5Bkd69hSVp+jYeJFBBlsILQAfSxU'+
+
+'ZPQtD+2Yc3iCmSYNyxqu9PcufDRJlnvB7PG29+L3y9lR37tetzUV9eTscJ7rdp8'+
+
+'Wt6AzpW32IJ/54yKNfP7S6ZIoIG+LP6EIxq6s8K1MXRt8uBJKw==';
+
+
+//this.publicKey = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQAB';
+this.publicKey ='30819F300D06092A864886F70D010101050003818D0030818902818100E17D30A7D828AB1B840B17542DCAF6207AFD221E086B2A60D16CB7F54448BA9F3F08BCD099DB21DD162A779E61AA89EEE554D3A47DE230BC7AC590D524067C3898BBA6F5DC4360B845EDA48CBD9CF126A723445F0E1952D7325A75FAF556144F9A98AF7186B0278685B8E2C08BEA87171B4DEE585C1828295B5395EB4A17779F0203010001';
+//Private Key
+
+this.privateKey ='MIICXQIBAAKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQABAoGAGkv6T6jC3WmhFZYL6CdCWvlc6gysmKrhjarrLTxgavtFY6R5g2ft5BXAsCCVbUkWxkIFSKqxpVNl0gKZCNGEzPDN6mHJOQI/h0rlxNIHAuGfoAbCzALnqmyZivhJAPGijAyKuU9tczsst5+Kpn+bn7ehzHQuj7iwJonS5WbojqECQQD851K8TpW2GrRizNgG4dx6orZxAaon/Jnl8lS7soXhllQty7qG+oDfzznmdMsiznCqEABzHUUKOVGE9RWPN3aRAkEA5D/w9N55d0ibnChFJlc8cUAoaqH+w+U3oQP2Lb6AZHJpLptN4y4b/uf5d4wYU5/i/gC7SSBH3wFhh9bjRLUDLwJAVOx8vN0Kqt7myfKNbCo19jxjVSlA8TKCn1Oznl/BU1I+rC4oUaEW25DjmX6IpAR8kq7S59ThVSCQPjxqY/A08QJBAIRaF2zGPITQk3r/VumemCvLWiRK/yG0noc9dtibqHOWbCtcXtOm/xDWjq+lis2i3ssOvYrvrv0/HcDY+Dv1An0CQQCLJtMsfSg4kvG/FRY5UMhtMuwo8ovYcMXt4Xv/LWaMhndD67b2UGawQCRqr5ghRTABWdDD/HuuMBjrkPsX0861';
+
+
+/*
+	this.certificate = 
+			'MIIBvTCCASYCCQD55fNzc0WF7TANBgkqhkiG9w0BAQUFADAjMQswCQYDVQQGEwJK'+
+			'UDEUMBIGA1UEChMLMDAtVEVTVC1SU0EwHhcNMTAwNTI4MDIwODUxWhcNMjAwNTI1'+
+			'MDIwODUxWjAjMQswCQYDVQQGEwJKUDEUMBIGA1UEChMLMDAtVEVTVC1SU0EwgZ8w'+
+			'DQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANGEYXtfgDRlWUSDn3haY4NVVQiKI9Cz'+
+			'Thoua9+DxJuiseyzmBBe7Roh1RPqdvmtOHmEPbJ+kXZYhbozzPRbFGHCJyBfCLzQ'+
+			'fVos9/qUQ88u83b0SFA2MGmQWQAlRtLy66EkR4rDRwTj2DzR4EEXgEKpIvo8VBs/'+
+			'3+sHLF3ESgAhAgMBAAEwDQYJKoZIhvcNAQEFBQADgYEAEZ6mXFFq3AzfaqWHmCy1'+
+			'ARjlauYAa8ZmUFnLm0emg9dkVBJ63aEqARhtok6bDQDzSJxiLpCEF6G4b/Nv/M/M'+
+			'LyhP+OoOTmETMegAVQMq71choVJyOFE5BtQa6M/lCHEOya5QUfoRF2HF9EjRF44K'+
+			'3OK+u3ivTSj3zwjtpudY5Xo=';
+	
+	this.privateKey =
+			'MIICWwIBAAKBgQDRhGF7X4A0ZVlEg594WmODVVUIiiPQs04aLmvfg8SborHss5gQ'+
+			'Xu0aIdUT6nb5rTh5hD2yfpF2WIW6M8z0WxRhwicgXwi80H1aLPf6lEPPLvN29EhQ'+
+			'NjBpkFkAJUbS8uuhJEeKw0cE49g80eBBF4BCqSL6PFQbP9/rByxdxEoAIQIDAQAB'+
+			'AoGAA9/q3Zk6ib2GFRpKDLO/O2KMnAfR+b4XJ6zMGeoZ7Lbpi3MW0Nawk9ckVaX0'+
+			'ZVGqxbSIX5Cvp/yjHHpww+QbUFrw/gCjLiiYjM9E8C3uAF5AKJ0r4GBPl4u8K4bp'+
+			'bXeSxSB60/wPQFiQAJVcA5xhZVzqNuF3EjuKdHsw+dk+dPECQQDubX/lVGFgD/xY'+
+			'uchz56Yc7VHX+58BUkNSewSzwJRbcueqknXRWwj97SXqpnYfKqZq78dnEF10SWsr'+
+			'/NMKi+7XAkEA4PVqDv/OZAbWr4syXZNv/Mpl4r5suzYMMUD9U8B2JIRnrhmGZPzL'+
+			'x23N9J4hEJ+Xh8tSKVc80jOkrvGlSv+BxwJAaTOtjA3YTV+gU7Hdza53sCnSw/8F'+
+			'YLrgc6NOJtYhX9xqdevbyn1lkU0zPr8mPYg/F84m6MXixm2iuSz8HZoyzwJARi2p'+
+			'aYZ5/5B2lwroqnKdZBJMGKFpUDn7Mb5hiSgocxnvMkv6NjT66Xsi3iYakJII9q8C'+
+			'Ma1qZvT/cigmdbAh7wJAQNXyoizuGEltiSaBXx4H29EdXNYWDJ9SS5f070BRbAIl'+
+			'dqRh3rcNvpY6BKJqFapda1DjdcncZECMizT/GMrc1w==';
+			
+			*/
+};
+
+
+KeyManager.prototype.verify = function verify(message,signature){
+	
+	var input = message;
+
+	var  _PEM_X509CERT_STRING_ = this.certificate;
+	
+	var x509 = new X509();
+	
+	x509.readCertPEM(_PEM_X509CERT_STRING_);
+	
+	var result = x509.subjectPublicKeyRSA.verifyString(input, signature);
+	
+	return result;
+};
+
+KeyManager.prototype.sign= function sign(message){
+	
+	var input = message;
+		
+	var  _PEM_PRIVATE_KEY_STRING_ = this.privateKey;
+	
+	var rsa = new RSAKey();
+	
+	rsa.readPrivateKeyFromPEMString(_PEM_PRIVATE_KEY_STRING_);
+	
+	var hSig = rsa.signString(input, "sha256");
+	
+	return hSig;
+
+};
+
+
+
+var globalKeyManager = new KeyManager();
+//var KeyPair = { "public" : "PUBLIC KEY" , "private" : "PRIVATE KEY" };
+
+
+/** 
+ * @author: Wentao Shang
+ * See COPYING for copyright and distribution information.
+ */
+
+var MerklePath = function MerkelPath() {
+	this.index = null;  // int
+	this.digestList = [];  // array of hex string
+};
+
+var Witness = function Witness() {
+	this.oid = null;  // string
+	this.path = new MerklePath();  // MerklePath
+};
+
+function parseOID(bytes, start, end) {
+    var s, n = 0, bits = 0;
+    for (var i = start; i < end; ++i) {
+        var v = bytes[i];
+        n = (n << 7) | (v & 0x7F);
+        bits += 7;
+        if (!(v & 0x80)) { // finished
+            if (s == undefined)
+                s = parseInt(n / 40) + "." + (n % 40);
+            else
+                s += "." + ((bits >= 31) ? "bigint" : n);
+            n = bits = 0;
+        }
+        s += String.fromCharCode();
+    }
+    return s;
+}
+
+function parseInteger(bytes, start, end) {
+    var n = 0;
+    for (var i = start; i < end; ++i)
+        n = (n << 8) | bytes[i];
+    return n;
+}
+
+Witness.prototype.decode = function(/* Uint8Array */ witness) {
+	/* The asn1.js decoder has some bug and 
+	 * cannot decode certain kind of witness.
+	 * So we use an alternative (and dirty) hack
+	 * to read witness from byte streams
+	 *      ------Wentao
+	 */
+	/*
+	var wit = DataUtils.toHex(witness).toLowerCase();
+	try {
+		var der = Hex.decode(wit);
+		var asn1 = ASN1.decode(der);
+	}
+	catch (e) {
+		console.log(e);
+		console.log(wit);
+	}
+	//console.log(asn1.toPrettyString());
+	
+	this.oid = asn1.sub[0].sub[0].content();  // OID
+	//console.log(this.oid);
+	this.path.index = asn1.sub[1].sub[0].sub[0].content();  // index
+	//console.log(this.path.index);
+	for (i = 0; i < asn1.sub[1].sub[0].sub[1].sub.length; i++) {
+		pos = asn1.sub[1].sub[0].sub[1].sub[i].stream.pos;
+		str = wit.substring(2 * pos + 4, 2 * pos + 68);
+		this.path.digestList.push(str);  // digest hex string
+		//console.log(str);
+	}
+	*/
+	
+	// FIXME: Need to be fixed to support arbitrary ASN1 encoding,
+	// But do we really nned that????  -------Wentao
+	
+	// The structure of Witness is fixed as follows:
+	// SEQUENCE  (2 elem)
+	//   SEQUENCE  (1 elem)
+	//     OBJECT IDENTIFIER  1.2.840.113550.11.1.2.2
+	//   OCTET STRING  (1 elem)
+	//     SEQUENCE  (2 elem)
+	//       INTEGER  index
+	//       SEQUENCE  (n elem)
+	//         OCTET STRING(32 byte) 345FB4B5E9A1D2FF450ECA87EB87601683027A1A...
+	//         OCTET STRING(32 byte) DBCEE5B7A6C2B851B029324197DDBD9A655723DC...
+	//         OCTET STRING(32 byte) 4C79B2D256E4CD657A27F01DCB51AC3C56A24E71...
+	//         OCTET STRING(32 byte) 7F7FB169604A87EAC94378F0BDB4FC5D5899AB88...
+	//         ......
+	// Hence we can follow this structure to extract witness fields at fixed level
+	// Tag numbers for ASN1:
+	//    SEQUENCE            0x10
+	//    OCT STRING          0x04
+	//    INTEGER             0x02
+	//    OBJECT IDENTIFIER   0x06
+	var i = 0;
+	var step = 0;  // count of sequence tag
+	while (i < witness.length) {
+		var len = 0;
+		
+		if (witness[i] == 0x30) {
+			// Sequence (constructed)
+			// There is no primitive sequence in Witness
+			if ((witness[i + 1] & 0x80) != 0) {
+				len = witness[i+1] & 0x7F;
+			}
+			step++;
+		} else if (witness[i] == 0x06) {
+			// Decode OID
+			len = witness[i+1];  // XXX: OID will not be longer than 127 bytes
+			this.oid = parseOID(witness, i + 2, i + 2 + len);
+			//console.log(this.oid);
+		} else if (witness[i] == 0x02) {
+			// Decode node index
+			len = witness[i+1];  // XXX: index will not be longer than 127 bytes
+			this.path.index = parseInteger(witness, i + 2, i + 2 + len);
+			//console.log(this.path.index);
+		} else if (witness[i] == 0x04) {
+			if ((witness[i + 1] & 0x80) != 0) {
+				len = witness[i+1] & 0x7F;
+			}
+			if (step == 4) {
+				// Start to decode digest hex string
+				len = witness[i+1];  // XXX: digest hex should always be 32 bytes
+				var str = DataUtils.toHex(witness.subarray(i + 2, i + 2 + len));
+				this.path.digestList.push(str);  // digest hex string
+				//console.log(str);
+			}
+		}
+		i = i + 2 + len;
+	}
+};
+/*
+ * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined
+ * in FIPS 180-2
+ * Version 2.2 Copyright Angel Marin, Paul Johnston 2000 - 2009.
+ * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
+ * Distributed under the BSD License
+ * See http://pajhome.org.uk/crypt/md5 for details.
+ * Also http://anmar.eu.org/projects/jssha2/
+ */
+
+/*
+ * Configurable variables. You may need to tweak these to be compatible with
+ * the server-side, but the defaults work in most cases.
+ */
+var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
+var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
+
+/*
+ * These are the functions you'll usually want to call
+ * They take string arguments and return either hex or base-64 encoded strings
+ */
+
+//@author axelcdv
+/**
+ * Computes the Sha-256 hash of the given byte array
+ * @param {byte[]} 
+ * @return the hex string corresponding to the Sha-256 hash of the byte array
+ */
+function hex_sha256_from_bytes(byteArray){
+	return rstr2hex(binb2rstr(binb_sha256( byteArray2binb(byteArray), byteArray.length * 8)));
+}
+
+function hex_sha256(s)    { return rstr2hex(rstr_sha256(str2rstr_utf8(s))); }
+function b64_sha256(s)    { return rstr2b64(rstr_sha256(str2rstr_utf8(s))); }
+function any_sha256(s, e) { return rstr2any(rstr_sha256(str2rstr_utf8(s)), e); }
+function hex_hmac_sha256(k, d)
+  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function b64_hmac_sha256(k, d)
+  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d))); }
+function any_hmac_sha256(k, d, e)
+  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), str2rstr_utf8(d)), e); }
+
+	
+/*
+	function hex_sha256(s)    { return rstr2hex(rstr_sha256(s)); }
+function b64_sha256(s)    { return rstr2b64(rstr_sha256(s)); }
+function any_sha256(s, e) { return rstr2any(rstr_sha256(s), e); }
+function hex_hmac_sha256(k, d)
+  { return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
+function b64_hmac_sha256(k, d)
+  { return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(k), d)); }
+function any_hmac_sha256(k, d, e)
+  { return rstr2any(rstr_hmac_sha256(str2rstr_utf8(k), d), e); }
+*/
+	
+/*
+ * Perform a simple self-test to see if the VM is working
+ */
+function sha256_vm_test()
+{
+  return hex_sha256("abc").toLowerCase() ==
+            "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad";
+}
+
+/**
+ * Calculate the sha256 of a raw string
+ * @param s: the raw string
+ */
+function rstr_sha256(s)
+{
+  return binb2rstr(binb_sha256(rstr2binb(s), s.length * 8));
+}
+
+/**
+ * Calculate the HMAC-sha256 of a key and some data (raw strings)
+ */
+function rstr_hmac_sha256(key, data)
+{
+  var bkey = rstr2binb(key);
+  if(bkey.length > 16) bkey = binb_sha256(bkey, key.length * 8);
+
+  var ipad = Array(16), opad = Array(16);
+  for(var i = 0; i < 16; i++)
+  {
+    ipad[i] = bkey[i] ^ 0x36363636;
+    opad[i] = bkey[i] ^ 0x5C5C5C5C;
+  }
+
+  var hash = binb_sha256(ipad.concat(rstr2binb(data)), 512 + data.length * 8);
+  return binb2rstr(binb_sha256(opad.concat(hash), 512 + 256));
+}
+
+/**
+ * Convert a raw string to a hex string
+ */
+function rstr2hex(input)
+{
+  try { hexcase } catch(e) { hexcase=0; }
+  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
+  var output = "";
+  var x;
+  for(var i = 0; i < input.length; i++)
+  {
+    x = input.charCodeAt(i);
+    output += hex_tab.charAt((x >>> 4) & 0x0F)
+           +  hex_tab.charAt( x        & 0x0F);
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to a base-64 string
+ */
+function rstr2b64(input)
+{
+  try { b64pad } catch(e) { b64pad=''; }
+  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  var output = "";
+  var len = input.length;
+  for(var i = 0; i < len; i += 3)
+  {
+    var triplet = (input.charCodeAt(i) << 16)
+                | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
+                | (i + 2 < len ? input.charCodeAt(i+2)      : 0);
+    for(var j = 0; j < 4; j++)
+    {
+      if(i * 8 + j * 6 > input.length * 8) output += b64pad;
+      else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
+    }
+  }
+  return output;
+}
+
+/*
+ * Convert a raw string to an arbitrary string encoding
+ */
+function rstr2any(input, encoding)
+{
+  var divisor = encoding.length;
+  var remainders = Array();
+  var i, q, x, quotient;
+
+  /* Convert to an array of 16-bit big-endian values, forming the dividend */
+  var dividend = Array(Math.ceil(input.length / 2));
+  for(i = 0; i < dividend.length; i++)
+  {
+    dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
+  }
+
+  /*
+   * Repeatedly perform a long division. The binary array forms the dividend,
+   * the length of the encoding is the divisor. Once computed, the quotient
+   * forms the dividend for the next step. We stop when the dividend is zero.
+   * All remainders are stored for later use.
+   */
+  while(dividend.length > 0)
+  {
+    quotient = Array();
+    x = 0;
+    for(i = 0; i < dividend.length; i++)
+    {
+      x = (x << 16) + dividend[i];
+      q = Math.floor(x / divisor);
+      x -= q * divisor;
+      if(quotient.length > 0 || q > 0)
+        quotient[quotient.length] = q;
+    }
+    remainders[remainders.length] = x;
+    dividend = quotient;
+  }
+
+  /* Convert the remainders to the output string */
+  var output = "";
+  for(i = remainders.length - 1; i >= 0; i--)
+    output += encoding.charAt(remainders[i]);
+
+  /* Append leading zero equivalents */
+  var full_length = Math.ceil(input.length * 8 /
+                                    (Math.log(encoding.length) / Math.log(2)))
+  for(i = output.length; i < full_length; i++)
+    output = encoding[0] + output;
+
+  return output;
+}
+
+/*
+ * Encode a string as utf-8.
+ * For efficiency, this assumes the input is valid utf-16.
+ */
+function str2rstr_utf8(input)
+{
+  var output = "";
+  var i = -1;
+  var x, y;
+
+  while(++i < input.length)
+  {
+    /* Decode utf-16 surrogate pairs */
+    x = input.charCodeAt(i);
+    y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
+    if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF)
+    {
+      x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
+      i++;
+    }
+
+    /* Encode output as utf-8 */
+    if(x <= 0x7F)
+      output += String.fromCharCode(x);
+    else if(x <= 0x7FF)
+      output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0xFFFF)
+      output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+    else if(x <= 0x1FFFFF)
+      output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
+                                    0x80 | ((x >>> 12) & 0x3F),
+                                    0x80 | ((x >>> 6 ) & 0x3F),
+                                    0x80 | ( x         & 0x3F));
+  }
+  return output;
+}
+
+/*
+ * Encode a string as utf-16
+ */
+function str2rstr_utf16le(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode( input.charCodeAt(i)        & 0xFF,
+                                  (input.charCodeAt(i) >>> 8) & 0xFF);
+  return output;
+}
+
+function str2rstr_utf16be(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length; i++)
+    output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
+                                   input.charCodeAt(i)        & 0xFF);
+  return output;
+}
+
+/**
+ * Convert a raw string to an array of big-endian words
+ * Characters >255 have their high-byte silently ignored.
+ */
+function rstr2binb(input)
+{
+  //console.log('Raw string comming is '+input);
+  var output = Array(input.length >> 2);
+  /* JavaScript automatically zeroizes a new array.
+  for(var i = 0; i < output.length; i++)
+    output[i] = 0;
+   */
+  for(var i = 0; i < input.length * 8; i += 8)
+    output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (24 - i % 32);
+  return output;
+}
+
+/**
+ * @author axelcdv
+ * Convert a byte array to an array of big-endian words
+ * @param {byte[]} input
+ * @return the array of big-endian words
+ */
+function byteArray2binb(input){
+	//console.log("Byte array coming is " + input);
+	var output = Array(input.length >> 2);
+      /* JavaScript automatically zeroizes a new array.
+	  for(var i = 0; i < output.length; i++)
+	    output[i] = 0;
+       */
+	  for(var i = 0; i < input.length * 8; i += 8)
+	    output[i>>5] |= (input[i / 8] & 0xFF) << (24 - i % 32);
+	  return output;
+}
+
+/*
+ * Convert an array of big-endian words to a string
+ */
+function binb2rstr(input)
+{
+  var output = "";
+  for(var i = 0; i < input.length * 32; i += 8)
+    output += String.fromCharCode((input[i>>5] >>> (24 - i % 32)) & 0xFF);
+  return output;
+}
+
+/*
+ * Main sha256 function, with its support functions
+ */
+function sha256_S (X, n) {return ( X >>> n ) | (X << (32 - n));}
+function sha256_R (X, n) {return ( X >>> n );}
+function sha256_Ch(x, y, z) {return ((x & y) ^ ((~x) & z));}
+function sha256_Maj(x, y, z) {return ((x & y) ^ (x & z) ^ (y & z));}
+function sha256_Sigma0256(x) {return (sha256_S(x, 2) ^ sha256_S(x, 13) ^ sha256_S(x, 22));}
+function sha256_Sigma1256(x) {return (sha256_S(x, 6) ^ sha256_S(x, 11) ^ sha256_S(x, 25));}
+function sha256_Gamma0256(x) {return (sha256_S(x, 7) ^ sha256_S(x, 18) ^ sha256_R(x, 3));}
+function sha256_Gamma1256(x) {return (sha256_S(x, 17) ^ sha256_S(x, 19) ^ sha256_R(x, 10));}
+function sha256_Sigma0512(x) {return (sha256_S(x, 28) ^ sha256_S(x, 34) ^ sha256_S(x, 39));}
+function sha256_Sigma1512(x) {return (sha256_S(x, 14) ^ sha256_S(x, 18) ^ sha256_S(x, 41));}
+function sha256_Gamma0512(x) {return (sha256_S(x, 1)  ^ sha256_S(x, 8) ^ sha256_R(x, 7));}
+function sha256_Gamma1512(x) {return (sha256_S(x, 19) ^ sha256_S(x, 61) ^ sha256_R(x, 6));}
+
+var sha256_K = new Array
+(
+  1116352408, 1899447441, -1245643825, -373957723, 961987163, 1508970993,
+  -1841331548, -1424204075, -670586216, 310598401, 607225278, 1426881987,
+  1925078388, -2132889090, -1680079193, -1046744716, -459576895, -272742522,
+  264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986,
+  -1740746414, -1473132947, -1341970488, -1084653625, -958395405, -710438585,
+  113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291,
+  1695183700, 1986661051, -2117940946, -1838011259, -1564481375, -1474664885,
+  -1035236496, -949202525, -778901479, -694614492, -200395387, 275423344,
+  430227734, 506948616, 659060556, 883997877, 958139571, 1322822218,
+  1537002063, 1747873779, 1955562222, 2024104815, -2067236844, -1933114872,
+  -1866530822, -1538233109, -1090935817, -965641998
+);
+
+function binb_sha256(m, l)
+{
+  var HASH = new Array(1779033703, -1150833019, 1013904242, -1521486534,
+                       1359893119, -1694144372, 528734635, 1541459225);
+  var W = new Array(64);
+
+  /* append padding */
+  m[l >> 5] |= 0x80 << (24 - l % 32);
+  m[((l + 64 >> 9) << 4) + 15] = l;
+ 
+  for(var offset = 0; offset < m.length; offset += 16)
+    processBlock_sha256(m, offset, HASH, W);
+
+  return HASH;
+}
+
+/*
+ * Process a block of 16 4-byte words in m starting at offset and update HASH.  
+ * offset must be a multiple of 16 and less than m.length.  W is a scratchpad Array(64).
+ */
+function processBlock_sha256(m, offset, HASH, W) {
+    var a, b, c, d, e, f, g, h;
+    var j, T1, T2;
+    
+    a = HASH[0];
+    b = HASH[1];
+    c = HASH[2];
+    d = HASH[3];
+    e = HASH[4];
+    f = HASH[5];
+    g = HASH[6];
+    h = HASH[7];
+
+    for(j = 0; j < 64; j++)
+    {
+      if (j < 16) W[j] = m[j + offset];
+      else W[j] = safe_add(safe_add(safe_add(sha256_Gamma1256(W[j - 2]), W[j - 7]),
+                                            sha256_Gamma0256(W[j - 15])), W[j - 16]);
+
+      T1 = safe_add(safe_add(safe_add(safe_add(h, sha256_Sigma1256(e)), sha256_Ch(e, f, g)),
+                                                          sha256_K[j]), W[j]);
+      T2 = safe_add(sha256_Sigma0256(a), sha256_Maj(a, b, c));
+      h = g;
+      g = f;
+      f = e;
+      e = safe_add(d, T1);
+      d = c;
+      c = b;
+      b = a;
+      a = safe_add(T1, T2);
+    }
+
+    HASH[0] = safe_add(a, HASH[0]);
+    HASH[1] = safe_add(b, HASH[1]);
+    HASH[2] = safe_add(c, HASH[2]);
+    HASH[3] = safe_add(d, HASH[3]);
+    HASH[4] = safe_add(e, HASH[4]);
+    HASH[5] = safe_add(f, HASH[5]);
+    HASH[6] = safe_add(g, HASH[6]);
+    HASH[7] = safe_add(h, HASH[7]);
+}
+
+function safe_add (x, y)
+{
+  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
+  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
+  return (msw << 16) | (lsw & 0xFFFF);
+}
+
+/*
+ * Create a Sha256, call update(data) multiple times, then call finalize().
+ */
+var Sha256 = function Sha256() {
+    this.W = new Array(64);
+    this.hash = new Array(1779033703, -1150833019, 1013904242, -1521486534,
+                          1359893119, -1694144372, 528734635, 1541459225);
+    this.nTotalBytes = 0;
+    this.buffer = new Uint8Array(16 * 4);
+    this.nBufferBytes = 0;
+}
+
+/*
+ * Update the hash with data, which is Uint8Array.
+ */
+Sha256.prototype.update = function(data) {
+    this.nTotalBytes += data.length;
+    
+    if (this.nBufferBytes > 0) {
+        // Fill up the buffer and process it first.
+        var bytesNeeded = this.buffer.length - this.nBufferBytes;
+        if (data.length < bytesNeeded) {
+            this.buffer.set(data, this.nBufferBytes);
+            this.nBufferBytes += data.length;
+            return;
+        }
+        else {
+            this.buffer.set(data.subarray(0, bytesNeeded), this.nBufferBytes);
+            processBlock_sha256(byteArray2binb(this.buffer), 0, this.hash, this.W);
+            this.nBufferBytes = 0;
+            // Consume the bytes from data.
+            data = data.subarray(bytesNeeded, data.length);
+            if (data.length == 0)
+                return;
+        }
+    }
+    
+    // 2^6 is 16 * 4.
+    var nBlocks = data.length >> 6;
+    if (nBlocks > 0) {
+        var nBytes = nBlocks * 16 * 4;
+        var m = byteArray2binb(data.subarray(0, nBytes));
+        for(var offset = 0; offset < m.length; offset += 16)
+            processBlock_sha256(m, offset, this.hash, this.W);
+
+        data = data.subarray(nBytes, data.length);
+    }
+    
+    if (data.length > 0) {
+        // Save the remainder in the buffer.
+        this.buffer.set(data);
+        this.nBufferBytes = data.length;
+    }
+}
+
+/*
+ * Finalize the hash and return the result as Uint8Array.
+ * Only call this once.  Return values on subsequent calls are undefined.
+ */
+Sha256.prototype.finalize = function() {
+    var m = byteArray2binb(this.buffer.subarray(0, this.nBufferBytes));
+    /* append padding */
+    var l = this.nBufferBytes * 8;
+    m[l >> 5] |= 0x80 << (24 - l % 32);
+    m[((l + 64 >> 9) << 4) + 15] = this.nTotalBytes * 8;
+
+    for(var offset = 0; offset < m.length; offset += 16)
+        processBlock_sha256(m, offset, this.hash, this.W);
+
+    return Sha256.binb2Uint8Array(this.hash);
+}
+
+/*
+ * Convert an array of big-endian words to Uint8Array.
+ */
+Sha256.binb2Uint8Array = function(input)
+{
+    var output = new Uint8Array(input.length * 4);
+    var iOutput = 0;
+    for (var i = 0; i < input.length * 32; i += 8)
+        output[iOutput++] = (input[i>>5] >>> (24 - i % 32)) & 0xFF;
+    return output;
+}
+var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var b64pad="=";
+
+function hex2b64(h) {
+  var i;
+  var c;
+  var ret = "";
+  for(i = 0; i+3 <= h.length; i+=3) {
+    c = parseInt(h.substring(i,i+3),16);
+    ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63);
+  }
+  if(i+1 == h.length) {
+    c = parseInt(h.substring(i,i+1),16);
+    ret += b64map.charAt(c << 2);
+  }
+  else if(i+2 == h.length) {
+    c = parseInt(h.substring(i,i+2),16);
+    ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4);
+  }
+  while((ret.length & 3) > 0) ret += b64pad;
+  return ret;
+}
+
+// convert a base64 string to hex
+function b64tohex(s) {
+  var ret = ""
+  var i;
+  var k = 0; // b64 state, 0-3
+  var slop;
+  for(i = 0; i < s.length; ++i) {
+    if(s.charAt(i) == b64pad) break;
+    var v = b64map.indexOf(s.charAt(i));
+    if(v < 0) continue;
+    if(k == 0) {
+      ret += int2char(v >> 2);
+      slop = v & 3;
+      k = 1;
+    }
+    else if(k == 1) {
+      ret += int2char((slop << 2) | (v >> 4));
+      slop = v & 0xf;
+      k = 2;
+    }
+    else if(k == 2) {
+      ret += int2char(slop);
+      ret += int2char(v >> 2);
+      slop = v & 3;
+      k = 3;
+    }
+    else {
+      ret += int2char((slop << 2) | (v >> 4));
+      ret += int2char(v & 0xf);
+      k = 0;
+    }
+  }
+  if(k == 1)
+    ret += int2char(slop << 2);
+  return ret;
+}
+
+// convert a base64 string to a byte/number array
+function b64toBA(s) {
+  //piggyback on b64tohex for now, optimize later
+  var h = b64tohex(s);
+  var i;
+  var a = new Array();
+  for(i = 0; 2*i < h.length; ++i) {
+    a[i] = parseInt(h.substring(2*i,2*i+2),16);
+  }
+  return a;
+}
+// Depends on jsbn.js and rng.js
+
+// Version 1.1: support utf-8 encoding in pkcs1pad2
+
+// convert a (hex) string to a bignum object
+function parseBigInt(str,r) {
+  return new BigInteger(str,r);
+}
+
+function linebrk(s,n) {
+  var ret = "";
+  var i = 0;
+  while(i + n < s.length) {
+    ret += s.substring(i,i+n) + "\n";
+    i += n;
+  }
+  return ret + s.substring(i,s.length);
+}
+
+function byte2Hex(b) {
+  if(b < 0x10)
+    return "0" + b.toString(16);
+  else
+    return b.toString(16);
+}
+
+/**
+ * PKCS#1 (type 2, random) pad input string s to n bytes, and return a bigint
+ * @param s: the string to encode
+ * @param n: the size in byte
+ */ 
+function pkcs1pad2(s,n) {
+  if(n < s.length + 11) { // TODO: fix for utf-8
+    alert("Message too long for RSA");
+    return null;
+  }
+  var ba = new Array();
+  var i = s.length - 1;
+  while(i >= 0 && n > 0) {
+    var c = s.charCodeAt(i--);
+    if(c < 128) { // encode using utf-8
+      ba[--n] = c;
+    }
+    else if((c > 127) && (c < 2048)) {
+      ba[--n] = (c & 63) | 128;
+      ba[--n] = (c >> 6) | 192;
+    }
+    else {
+      ba[--n] = (c & 63) | 128;
+      ba[--n] = ((c >> 6) & 63) | 128;
+      ba[--n] = (c >> 12) | 224;
+    }
+  }
+  ba[--n] = 0;
+  var rng = new SecureRandom();
+  var x = new Array();
+  while(n > 2) { // random non-zero pad
+    x[0] = 0;
+    while(x[0] == 0) rng.nextBytes(x);
+    ba[--n] = x[0];
+  }
+  ba[--n] = 2;
+  ba[--n] = 0;
+  return new BigInteger(ba);
+}
+
+/** 
+ * "empty" RSA key constructor
+ * @returns {RSAKey}
+ */
+function RSAKey() {
+  this.n = null;
+  this.e = 0;
+  this.d = null;
+  this.p = null;
+  this.q = null;
+  this.dmp1 = null;
+  this.dmq1 = null;
+  this.coeff = null;
+}
+
+/** 
+ * Set the public key fields N and e from hex strings
+ * @param N
+ * @param E
+ * @returns {RSASetPublic}
+ */
+function RSASetPublic(N,E) {
+  if(N != null && E != null && N.length > 0 && E.length > 0) {
+    this.n = parseBigInt(N,16);
+    this.e = parseInt(E,16);
+  }
+  else
+    alert("Invalid RSA public key");
+}
+
+/** 
+ * Perform raw public operation on "x": return x^e (mod n)
+ * @param x
+ * @returns x^e (mod n)
+ */
+function RSADoPublic(x) {
+  return x.modPowInt(this.e, this.n);
+}
+
+/**
+ * Return the PKCS#1 RSA encryption of "text" as an even-length hex string
+ */ 
+function RSAEncrypt(text) {
+  var m = pkcs1pad2(text,(this.n.bitLength()+7)>>3);
+  if(m == null) return null;
+  var c = this.doPublic(m);
+  if(c == null) return null;
+  var h = c.toString(16);
+  if((h.length & 1) == 0) return h; else return "0" + h;
+}
+
+// Return the PKCS#1 RSA encryption of "text" as a Base64-encoded string
+//function RSAEncryptB64(text) {
+//  var h = this.encrypt(text);
+//  if(h) return hex2b64(h); else return null;
+//}
+
+// protected
+RSAKey.prototype.doPublic = RSADoPublic;
+
+// public
+RSAKey.prototype.setPublic = RSASetPublic;
+RSAKey.prototype.encrypt = RSAEncrypt;
+//RSAKey.prototype.encrypt_b64 = RSAEncryptB64;
+// Depends on rsa.js and jsbn2.js
+
+// Version 1.1: support utf-8 decoding in pkcs1unpad2
+
+// Undo PKCS#1 (type 2, random) padding and, if valid, return the plaintext
+function pkcs1unpad2(d,n) {
+  var b = d.toByteArray();
+  var i = 0;
+  while(i < b.length && b[i] == 0) ++i;
+  if(b.length-i != n-1 || b[i] != 2)
+    return null;
+  ++i;
+  while(b[i] != 0)
+    if(++i >= b.length) return null;
+  var ret = "";
+  while(++i < b.length) {
+    var c = b[i] & 255;
+    if(c < 128) { // utf-8 decode
+      ret += String.fromCharCode(c);
+    }
+    else if((c > 191) && (c < 224)) {
+      ret += String.fromCharCode(((c & 31) << 6) | (b[i+1] & 63));
+      ++i;
+    }
+    else {
+      ret += String.fromCharCode(((c & 15) << 12) | ((b[i+1] & 63) << 6) | (b[i+2] & 63));
+      i += 2;
+    }
+  }
+  return ret;
+}
+
+// Set the private key fields N, e, and d from hex strings
+function RSASetPrivate(N,E,D) {
+  if(N != null && E != null && N.length > 0 && E.length > 0) {
+    this.n = parseBigInt(N,16);
+    this.e = parseInt(E,16);
+    this.d = parseBigInt(D,16);
+  }
+  else
+    alert("Invalid RSA private key");
+}
+
+// Set the private key fields N, e, d and CRT params from hex strings
+function RSASetPrivateEx(N,E,D,P,Q,DP,DQ,C) {
+  if(N != null && E != null && N.length > 0 && E.length > 0) {
+    this.n = parseBigInt(N,16);
+    this.e = parseInt(E,16);
+    this.d = parseBigInt(D,16);
+    this.p = parseBigInt(P,16);
+    this.q = parseBigInt(Q,16);
+    this.dmp1 = parseBigInt(DP,16);
+    this.dmq1 = parseBigInt(DQ,16);
+    this.coeff = parseBigInt(C,16);
+  }
+  else
+    alert("Invalid RSA private key");
+}
+
+/**
+ * Generate a new random private key B bits long, using public expt E
+ */
+function RSAGenerate(B,E) {
+  var rng = new SecureRandom();
+  var qs = B>>1;
+  this.e = parseInt(E,16);
+  var ee = new BigInteger(E,16);
+  for(;;) {
+    for(;;) {
+      this.p = new BigInteger(B-qs,1,rng);
+      if(this.p.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.p.isProbablePrime(10)) break;
+    }
+    for(;;) {
+      this.q = new BigInteger(qs,1,rng);
+      if(this.q.subtract(BigInteger.ONE).gcd(ee).compareTo(BigInteger.ONE) == 0 && this.q.isProbablePrime(10)) break;
+    }
+    if(this.p.compareTo(this.q) <= 0) {
+      var t = this.p;
+      this.p = this.q;
+      this.q = t;
+    }
+    var p1 = this.p.subtract(BigInteger.ONE);	// p1 = p - 1
+    var q1 = this.q.subtract(BigInteger.ONE);	// q1 = q - 1
+    var phi = p1.multiply(q1);
+    if(phi.gcd(ee).compareTo(BigInteger.ONE) == 0) {
+      this.n = this.p.multiply(this.q);	// this.n = p * q
+      this.d = ee.modInverse(phi);	// this.d = 
+      this.dmp1 = this.d.mod(p1);	// this.dmp1 = d mod (p - 1)
+      this.dmq1 = this.d.mod(q1);	// this.dmq1 = d mod (q - 1)
+      this.coeff = this.q.modInverse(this.p);	// this.coeff = (q ^ -1) mod p
+      break;
+    }
+  }
+}
+
+/**
+ * Perform raw private operation on "x": return x^d (mod n)
+ * @return x^d (mod n)
+ */ 
+function RSADoPrivate(x) {
+  if(this.p == null || this.q == null)
+    return x.modPow(this.d, this.n);
+
+  // TODO: re-calculate any missing CRT params
+  var xp = x.mod(this.p).modPow(this.dmp1, this.p); // xp=cp?
+  var xq = x.mod(this.q).modPow(this.dmq1, this.q); // xq=cq?
+
+  while(xp.compareTo(xq) < 0)
+    xp = xp.add(this.p);
+  // NOTE:
+  // xp.subtract(xq) => cp -cq
+  // xp.subtract(xq).multiply(this.coeff).mod(this.p) => (cp - cq) * u mod p = h
+  // xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq) => cq + (h * q) = M
+  return xp.subtract(xq).multiply(this.coeff).mod(this.p).multiply(this.q).add(xq);
+}
+
+// Return the PKCS#1 RSA decryption of "ctext".
+// "ctext" is an even-length hex string and the output is a plain string.
+function RSADecrypt(ctext) {
+  var c = parseBigInt(ctext, 16);
+  var m = this.doPrivate(c);
+  if(m == null) return null;
+  return pkcs1unpad2(m, (this.n.bitLength()+7)>>3);
+}
+
+// Return the PKCS#1 RSA decryption of "ctext".
+// "ctext" is a Base64-encoded string and the output is a plain string.
+//function RSAB64Decrypt(ctext) {
+//  var h = b64tohex(ctext);
+//  if(h) return this.decrypt(h); else return null;
+//}
+
+// protected
+RSAKey.prototype.doPrivate = RSADoPrivate;
+
+// public
+RSAKey.prototype.setPrivate = RSASetPrivate;
+RSAKey.prototype.setPrivateEx = RSASetPrivateEx;
+RSAKey.prototype.generate = RSAGenerate;
+RSAKey.prototype.decrypt = RSADecrypt;
+//RSAKey.prototype.b64_decrypt = RSAB64Decrypt;
+/*! rsapem-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+//
+// rsa-pem.js - adding function for reading/writing PKCS#1 PEM private key
+//              to RSAKey class.
+//
+// version: 1.1 (2012-May-10)
+//
+// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://kjur.github.com/jsrsasign/license/
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+// 
+//
+// Depends on:
+//
+//
+//
+// _RSApem_pemToBase64(sPEM)
+//
+//   removing PEM header, PEM footer and space characters including
+//   new lines from PEM formatted RSA private key string.
+//
+
+function _rsapem_pemToBase64(sPEMPrivateKey) {
+  var s = sPEMPrivateKey;
+  s = s.replace("-----BEGIN RSA PRIVATE KEY-----", "");
+  s = s.replace("-----END RSA PRIVATE KEY-----", "");
+  s = s.replace(/[ \n]+/g, "");
+  return s;
+}
+
+function _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey) {
+  var a = new Array();
+  var v1 = ASN1HEX.getStartPosOfV_AtObj(hPrivateKey, 0);
+  var n1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, v1);
+  var e1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, n1);
+  var d1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, e1);
+  var p1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, d1);
+  var q1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, p1);
+  var dp1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, q1);
+  var dq1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dp1);
+  var co1 = ASN1HEX.getPosOfNextSibling_AtObj(hPrivateKey, dq1);
+  a.push(v1, n1, e1, d1, p1, q1, dp1, dq1, co1);
+  return a;
+}
+
+function _rsapem_getHexValueArrayOfChildrenFromHex(hPrivateKey) {
+  var posArray = _rsapem_getPosArrayOfChildrenFromHex(hPrivateKey);
+  var v =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[0]);
+  var n =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[1]);
+  var e =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[2]);
+  var d =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[3]);
+  var p =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[4]);
+  var q =  ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[5]);
+  var dp = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[6]);
+  var dq = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[7]);
+  var co = ASN1HEX.getHexOfV_AtObj(hPrivateKey, posArray[8]);
+  var a = new Array();
+  a.push(v, n, e, d, p, q, dp, dq, co);
+  return a;
+}
+
+/**
+ * read PKCS#1 private key from a string
+ * @name readPrivateKeyFromPEMString
+ * @memberOf RSAKey#
+ * @function
+ * @param {String} keyPEM string of PKCS#1 private key.
+ */
+function _rsapem_readPrivateKeyFromPEMString(keyPEM) {
+  var keyB64 = _rsapem_pemToBase64(keyPEM);
+  var keyHex = b64tohex(keyB64) // depends base64.js
+  var a = _rsapem_getHexValueArrayOfChildrenFromHex(keyHex);
+  this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8]);
+}
+
+RSAKey.prototype.readPrivateKeyFromPEMString = _rsapem_readPrivateKeyFromPEMString;
+/*! rsasign-1.2.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+//
+// rsa-sign.js - adding signing functions to RSAKey class.
+//
+//
+// version: 1.2.1 (08 May 2012)
+//
+// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://kjur.github.com/jsrsasign/license/
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+
+//
+// Depends on:
+//   function sha1.hex(s) of sha1.js
+//   jsbn.js
+//   jsbn2.js
+//   rsa.js
+//   rsa2.js
+//
+
+// keysize / pmstrlen
+//  512 /  128
+// 1024 /  256
+// 2048 /  512
+// 4096 / 1024
+
+/**
+ * @property {Dictionary} _RSASIGN_DIHEAD
+ * @description Array of head part of hexadecimal DigestInfo value for hash algorithms.
+ * You can add any DigestInfo hash algorith for signing.
+ * See PKCS#1 v2.1 spec (p38).
+ */
+var _RSASIGN_DIHEAD = [];
+_RSASIGN_DIHEAD['sha1'] =      "3021300906052b0e03021a05000414";
+_RSASIGN_DIHEAD['sha256'] =    "3031300d060960864801650304020105000420";
+_RSASIGN_DIHEAD['sha384'] =    "3041300d060960864801650304020205000430";
+_RSASIGN_DIHEAD['sha512'] =    "3051300d060960864801650304020305000440";
+_RSASIGN_DIHEAD['md2'] =       "3020300c06082a864886f70d020205000410";
+_RSASIGN_DIHEAD['md5'] =       "3020300c06082a864886f70d020505000410";
+_RSASIGN_DIHEAD['ripemd160'] = "3021300906052b2403020105000414";
+
+/**
+ * @property {Dictionary} _RSASIGN_HASHHEXFUNC
+ * @description Array of functions which calculate hash and returns it as hexadecimal.
+ * You can add any hash algorithm implementations.
+ */
+var _RSASIGN_HASHHEXFUNC = [];
+_RSASIGN_HASHHEXFUNC['sha1'] =      function(s){return hex_sha1(s);};  // http://pajhome.org.uk/crypt/md5/md5.html
+_RSASIGN_HASHHEXFUNC['sha256'] =    function(s){return hex_sha256(s);} // http://pajhome.org.uk/crypt/md5/md5.html
+_RSASIGN_HASHHEXFUNC['sha512'] =    function(s){return hex_sha512(s);} // http://pajhome.org.uk/crypt/md5/md5.html
+_RSASIGN_HASHHEXFUNC['md5'] =       function(s){return hex_md5(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
+_RSASIGN_HASHHEXFUNC['ripemd160'] = function(s){return hex_rmd160(s);};   // http://pajhome.org.uk/crypt/md5/md5.html
+
+//@author axelcdv
+var _RSASIGN_HASHBYTEFUNC = [];
+_RSASIGN_HASHBYTEFUNC['sha256'] = 	function(byteArray){return hex_sha256_from_bytes(byteArray);};
+
+//_RSASIGN_HASHHEXFUNC['sha1'] =   function(s){return sha1.hex(s);}   // http://user1.matsumoto.ne.jp/~goma/js/hash.html
+//_RSASIGN_HASHHEXFUNC['sha256'] = function(s){return sha256.hex;}    // http://user1.matsumoto.ne.jp/~goma/js/hash.html
+
+var _RE_HEXDECONLY = new RegExp("");
+_RE_HEXDECONLY.compile("[^0-9a-f]", "gi");
+
+// ========================================================================
+// Signature Generation
+// ========================================================================
+
+function _rsasign_getHexPaddedDigestInfoForString(s, keySize, hashAlg) {
+  var pmStrLen = keySize / 4;
+  var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
+  var sHashHex = hashFunc(s);
+
+  var sHead = "0001";
+  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
+  var sMid = "";
+  var fLen = pmStrLen - sHead.length - sTail.length;
+  for (var i = 0; i < fLen; i += 2) {
+    sMid += "ff";
+  }
+  sPaddedMessageHex = sHead + sMid + sTail;
+  return sPaddedMessageHex;
+}
+
+
+//@author: Meki Cheraoui
+function _rsasign_getHexPaddedDigestInfoForStringHEX(s, keySize, hashAlg) {
+  var pmStrLen = keySize / 4;
+  var hashFunc = _RSASIGN_HASHHEXFUNC[hashAlg];
+  var sHashHex = hashFunc(s);
+
+  var sHead = "0001";
+  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
+  var sMid = "";
+  var fLen = pmStrLen - sHead.length - sTail.length;
+  for (var i = 0; i < fLen; i += 2) {
+    sMid += "ff";
+  }
+  sPaddedMessageHex = sHead + sMid + sTail;
+  return sPaddedMessageHex;
+}
+
+/**
+ * Apply padding, then computes the hash of the given byte array, according to the key size and with the hash algorithm
+ * @param byteArray (byte[])
+ * @param keySize (int)
+ * @param hashAlg the hash algorithm to apply (string)
+ * @return the hash of byteArray
+ */
+function _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, keySize, hashAlg){
+	var pmStrLen = keySize / 4;
+	var hashFunc = _RSASIGN_HASHBYTEFUNC[hashAlg];
+	var sHashHex = hashFunc(byteArray); //returns hex hash
+	
+	var sHead = "0001";
+	  var sTail = "00" + _RSASIGN_DIHEAD[hashAlg] + sHashHex;
+	  var sMid = "";
+	  var fLen = pmStrLen - sHead.length - sTail.length;
+	  for (var i = 0; i < fLen; i += 2) {
+	    sMid += "ff";
+	  }
+	  sPaddedMessageHex = sHead + sMid + sTail;
+	  return sPaddedMessageHex;
+}
+
+function _zeroPaddingOfSignature(hex, bitLength) {
+  var s = "";
+  var nZero = bitLength / 4 - hex.length;
+  for (var i = 0; i < nZero; i++) {
+    s = s + "0";
+  }
+  return s + hex;
+}
+
+/**
+ * sign for a message string with RSA private key.<br/>
+ * @name signString
+ * @memberOf RSAKey#
+ * @function
+ * @param {String} s message string to be signed.
+ * @param {String} hashAlg hash algorithm name for signing.<br/>
+ * @return returns hexadecimal string of signature value.
+ */
+function _rsasign_signString(s, hashAlg) {
+  //alert("this.n.bitLength() = " + this.n.bitLength());
+  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
+  var biPaddedMessage = parseBigInt(hPM, 16);
+  var biSign = this.doPrivate(biPaddedMessage);
+  var hexSign = biSign.toString(16);
+  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
+}
+
+//@author: ucla-cs
+function _rsasign_signStringHEX(s, hashAlg) {
+  //alert("this.n.bitLength() = " + this.n.bitLength());
+  var hPM = _rsasign_getHexPaddedDigestInfoForString(s, this.n.bitLength(), hashAlg);
+  var biPaddedMessage = parseBigInt(hPM, 16);
+  var biSign = this.doPrivate(biPaddedMessage);
+  var hexSign = biSign.toString(16);
+  return _zeroPaddingOfSignature(hexSign, this.n.bitLength());
+}
+
+
+/**
+ * Sign a message byteArray with an RSA private key
+ * @name signByteArray
+ * @memberOf RSAKey#
+ * @function
+ * @param {byte[]} byteArray
+ * @param {Sring} hashAlg the hash algorithm to apply
+ * @param {RSAKey} rsa key to sign with: hack because the context is lost here
+ * @return hexadecimal string of signature value
+ */
+function _rsasign_signByteArray(byteArray, hashAlg, rsaKey) {
+	var hPM = _rsasign_getHexPaddedDigestInfoForByteArray(byteArray, rsaKey.n.bitLength(), hashAlg); ///hack because the context is lost here
+	var biPaddedMessage = parseBigInt(hPM, 16);
+	var biSign = rsaKey.doPrivate(biPaddedMessage); //hack because the context is lost here
+	var hexSign = biSign.toString(16);
+	return _zeroPaddingOfSignature(hexSign, rsaKey.n.bitLength()); //hack because the context is lost here
+}
+
+/**
+ * Sign a byte array with the Sha-256 algorithm
+ * @param {byte[]} byteArray
+ * @return hexadecimal string of signature value
+ */
+function _rsasign_signByteArrayWithSHA256(byteArray){
+	return _rsasign_signByteArray(byteArray, 'sha256', this); //Hack because the context is lost in the next function
+}
+
+
+function _rsasign_signStringWithSHA1(s) {
+  return _rsasign_signString(s, 'sha1');
+}
+
+function _rsasign_signStringWithSHA256(s) {
+  return _rsasign_signString(s, 'sha256');
+}
+
+// ========================================================================
+// Signature Verification
+// ========================================================================
+
+function _rsasign_getDecryptSignatureBI(biSig, hN, hE) {
+  var rsa = new RSAKey();
+  rsa.setPublic(hN, hE);
+  var biDecryptedSig = rsa.doPublic(biSig);
+  return biDecryptedSig;
+}
+
+function _rsasign_getHexDigestInfoFromSig(biSig, hN, hE) {
+  var biDecryptedSig = _rsasign_getDecryptSignatureBI(biSig, hN, hE);
+  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+  return hDigestInfo;
+}
+
+function _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo) {
+  for (var algName in _RSASIGN_DIHEAD) {
+    var head = _RSASIGN_DIHEAD[algName];
+    var len = head.length;
+    if (hDigestInfo.substring(0, len) == head) {
+      var a = [algName, hDigestInfo.substring(len)];
+      return a;
+    }
+  }
+  return [];
+}
+
+function _rsasign_verifySignatureWithArgs(sMsg, biSig, hN, hE) {
+  var hDigestInfo = _rsasign_getHexDigestInfoFromSig(biSig, hN, hE);
+  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+  if (digestInfoAry.length == 0) return false;
+  var algName = digestInfoAry[0];
+  var diHashValue = digestInfoAry[1];
+  var ff = _RSASIGN_HASHHEXFUNC[algName];
+  var msgHashValue = ff(sMsg);
+  return (diHashValue == msgHashValue);
+}
+
+function _rsasign_verifyHexSignatureForMessage(hSig, sMsg) {
+  var biSig = parseBigInt(hSig, 16);
+  var result = _rsasign_verifySignatureWithArgs(sMsg, biSig,
+						this.n.toString(16),
+						this.e.toString(16));
+  return result;
+}
+
+/**
+ * verifies a sigature for a message string with RSA public key.<br/>
+ * @name verifyString
+ * @memberOf RSAKey#
+ * @function
+ * @param {String} sMsg message string to be verified.
+ * @param {String} hSig hexadecimal string of siganture.<br/>
+ *                 non-hexadecimal charactors including new lines will be ignored.
+ * @return returns 1 if valid, otherwise 0
+ */
+function _rsasign_verifyString(sMsg, hSig) {
+  hSig = hSig.replace(_RE_HEXDECONLY, '');
+  
+  if(LOG>3)console.log('n is '+this.n);
+  if(LOG>3)console.log('e is '+this.e);
+  
+  if (hSig.length != this.n.bitLength() / 4) return 0;
+  hSig = hSig.replace(/[ \n]+/g, "");
+  var biSig = parseBigInt(hSig, 16);
+  var biDecryptedSig = this.doPublic(biSig);
+  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+  
+  if (digestInfoAry.length == 0) return false;
+  var algName = digestInfoAry[0];
+  var diHashValue = digestInfoAry[1];
+  var ff = _RSASIGN_HASHHEXFUNC[algName];
+  var msgHashValue = ff(sMsg);
+  return (diHashValue == msgHashValue);
+}
+
+/**
+ * verifies a sigature for a message byte array with RSA public key.<br/>
+ * @name verifyByteArray
+ * @memberOf RSAKey#
+ * @function
+ * @param {byte[]} byteArray message byte array to be verified.
+ * @param {String} hSig hexadecimal string of signature.<br/>
+ *                 non-hexadecimal charactors including new lines will be ignored.
+ * @return returns 1 if valid, otherwise 0 
+ */
+function _rsasign_verifyByteArray(byteArray, witness, hSig) {
+	hSig = hSig.replace(_RE_HEXDECONLY, '');
+	  
+	  if(LOG>3)console.log('n is '+this.n);
+	  if(LOG>3)console.log('e is '+this.e);
+	  
+	  if (hSig.length != this.n.bitLength() / 4) return 0;
+	  hSig = hSig.replace(/[ \n]+/g, "");
+	  var biSig = parseBigInt(hSig, 16);
+	  var biDecryptedSig = this.doPublic(biSig);
+	  var hDigestInfo = biDecryptedSig.toString(16).replace(/^1f+00/, '');
+	  var digestInfoAry = _rsasign_getAlgNameAndHashFromHexDisgestInfo(hDigestInfo);
+	  
+	  if (digestInfoAry.length == 0) return false;
+	  var algName = digestInfoAry[0];
+	  var diHashValue = digestInfoAry[1];
+	  var msgHashValue = null;
+	  
+	  if (witness == null) {
+	  	var ff = _RSASIGN_HASHBYTEFUNC[algName];
+	  	msgHashValue = ff(byteArray);
+	  } else {
+	  	// Compute merkle hash
+		  var h = hex_sha256_from_bytes(byteArray);
+		  var index = witness.path.index;
+		  for (var i = witness.path.digestList.length - 1; i >= 0; i--) {
+		  	var str = "";
+		  	if (index % 2 == 0) {
+		  		str = h + witness.path.digestList[i];
+		  	} else {
+		  		str = witness.path.digestList[i] + h;
+		  	}
+		  	h = hex_sha256_from_bytes(DataUtils.toNumbers(str));
+		  	index = Math.floor(index / 2);
+		  }
+		  msgHashValue = hex_sha256_from_bytes(DataUtils.toNumbers(h));
+	  }
+	  //console.log(diHashValue);
+	  //console.log(msgHashValue);
+	  return (diHashValue == msgHashValue);
+}
+
+
+RSAKey.prototype.signString = _rsasign_signString;
+
+RSAKey.prototype.signByteArray = _rsasign_signByteArray; //@author axelcdv
+RSAKey.prototype.signByteArrayWithSHA256 = _rsasign_signByteArrayWithSHA256; //@author axelcdv
+
+RSAKey.prototype.signStringWithSHA1 = _rsasign_signStringWithSHA1;
+RSAKey.prototype.signStringWithSHA256 = _rsasign_signStringWithSHA256;
+RSAKey.prototype.sign = _rsasign_signString;
+RSAKey.prototype.signWithSHA1 = _rsasign_signStringWithSHA1;
+RSAKey.prototype.signWithSHA256 = _rsasign_signStringWithSHA256;
+
+
+/*RSAKey.prototype.signStringHEX = _rsasign_signStringHEX;
+RSAKey.prototype.signStringWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
+RSAKey.prototype.signStringWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
+RSAKey.prototype.signHEX = _rsasign_signStringHEX;
+RSAKey.prototype.signWithSHA1HEX = _rsasign_signStringWithSHA1HEX;
+RSAKey.prototype.signWithSHA256HEX = _rsasign_signStringWithSHA256HEX;
+*/
+
+RSAKey.prototype.verifyByteArray = _rsasign_verifyByteArray;
+RSAKey.prototype.verifyString = _rsasign_verifyString;
+RSAKey.prototype.verifyHexSignatureForMessage = _rsasign_verifyHexSignatureForMessage;
+RSAKey.prototype.verify = _rsasign_verifyString;
+RSAKey.prototype.verifyHexSignatureForByteArrayMessage = _rsasign_verifyHexSignatureForMessage;
+
+/*
+RSAKey.prototype.verifyStringHEX = _rsasign_verifyStringHEX;
+RSAKey.prototype.verifyHexSignatureForMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
+RSAKey.prototype.verifyHEX = _rsasign_verifyStringHEX;
+RSAKey.prototype.verifyHexSignatureForByteArrayMessageHEX = _rsasign_verifyHexSignatureForMessageHEX;
+*/
+	
+	
+/**
+ * @name RSAKey
+ * @class
+ * @description Tom Wu's RSA Key class and extension
+ */
+/*! asn1hex-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+//
+// asn1hex.js - Hexadecimal represented ASN.1 string library
+//
+// version: 1.1 (09-May-2012)
+//
+// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://kjur.github.com/jsrsasign/license/
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+//
+// Depends on:
+//
+
+// MEMO:
+//   f('3082025b02...', 2) ... 82025b ... 3bytes
+//   f('020100', 2) ... 01 ... 1byte
+//   f('0203001...', 2) ... 03 ... 1byte
+//   f('02818003...', 2) ... 8180 ... 2bytes
+//   f('3080....0000', 2) ... 80 ... -1
+//
+//   Requirements:
+//   - ASN.1 type octet length MUST be 1. 
+//     (i.e. ASN.1 primitives like SET, SEQUENCE, INTEGER, OCTETSTRING ...)
+//   - 
+/**
+ * get byte length for ASN.1 L(length) bytes
+ * @name getByteLengthOfL_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return byte length for ASN.1 L(length) bytes
+ */
+function _asnhex_getByteLengthOfL_AtObj(s, pos) {
+  if (s.substring(pos + 2, pos + 3) != '8') return 1;
+  var i = parseInt(s.substring(pos + 3, pos + 4));
+  if (i == 0) return -1; 		// length octet '80' indefinite length
+  if (0 < i && i < 10) return i + 1;	// including '8?' octet;
+  return -2;				// malformed format
+}
+
+
+/**
+ * get hexadecimal string for ASN.1 L(length) bytes
+ * @name getHexOfL_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return {String} hexadecimal string for ASN.1 L(length) bytes
+ */
+function _asnhex_getHexOfL_AtObj(s, pos) {
+  var len = _asnhex_getByteLengthOfL_AtObj(s, pos);
+  if (len < 1) return '';
+  return s.substring(pos + 2, pos + 2 + len * 2);
+}
+
+//
+//   getting ASN.1 length value at the position 'idx' of
+//   hexa decimal string 's'.
+//
+//   f('3082025b02...', 0) ... 82025b ... ???
+//   f('020100', 0) ... 01 ... 1
+//   f('0203001...', 0) ... 03 ... 3
+//   f('02818003...', 0) ... 8180 ... 128
+/**
+ * get integer value of ASN.1 length for ASN.1 data
+ * @name getIntOfL_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return ASN.1 L(length) integer value
+ */
+function _asnhex_getIntOfL_AtObj(s, pos) {
+  var hLength = _asnhex_getHexOfL_AtObj(s, pos);
+  if (hLength == '') return -1;
+  var bi;
+  if (parseInt(hLength.substring(0, 1)) < 8) {
+     bi = parseBigInt(hLength, 16);
+  } else {
+     bi = parseBigInt(hLength.substring(2), 16);
+  }
+  return bi.intValue();
+}
+
+/**
+ * get ASN.1 value starting string position for ASN.1 object refered by index 'idx'.
+ * @name getStartPosOfV_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ */
+function _asnhex_getStartPosOfV_AtObj(s, pos) {
+  var l_len = _asnhex_getByteLengthOfL_AtObj(s, pos);
+  if (l_len < 0) return l_len;
+  return pos + (l_len + 1) * 2;
+}
+
+/**
+ * get hexadecimal string of ASN.1 V(value)
+ * @name getHexOfV_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return {String} hexadecimal string of ASN.1 value.
+ */
+function _asnhex_getHexOfV_AtObj(s, pos) {
+  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
+  var len = _asnhex_getIntOfL_AtObj(s, pos);
+  return s.substring(pos1, pos1 + len * 2);
+}
+
+/**
+ * get hexadecimal string of ASN.1 TLV at
+ * @name getHexOfTLV_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return {String} hexadecimal string of ASN.1 TLV.
+ * @since 1.1
+ */
+function _asnhex_getHexOfTLV_AtObj(s, pos) {
+  var hT = s.substr(pos, 2);
+  var hL = _asnhex_getHexOfL_AtObj(s, pos);
+  var hV = _asnhex_getHexOfV_AtObj(s, pos);
+  return hT + hL + hV;
+}
+
+/**
+ * get next sibling starting index for ASN.1 object string
+ * @name getPosOfNextSibling_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} pos string index
+ * @return next sibling starting index for ASN.1 object string
+ */
+function _asnhex_getPosOfNextSibling_AtObj(s, pos) {
+  var pos1 = _asnhex_getStartPosOfV_AtObj(s, pos);
+  var len = _asnhex_getIntOfL_AtObj(s, pos);
+  return pos1 + len * 2;
+}
+
+/**
+ * get array of indexes of child ASN.1 objects
+ * @name getPosArrayOfChildren_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} s hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} start string index of ASN.1 object
+ * @return {Array of Number} array of indexes for childen of ASN.1 objects
+ */
+function _asnhex_getPosArrayOfChildren_AtObj(h, pos) {
+  var a = new Array();
+  var p0 = _asnhex_getStartPosOfV_AtObj(h, pos);
+  a.push(p0);
+
+  var len = _asnhex_getIntOfL_AtObj(h, pos);
+  var p = p0;
+  var k = 0;
+  while (1) {
+    var pNext = _asnhex_getPosOfNextSibling_AtObj(h, p);
+    if (pNext == null || (pNext - p0  >= (len * 2))) break;
+    if (k >= 200) break;
+
+    a.push(pNext);
+    p = pNext;
+
+    k++;
+  }
+
+  return a;
+}
+
+/**
+ * get string index of nth child object of ASN.1 object refered by h, idx
+ * @name getNthChildIndex_AtObj
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} h hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} idx start string index of ASN.1 object
+ * @param {Number} nth for child
+ * @return {Number} string index of nth child.
+ * @since 1.1
+ */
+function _asnhex_getNthChildIndex_AtObj(h, idx, nth) {
+  var a = _asnhex_getPosArrayOfChildren_AtObj(h, idx);
+  return a[nth];
+}
+
+// ========== decendant methods ==============================
+
+/**
+ * get string index of nth child object of ASN.1 object refered by h, idx
+ * @name getDecendantIndexByNthList
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} h hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} currentIndex start string index of ASN.1 object
+ * @param {Array of Number} nthList array list of nth
+ * @return {Number} string index refered by nthList
+ * @since 1.1
+ */
+function _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList) {
+  if (nthList.length == 0) {
+    return currentIndex;
+  }
+  var firstNth = nthList.shift();
+  var a = _asnhex_getPosArrayOfChildren_AtObj(h, currentIndex);
+  return _asnhex_getDecendantIndexByNthList(h, a[firstNth], nthList);
+}
+
+/**
+ * get hexadecimal string of ASN.1 TLV refered by current index and nth index list.
+ * @name getDecendantHexTLVByNthList
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} h hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} currentIndex start string index of ASN.1 object
+ * @param {Array of Number} nthList array list of nth
+ * @return {Number} hexadecimal string of ASN.1 TLV refered by nthList
+ * @since 1.1
+ */
+function _asnhex_getDecendantHexTLVByNthList(h, currentIndex, nthList) {
+  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
+  return _asnhex_getHexOfTLV_AtObj(h, idx);
+}
+
+/**
+ * get hexadecimal string of ASN.1 V refered by current index and nth index list.
+ * @name getDecendantHexVByNthList
+ * @memberOf ASN1HEX
+ * @function
+ * @param {String} h hexadecimal string of ASN.1 DER encoded data
+ * @param {Number} currentIndex start string index of ASN.1 object
+ * @param {Array of Number} nthList array list of nth
+ * @return {Number} hexadecimal string of ASN.1 V refered by nthList
+ * @since 1.1
+ */
+function _asnhex_getDecendantHexVByNthList(h, currentIndex, nthList) {
+  var idx = _asnhex_getDecendantIndexByNthList(h, currentIndex, nthList);
+  return _asnhex_getHexOfV_AtObj(h, idx);
+}
+
+// ========== class definition ==============================
+
+/**
+ * ASN.1 DER encoded hexadecimal string utility class
+ * @class ASN.1 DER encoded hexadecimal string utility class
+ * @author Kenji Urushima
+ * @version 1.1 (09 May 2012)
+ * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
+ * @since 1.1
+ */
+function ASN1HEX() {
+  return ASN1HEX;
+}
+
+ASN1HEX.getByteLengthOfL_AtObj = _asnhex_getByteLengthOfL_AtObj;
+ASN1HEX.getHexOfL_AtObj = _asnhex_getHexOfL_AtObj;
+ASN1HEX.getIntOfL_AtObj = _asnhex_getIntOfL_AtObj;
+ASN1HEX.getStartPosOfV_AtObj = _asnhex_getStartPosOfV_AtObj;
+ASN1HEX.getHexOfV_AtObj = _asnhex_getHexOfV_AtObj;
+ASN1HEX.getHexOfTLV_AtObj = _asnhex_getHexOfTLV_AtObj;
+ASN1HEX.getPosOfNextSibling_AtObj = _asnhex_getPosOfNextSibling_AtObj;
+ASN1HEX.getPosArrayOfChildren_AtObj = _asnhex_getPosArrayOfChildren_AtObj;
+ASN1HEX.getNthChildIndex_AtObj = _asnhex_getNthChildIndex_AtObj;
+ASN1HEX.getDecendantIndexByNthList = _asnhex_getDecendantIndexByNthList;
+ASN1HEX.getDecendantHexVByNthList = _asnhex_getDecendantHexVByNthList;
+ASN1HEX.getDecendantHexTLVByNthList = _asnhex_getDecendantHexTLVByNthList;
+/*! x509-1.1.js (c) 2012 Kenji Urushima | kjur.github.com/jsrsasign/license
+ */
+// 
+// x509.js - X509 class to read subject public key from certificate.
+//
+// version: 1.1 (10-May-2012)
+//
+// Copyright (c) 2010-2012 Kenji Urushima (kenji.urushima@gmail.com)
+//
+// This software is licensed under the terms of the MIT License.
+// http://kjur.github.com/jsrsasign/license
+//
+// The above copyright and license notice shall be 
+// included in all copies or substantial portions of the Software.
+// 
+
+// Depends:
+//   base64.js
+//   rsa.js
+//   asn1hex.js
+
+function _x509_pemToBase64(sCertPEM) {
+  var s = sCertPEM;
+  s = s.replace("-----BEGIN CERTIFICATE-----", "");
+  s = s.replace("-----END CERTIFICATE-----", "");
+  s = s.replace(/[ \n]+/g, "");
+  return s;
+}
+
+function _x509_pemToHex(sCertPEM) {
+  var b64Cert = _x509_pemToBase64(sCertPEM);
+  var hCert = b64tohex(b64Cert);
+  return hCert;
+}
+
+function _x509_getHexTbsCertificateFromCert(hCert) {
+  var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
+  return pTbsCert;
+}
+
+// NOTE: privateKeyUsagePeriod field of X509v2 not supported.
+// NOTE: v1 and v3 supported
+function _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert) {
+  var pTbsCert = ASN1HEX.getStartPosOfV_AtObj(hCert, 0);
+  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pTbsCert); 
+  if (a.length < 1) return -1;
+  if (hCert.substring(a[0], a[0] + 10) == "a003020102") { // v3
+    if (a.length < 6) return -1;
+    return a[6];
+  } else {
+    if (a.length < 5) return -1;
+    return a[5];
+  }
+}
+
+// NOTE: Without BITSTRING encapsulation.
+// If pInfo is supplied, it is the position in hCert of the SubjectPublicKeyInfo.
+function _x509_getSubjectPublicKeyPosFromCertHex(hCert, pInfo) {
+  if (pInfo == null)
+      pInfo = _x509_getSubjectPublicKeyInfoPosFromCertHex(hCert);
+  if (pInfo == -1) return -1;    
+  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, pInfo); 
+  
+  if (a.length != 2) return -1;
+  var pBitString = a[1];
+  if (hCert.substring(pBitString, pBitString + 2) != '03') return -1;
+  var pBitStringV = ASN1HEX.getStartPosOfV_AtObj(hCert, pBitString);
+
+  if (hCert.substring(pBitStringV, pBitStringV + 2) != '00') return -1;
+  return pBitStringV + 2;
+}
+
+// If p is supplied, it is the public key position in hCert.
+function _x509_getPublicKeyHexArrayFromCertHex(hCert, p) {
+  if (p == null)
+      p = _x509_getSubjectPublicKeyPosFromCertHex(hCert);
+  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, p); 
+  //var a = ASN1HEX.getPosArrayOfChildren_AtObj(hCert, a[3]); 
+  if(LOG>4){
+	  console.log('a is now');
+	  console.log(a);
+  }
+  
+  //if (a.length != 2) return [];
+  if (a.length < 2) return [];
+
+  var hN = ASN1HEX.getHexOfV_AtObj(hCert, a[0]);
+  var hE = ASN1HEX.getHexOfV_AtObj(hCert, a[1]);
+  if (hN != null && hE != null) {
+    return [hN, hE];
+  } else {
+    return [];
+  }
+}
+
+function _x509_getPublicKeyHexArrayFromCertPEM(sCertPEM) {
+  var hCert = _x509_pemToHex(sCertPEM);
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  return a;
+}
+
+// ===== get basic fields from hex =====================================
+/**
+ * get hexadecimal string of serialNumber field of certificate.<br/>
+ * @name getSerialNumberHex
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getSerialNumberHex() {
+  return ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 1]);
+}
+
+/**
+ * get hexadecimal string of issuer field of certificate.<br/>
+ * @name getIssuerHex
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getIssuerHex() {
+  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]);
+}
+
+/**
+ * get string of issuer field of certificate.<br/>
+ * @name getIssuerString
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getIssuerString() {
+  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 3]));
+}
+
+/**
+ * get hexadecimal string of subject field of certificate.<br/>
+ * @name getSubjectHex
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getSubjectHex() {
+  return ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]);
+}
+
+/**
+ * get string of subject field of certificate.<br/>
+ * @name getSubjectString
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getSubjectString() {
+  return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex, 0, [0, 5]));
+}
+
+/**
+ * get notBefore field string of certificate.<br/>
+ * @name getNotBefore
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getNotBefore() {
+  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 0]);
+  s = s.replace(/(..)/g, "%$1");
+  s = decodeURIComponent(s);
+  return s;
+}
+
+/**
+ * get notAfter field string of certificate.<br/>
+ * @name getNotAfter
+ * @memberOf X509#
+ * @function
+ */
+function _x509_getNotAfter() {
+  var s = ASN1HEX.getDecendantHexVByNthList(this.hex, 0, [0, 4, 1]);
+  s = s.replace(/(..)/g, "%$1");
+  s = decodeURIComponent(s);
+  return s;
+}
+
+// ===== read certificate =====================================
+
+_x509_DN_ATTRHEX = {
+    "0603550406": "C",
+    "060355040a": "O",
+    "060355040b": "OU",
+    "0603550403": "CN",
+    "0603550405": "SN",
+    "0603550408": "ST",
+    "0603550407": "L" };
+
+function _x509_hex2dn(hDN) {
+  var s = "";
+  var a = ASN1HEX.getPosArrayOfChildren_AtObj(hDN, 0);
+  for (var i = 0; i < a.length; i++) {
+    var hRDN = ASN1HEX.getHexOfTLV_AtObj(hDN, a[i]);
+    s = s + "/" + _x509_hex2rdn(hRDN);
+  }
+  return s;
+}
+
+function _x509_hex2rdn(hRDN) {
+    var hType = ASN1HEX.getDecendantHexTLVByNthList(hRDN, 0, [0, 0]);
+    var hValue = ASN1HEX.getDecendantHexVByNthList(hRDN, 0, [0, 1]);
+    var type = "";
+    try { type = _x509_DN_ATTRHEX[hType]; } catch (ex) { type = hType; }
+    hValue = hValue.replace(/(..)/g, "%$1");
+    var value = decodeURIComponent(hValue);
+    return type + "=" + value;
+}
+
+// ===== read certificate =====================================
+
+
+/**
+ * read PEM formatted X.509 certificate from string.<br/>
+ * @name readCertPEM
+ * @memberOf X509#
+ * @function
+ * @param {String} sCertPEM string for PEM formatted X.509 certificate
+ */
+function _x509_readCertPEM(sCertPEM) {
+  var hCert = _x509_pemToHex(sCertPEM);
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  if(LOG>4){
+	  console.log('HEX VALUE IS ' + hCert);
+	  console.log('type of a' + typeof a);
+	  console.log('a VALUE IS ');
+	  console.log(a);
+	  console.log('a[0] VALUE IS ' + a[0]);
+	  console.log('a[1] VALUE IS ' + a[1]);
+  }
+  var rsa = new RSAKey();
+  rsa.setPublic(a[0], a[1]);
+  this.subjectPublicKeyRSA = rsa;
+  this.subjectPublicKeyRSA_hN = a[0];
+  this.subjectPublicKeyRSA_hE = a[1];
+  this.hex = hCert;
+}
+
+/**
+ * read hex formatted X.509 certificate from string.
+ * @name readCertHex
+ * @memberOf X509#
+ * @function
+ * @param {String} hCert string for hex formatted X.509 certificate
+ */
+function _x509_readCertHex(hCert) {
+  hCert = hCert.toLowerCase();
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  var rsa = new RSAKey();
+  rsa.setPublic(a[0], a[1]);
+  this.subjectPublicKeyRSA = rsa;
+  this.subjectPublicKeyRSA_hN = a[0];
+  this.subjectPublicKeyRSA_hE = a[1];
+  this.hex = hCert;
+}
+
+function _x509_readCertPEMWithoutRSAInit(sCertPEM) {
+  var hCert = _x509_pemToHex(sCertPEM);
+  var a = _x509_getPublicKeyHexArrayFromCertHex(hCert);
+  this.subjectPublicKeyRSA.setPublic(a[0], a[1]);
+  this.subjectPublicKeyRSA_hN = a[0];
+  this.subjectPublicKeyRSA_hE = a[1];
+  this.hex = hCert;
+}
+
+/**
+ * X.509 certificate class.<br/>
+ * @class X.509 certificate class
+ * @property {RSAKey} subjectPublicKeyRSA Tom Wu's RSAKey object
+ * @property {String} subjectPublicKeyRSA_hN hexadecimal string for modulus of RSA public key
+ * @property {String} subjectPublicKeyRSA_hE hexadecimal string for public exponent of RSA public key
+ * @property {String} hex hexacedimal string for X.509 certificate.
+ * @author Kenji Urushima
+ * @version 1.0.1 (08 May 2012)
+ * @see <a href="http://kjur.github.com/jsrsasigns/">'jwrsasign'(RSA Sign JavaScript Library) home page http://kjur.github.com/jsrsasign/</a>
+ */
+function X509() {
+  this.subjectPublicKeyRSA = null;
+  this.subjectPublicKeyRSA_hN = null;
+  this.subjectPublicKeyRSA_hE = null;
+  this.hex = null;
+}
+
+X509.prototype.readCertPEM = _x509_readCertPEM;
+X509.prototype.readCertHex = _x509_readCertHex;
+X509.prototype.readCertPEMWithoutRSAInit = _x509_readCertPEMWithoutRSAInit;
+X509.prototype.getSerialNumberHex = _x509_getSerialNumberHex;
+X509.prototype.getIssuerHex = _x509_getIssuerHex;
+X509.prototype.getSubjectHex = _x509_getSubjectHex;
+X509.prototype.getIssuerString = _x509_getIssuerString;
+X509.prototype.getSubjectString = _x509_getSubjectString;
+X509.prototype.getNotBefore = _x509_getNotBefore;
+X509.prototype.getNotAfter = _x509_getNotAfter;
+
+// Copyright (c) 2005  Tom Wu
+// All Rights Reserved.
+// See "LICENSE" for details.
+
+// Basic JavaScript BN library - subset useful for RSA encryption.
+
+// Bits per digit
+var dbits;
+
+// JavaScript engine analysis
+var canary = 0xdeadbeefcafe;
+var j_lm = ((canary&0xffffff)==0xefcafe);
+
+// (public) Constructor
+function BigInteger(a,b,c) {
+  if(a != null)
+    if("number" == typeof a) this.fromNumber(a,b,c);
+    else if(b == null && "string" != typeof a) this.fromString(a,256);
+    else this.fromString(a,b);
+}
+
+// return new, unset BigInteger
+function nbi() { return new BigInteger(null); }
+
+// am: Compute w_j += (x*this_i), propagate carries,
+// c is initial carry, returns final carry.
+// c < 3*dvalue, x < 2*dvalue, this_i < dvalue
+// We need to select the fastest one that works in this environment.
+
+// am1: use a single mult and divide to get the high bits,
+// max digit bits should be 26 because
+// max internal value = 2*dvalue^2-2*dvalue (< 2^53)
+function am1(i,x,w,j,c,n) {
+  while(--n >= 0) {
+    var v = x*this[i++]+w[j]+c;
+    c = Math.floor(v/0x4000000);
+    w[j++] = v&0x3ffffff;
+  }
+  return c;
+}
+// am2 avoids a big mult-and-extract completely.
+// Max digit bits should be <= 30 because we do bitwise ops
+// on values up to 2*hdvalue^2-hdvalue-1 (< 2^31)
+function am2(i,x,w,j,c,n) {
+  var xl = x&0x7fff, xh = x>>15;
+  while(--n >= 0) {
+    var l = this[i]&0x7fff;
+    var h = this[i++]>>15;
+    var m = xh*l+h*xl;
+    l = xl*l+((m&0x7fff)<<15)+w[j]+(c&0x3fffffff);
+    c = (l>>>30)+(m>>>15)+xh*h+(c>>>30);
+    w[j++] = l&0x3fffffff;
+  }
+  return c;
+}
+// Alternately, set max digit bits to 28 since some
+// browsers slow down when dealing with 32-bit numbers.
+function am3(i,x,w,j,c,n) {
+  var xl = x&0x3fff, xh = x>>14;
+  while(--n >= 0) {
+    var l = this[i]&0x3fff;
+    var h = this[i++]>>14;
+    var m = xh*l+h*xl;
+    l = xl*l+((m&0x3fff)<<14)+w[j]+c;
+    c = (l>>28)+(m>>14)+xh*h;
+    w[j++] = l&0xfffffff;
+  }
+  return c;
+}
+if(j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
+  BigInteger.prototype.am = am2;
+  dbits = 30;
+}
+else if(j_lm && (navigator.appName != "Netscape")) {
+  BigInteger.prototype.am = am1;
+  dbits = 26;
+}
+else { // Mozilla/Netscape seems to prefer am3
+  BigInteger.prototype.am = am3;
+  dbits = 28;
+}
+
+BigInteger.prototype.DB = dbits;
+BigInteger.prototype.DM = ((1<<dbits)-1);
+BigInteger.prototype.DV = (1<<dbits);
+
+var BI_FP = 52;
+BigInteger.prototype.FV = Math.pow(2,BI_FP);
+BigInteger.prototype.F1 = BI_FP-dbits;
+BigInteger.prototype.F2 = 2*dbits-BI_FP;
+
+// Digit conversions
+var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
+var BI_RC = new Array();
+var rr,vv;
+rr = "0".charCodeAt(0);
+for(vv = 0; vv <= 9; ++vv) BI_RC[rr++] = vv;
+rr = "a".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+rr = "A".charCodeAt(0);
+for(vv = 10; vv < 36; ++vv) BI_RC[rr++] = vv;
+
+function int2char(n) { return BI_RM.charAt(n); }
+function intAt(s,i) {
+  var c = BI_RC[s.charCodeAt(i)];
+  return (c==null)?-1:c;
+}
+
+// (protected) copy this to r
+function bnpCopyTo(r) {
+  for(var i = this.t-1; i >= 0; --i) r[i] = this[i];
+  r.t = this.t;
+  r.s = this.s;
+}
+
+// (protected) set from integer value x, -DV <= x < DV
+function bnpFromInt(x) {
+  this.t = 1;
+  this.s = (x<0)?-1:0;
+  if(x > 0) this[0] = x;
+  else if(x < -1) this[0] = x+DV;
+  else this.t = 0;
+}
+
+// return bigint initialized to value
+function nbv(i) { var r = nbi(); r.fromInt(i); return r; }
+
+// (protected) set from string and radix
+function bnpFromString(s,b) {
+  var k;
+  if(b == 16) k = 4;
+  else if(b == 8) k = 3;
+  else if(b == 256) k = 8; // byte array
+  else if(b == 2) k = 1;
+  else if(b == 32) k = 5;
+  else if(b == 4) k = 2;
+  else { this.fromRadix(s,b); return; }
+  this.t = 0;
+  this.s = 0;
+  var i = s.length, mi = false, sh = 0;
+  while(--i >= 0) {
+    var x = (k==8)?s[i]&0xff:intAt(s,i);
+    if(x < 0) {
+      if(s.charAt(i) == "-") mi = true;
+      continue;
+    }
+    mi = false;
+    if(sh == 0)
+      this[this.t++] = x;
+    else if(sh+k > this.DB) {
+      this[this.t-1] |= (x&((1<<(this.DB-sh))-1))<<sh;
+      this[this.t++] = (x>>(this.DB-sh));
+    }
+    else
+      this[this.t-1] |= x<<sh;
+    sh += k;
+    if(sh >= this.DB) sh -= this.DB;
+  }
+  if(k == 8 && (s[0]&0x80) != 0) {
+    this.s = -1;
+    if(sh > 0) this[this.t-1] |= ((1<<(this.DB-sh))-1)<<sh;
+  }
+  this.clamp();
+  if(mi) BigInteger.ZERO.subTo(this,this);
+}
+
+// (protected) clamp off excess high words
+function bnpClamp() {
+  var c = this.s&this.DM;
+  while(this.t > 0 && this[this.t-1] == c) --this.t;
+}
+
+// (public) return string representation in given radix
+function bnToString(b) {
+  if(this.s < 0) return "-"+this.negate().toString(b);
+  var k;
+  if(b == 16) k = 4;
+  else if(b == 8) k = 3;
+  else if(b == 2) k = 1;
+  else if(b == 32) k = 5;
+  else if(b == 4) k = 2;
+  else return this.toRadix(b);
+  var km = (1<<k)-1, d, m = false, r = "", i = this.t;
+  var p = this.DB-(i*this.DB)%k;
+  if(i-- > 0) {
+    if(p < this.DB && (d = this[i]>>p) > 0) { m = true; r = int2char(d); }
+    while(i >= 0) {
+      if(p < k) {
+        d = (this[i]&((1<<p)-1))<<(k-p);
+        d |= this[--i]>>(p+=this.DB-k);
+      }
+      else {
+        d = (this[i]>>(p-=k))&km;
+        if(p <= 0) { p += this.DB; --i; }
+      }
+      if(d > 0) m = true;
+      if(m) r += int2char(d);
+    }
+  }
+  return m?r:"0";
+}
+
+// (public) -this
+function bnNegate() { var r = nbi(); BigInteger.ZERO.subTo(this,r); return r; }
+
+// (public) |this|
+function bnAbs() { return (this.s<0)?this.negate():this; }
+
+// (public) return + if this > a, - if this < a, 0 if equal
+function bnCompareTo(a) {
+  var r = this.s-a.s;
+  if(r != 0) return r;
+  var i = this.t;
+  r = i-a.t;
+  if(r != 0) return r;
+  while(--i >= 0) if((r=this[i]-a[i]) != 0) return r;
+  return 0;
+}
+
+// returns bit length of the integer x
+function nbits(x) {
+  var r = 1, t;
+  if((t=x>>>16) != 0) { x = t; r += 16; }
+  if((t=x>>8) != 0) { x = t; r += 8; }
+  if((t=x>>4) != 0) { x = t; r += 4; }
+  if((t=x>>2) != 0) { x = t; r += 2; }
+  if((t=x>>1) != 0) { x = t; r += 1; }
+  return r;
+}
+
+// (public) return the number of bits in "this"
+function bnBitLength() {
+  if(this.t <= 0) return 0;
+  return this.DB*(this.t-1)+nbits(this[this.t-1]^(this.s&this.DM));
+}
+
+// (protected) r = this << n*DB
+function bnpDLShiftTo(n,r) {
+  var i;
+  for(i = this.t-1; i >= 0; --i) r[i+n] = this[i];
+  for(i = n-1; i >= 0; --i) r[i] = 0;
+  r.t = this.t+n;
+  r.s = this.s;
+}
+
+// (protected) r = this >> n*DB
+function bnpDRShiftTo(n,r) {
+  for(var i = n; i < this.t; ++i) r[i-n] = this[i];
+  r.t = Math.max(this.t-n,0);
+  r.s = this.s;
+}
+
+// (protected) r = this << n
+function bnpLShiftTo(n,r) {
+  var bs = n%this.DB;
+  var cbs = this.DB-bs;
+  var bm = (1<<cbs)-1;
+  var ds = Math.floor(n/this.DB), c = (this.s<<bs)&this.DM, i;
+  for(i = this.t-1; i >= 0; --i) {
+    r[i+ds+1] = (this[i]>>cbs)|c;
+    c = (this[i]&bm)<<bs;
+  }
+  for(i = ds-1; i >= 0; --i) r[i] = 0;
+  r[ds] = c;
+  r.t = this.t+ds+1;
+  r.s = this.s;
+  r.clamp();
+}
+
+// (protected) r = this >> n
+function bnpRShiftTo(n,r) {
+  r.s = this.s;
+  var ds = Math.floor(n/this.DB);
+  if(ds >= this.t) { r.t = 0; return; }
+  var bs = n%this.DB;
+  var cbs = this.DB-bs;
+  var bm = (1<<bs)-1;
+  r[0] = this[ds]>>bs;
+  for(var i = ds+1; i < this.t; ++i) {
+    r[i-ds-1] |= (this[i]&bm)<<cbs;
+    r[i-ds] = this[i]>>bs;
+  }
+  if(bs > 0) r[this.t-ds-1] |= (this.s&bm)<<cbs;
+  r.t = this.t-ds;
+  r.clamp();
+}
+
+// (protected) r = this - a
+function bnpSubTo(a,r) {
+  var i = 0, c = 0, m = Math.min(a.t,this.t);
+  while(i < m) {
+    c += this[i]-a[i];
+    r[i++] = c&this.DM;
+    c >>= this.DB;
+  }
+  if(a.t < this.t) {
+    c -= a.s;
+    while(i < this.t) {
+      c += this[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c += this.s;
+  }
+  else {
+    c += this.s;
+    while(i < a.t) {
+      c -= a[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c -= a.s;
+  }
+  r.s = (c<0)?-1:0;
+  if(c < -1) r[i++] = this.DV+c;
+  else if(c > 0) r[i++] = c;
+  r.t = i;
+  r.clamp();
+}
+
+// (protected) r = this * a, r != this,a (HAC 14.12)
+// "this" should be the larger one if appropriate.
+function bnpMultiplyTo(a,r) {
+  var x = this.abs(), y = a.abs();
+  var i = x.t;
+  r.t = i+y.t;
+  while(--i >= 0) r[i] = 0;
+  for(i = 0; i < y.t; ++i) r[i+x.t] = x.am(0,y[i],r,i,0,x.t);
+  r.s = 0;
+  r.clamp();
+  if(this.s != a.s) BigInteger.ZERO.subTo(r,r);
+}
+
+// (protected) r = this^2, r != this (HAC 14.16)
+function bnpSquareTo(r) {
+  var x = this.abs();
+  var i = r.t = 2*x.t;
+  while(--i >= 0) r[i] = 0;
+  for(i = 0; i < x.t-1; ++i) {
+    var c = x.am(i,x[i],r,2*i,0,1);
+    if((r[i+x.t]+=x.am(i+1,2*x[i],r,2*i+1,c,x.t-i-1)) >= x.DV) {
+      r[i+x.t] -= x.DV;
+      r[i+x.t+1] = 1;
+    }
+  }
+  if(r.t > 0) r[r.t-1] += x.am(i,x[i],r,2*i,0,1);
+  r.s = 0;
+  r.clamp();
+}
+
+// (protected) divide this by m, quotient and remainder to q, r (HAC 14.20)
+// r != q, this != m.  q or r may be null.
+function bnpDivRemTo(m,q,r) {
+  var pm = m.abs();
+  if(pm.t <= 0) return;
+  var pt = this.abs();
+  if(pt.t < pm.t) {
+    if(q != null) q.fromInt(0);
+    if(r != null) this.copyTo(r);
+    return;
+  }
+  if(r == null) r = nbi();
+  var y = nbi(), ts = this.s, ms = m.s;
+  var nsh = this.DB-nbits(pm[pm.t-1]);	// normalize modulus
+  if(nsh > 0) { pm.lShiftTo(nsh,y); pt.lShiftTo(nsh,r); }
+  else { pm.copyTo(y); pt.copyTo(r); }
+  var ys = y.t;
+  var y0 = y[ys-1];
+  if(y0 == 0) return;
+  var yt = y0*(1<<this.F1)+((ys>1)?y[ys-2]>>this.F2:0);
+  var d1 = this.FV/yt, d2 = (1<<this.F1)/yt, e = 1<<this.F2;
+  var i = r.t, j = i-ys, t = (q==null)?nbi():q;
+  y.dlShiftTo(j,t);
+  if(r.compareTo(t) >= 0) {
+    r[r.t++] = 1;
+    r.subTo(t,r);
+  }
+  BigInteger.ONE.dlShiftTo(ys,t);
+  t.subTo(y,y);	// "negative" y so we can replace sub with am later
+  while(y.t < ys) y[y.t++] = 0;
+  while(--j >= 0) {
+    // Estimate quotient digit
+    var qd = (r[--i]==y0)?this.DM:Math.floor(r[i]*d1+(r[i-1]+e)*d2);
+    if((r[i]+=y.am(0,qd,r,j,0,ys)) < qd) {	// Try it out
+      y.dlShiftTo(j,t);
+      r.subTo(t,r);
+      while(r[i] < --qd) r.subTo(t,r);
+    }
+  }
+  if(q != null) {
+    r.drShiftTo(ys,q);
+    if(ts != ms) BigInteger.ZERO.subTo(q,q);
+  }
+  r.t = ys;
+  r.clamp();
+  if(nsh > 0) r.rShiftTo(nsh,r);	// Denormalize remainder
+  if(ts < 0) BigInteger.ZERO.subTo(r,r);
+}
+
+// (public) this mod a
+function bnMod(a) {
+  var r = nbi();
+  this.abs().divRemTo(a,null,r);
+  if(this.s < 0 && r.compareTo(BigInteger.ZERO) > 0) a.subTo(r,r);
+  return r;
+}
+
+// Modular reduction using "classic" algorithm
+function Classic(m) { this.m = m; }
+function cConvert(x) {
+  if(x.s < 0 || x.compareTo(this.m) >= 0) return x.mod(this.m);
+  else return x;
+}
+function cRevert(x) { return x; }
+function cReduce(x) { x.divRemTo(this.m,null,x); }
+function cMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+function cSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+Classic.prototype.convert = cConvert;
+Classic.prototype.revert = cRevert;
+Classic.prototype.reduce = cReduce;
+Classic.prototype.mulTo = cMulTo;
+Classic.prototype.sqrTo = cSqrTo;
+
+// (protected) return "-1/this % 2^DB"; useful for Mont. reduction
+// justification:
+//         xy == 1 (mod m)
+//         xy =  1+km
+//   xy(2-xy) = (1+km)(1-km)
+// x[y(2-xy)] = 1-k^2m^2
+// x[y(2-xy)] == 1 (mod m^2)
+// if y is 1/x mod m, then y(2-xy) is 1/x mod m^2
+// should reduce x and y(2-xy) by m^2 at each step to keep size bounded.
+// JS multiply "overflows" differently from C/C++, so care is needed here.
+function bnpInvDigit() {
+  if(this.t < 1) return 0;
+  var x = this[0];
+  if((x&1) == 0) return 0;
+  var y = x&3;		// y == 1/x mod 2^2
+  y = (y*(2-(x&0xf)*y))&0xf;	// y == 1/x mod 2^4
+  y = (y*(2-(x&0xff)*y))&0xff;	// y == 1/x mod 2^8
+  y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff;	// y == 1/x mod 2^16
+  // last step - calculate inverse mod DV directly;
+  // assumes 16 < DB <= 32 and assumes ability to handle 48-bit ints
+  y = (y*(2-x*y%this.DV))%this.DV;		// y == 1/x mod 2^dbits
+  // we really want the negative inverse, and -DV < y < DV
+  return (y>0)?this.DV-y:-y;
+}
+
+// Montgomery reduction
+function Montgomery(m) {
+  this.m = m;
+  this.mp = m.invDigit();
+  this.mpl = this.mp&0x7fff;
+  this.mph = this.mp>>15;
+  this.um = (1<<(m.DB-15))-1;
+  this.mt2 = 2*m.t;
+}
+
+// xR mod m
+function montConvert(x) {
+  var r = nbi();
+  x.abs().dlShiftTo(this.m.t,r);
+  r.divRemTo(this.m,null,r);
+  if(x.s < 0 && r.compareTo(BigInteger.ZERO) > 0) this.m.subTo(r,r);
+  return r;
+}
+
+// x/R mod m
+function montRevert(x) {
+  var r = nbi();
+  x.copyTo(r);
+  this.reduce(r);
+  return r;
+}
+
+// x = x/R mod m (HAC 14.32)
+function montReduce(x) {
+  while(x.t <= this.mt2)	// pad x so am has enough room later
+    x[x.t++] = 0;
+  for(var i = 0; i < this.m.t; ++i) {
+    // faster way of calculating u0 = x[i]*mp mod DV
+    var j = x[i]&0x7fff;
+    var u0 = (j*this.mpl+(((j*this.mph+(x[i]>>15)*this.mpl)&this.um)<<15))&x.DM;
+    // use am to combine the multiply-shift-add into one call
+    j = i+this.m.t;
+    x[j] += this.m.am(0,u0,x,i,0,this.m.t);
+    // propagate carry
+    while(x[j] >= x.DV) { x[j] -= x.DV; x[++j]++; }
+  }
+  x.clamp();
+  x.drShiftTo(this.m.t,x);
+  if(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
+}
+
+// r = "x^2/R mod m"; x != r
+function montSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+// r = "xy/R mod m"; x,y != r
+function montMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+
+Montgomery.prototype.convert = montConvert;
+Montgomery.prototype.revert = montRevert;
+Montgomery.prototype.reduce = montReduce;
+Montgomery.prototype.mulTo = montMulTo;
+Montgomery.prototype.sqrTo = montSqrTo;
+
+// (protected) true iff this is even
+function bnpIsEven() { return ((this.t>0)?(this[0]&1):this.s) == 0; }
+
+// (protected) this^e, e < 2^32, doing sqr and mul with "r" (HAC 14.79)
+function bnpExp(e,z) {
+  if(e > 0xffffffff || e < 1) return BigInteger.ONE;
+  var r = nbi(), r2 = nbi(), g = z.convert(this), i = nbits(e)-1;
+  g.copyTo(r);
+  while(--i >= 0) {
+    z.sqrTo(r,r2);
+    if((e&(1<<i)) > 0) z.mulTo(r2,g,r);
+    else { var t = r; r = r2; r2 = t; }
+  }
+  return z.revert(r);
+}
+
+// (public) this^e % m, 0 <= e < 2^32
+function bnModPowInt(e,m) {
+  var z;
+  if(e < 256 || m.isEven()) z = new Classic(m); else z = new Montgomery(m);
+  return this.exp(e,z);
+}
+
+// protected
+BigInteger.prototype.copyTo = bnpCopyTo;
+BigInteger.prototype.fromInt = bnpFromInt;
+BigInteger.prototype.fromString = bnpFromString;
+BigInteger.prototype.clamp = bnpClamp;
+BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
+BigInteger.prototype.drShiftTo = bnpDRShiftTo;
+BigInteger.prototype.lShiftTo = bnpLShiftTo;
+BigInteger.prototype.rShiftTo = bnpRShiftTo;
+BigInteger.prototype.subTo = bnpSubTo;
+BigInteger.prototype.multiplyTo = bnpMultiplyTo;
+BigInteger.prototype.squareTo = bnpSquareTo;
+BigInteger.prototype.divRemTo = bnpDivRemTo;
+BigInteger.prototype.invDigit = bnpInvDigit;
+BigInteger.prototype.isEven = bnpIsEven;
+BigInteger.prototype.exp = bnpExp;
+
+// public
+BigInteger.prototype.toString = bnToString;
+BigInteger.prototype.negate = bnNegate;
+BigInteger.prototype.abs = bnAbs;
+BigInteger.prototype.compareTo = bnCompareTo;
+BigInteger.prototype.bitLength = bnBitLength;
+BigInteger.prototype.mod = bnMod;
+BigInteger.prototype.modPowInt = bnModPowInt;
+
+// "constants"
+BigInteger.ZERO = nbv(0);
+BigInteger.ONE = nbv(1);
+// Copyright (c) 2005-2009  Tom Wu
+// All Rights Reserved.
+// See "LICENSE" for details.
+
+// Extended JavaScript BN functions, required for RSA private ops.
+
+// Version 1.1: new BigInteger("0", 10) returns "proper" zero
+
+// (public)
+function bnClone() { var r = nbi(); this.copyTo(r); return r; }
+
+// (public) return value as integer
+function bnIntValue() {
+  if(this.s < 0) {
+    if(this.t == 1) return this[0]-this.DV;
+    else if(this.t == 0) return -1;
+  }
+  else if(this.t == 1) return this[0];
+  else if(this.t == 0) return 0;
+  // assumes 16 < DB < 32
+  return ((this[1]&((1<<(32-this.DB))-1))<<this.DB)|this[0];
+}
+
+// (public) return value as byte
+function bnByteValue() { return (this.t==0)?this.s:(this[0]<<24)>>24; }
+
+// (public) return value as short (assumes DB>=16)
+function bnShortValue() { return (this.t==0)?this.s:(this[0]<<16)>>16; }
+
+// (protected) return x s.t. r^x < DV
+function bnpChunkSize(r) { return Math.floor(Math.LN2*this.DB/Math.log(r)); }
+
+// (public) 0 if this == 0, 1 if this > 0
+function bnSigNum() {
+  if(this.s < 0) return -1;
+  else if(this.t <= 0 || (this.t == 1 && this[0] <= 0)) return 0;
+  else return 1;
+}
+
+// (protected) convert to radix string
+function bnpToRadix(b) {
+  if(b == null) b = 10;
+  if(this.signum() == 0 || b < 2 || b > 36) return "0";
+  var cs = this.chunkSize(b);
+  var a = Math.pow(b,cs);
+  var d = nbv(a), y = nbi(), z = nbi(), r = "";
+  this.divRemTo(d,y,z);
+  while(y.signum() > 0) {
+    r = (a+z.intValue()).toString(b).substr(1) + r;
+    y.divRemTo(d,y,z);
+  }
+  return z.intValue().toString(b) + r;
+}
+
+// (protected) convert from radix string
+function bnpFromRadix(s,b) {
+  this.fromInt(0);
+  if(b == null) b = 10;
+  var cs = this.chunkSize(b);
+  var d = Math.pow(b,cs), mi = false, j = 0, w = 0;
+  for(var i = 0; i < s.length; ++i) {
+    var x = intAt(s,i);
+    if(x < 0) {
+      if(s.charAt(i) == "-" && this.signum() == 0) mi = true;
+      continue;
+    }
+    w = b*w+x;
+    if(++j >= cs) {
+      this.dMultiply(d);
+      this.dAddOffset(w,0);
+      j = 0;
+      w = 0;
+    }
+  }
+  if(j > 0) {
+    this.dMultiply(Math.pow(b,j));
+    this.dAddOffset(w,0);
+  }
+  if(mi) BigInteger.ZERO.subTo(this,this);
+}
+
+// (protected) alternate constructor
+function bnpFromNumber(a,b,c) {
+  if("number" == typeof b) {
+    // new BigInteger(int,int,RNG)
+    if(a < 2) this.fromInt(1);
+    else {
+      this.fromNumber(a,c);
+      if(!this.testBit(a-1))	// force MSB set
+        this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);
+      if(this.isEven()) this.dAddOffset(1,0); // force odd
+      while(!this.isProbablePrime(b)) {
+        this.dAddOffset(2,0);
+        if(this.bitLength() > a) this.subTo(BigInteger.ONE.shiftLeft(a-1),this);
+      }
+    }
+  }
+  else {
+    // new BigInteger(int,RNG)
+    var x = new Array(), t = a&7;
+    x.length = (a>>3)+1;
+    b.nextBytes(x);
+    if(t > 0) x[0] &= ((1<<t)-1); else x[0] = 0;
+    this.fromString(x,256);
+  }
+}
+
+// (public) convert to bigendian byte array
+function bnToByteArray() {
+  var i = this.t, r = new Array();
+  r[0] = this.s;
+  var p = this.DB-(i*this.DB)%8, d, k = 0;
+  if(i-- > 0) {
+    if(p < this.DB && (d = this[i]>>p) != (this.s&this.DM)>>p)
+      r[k++] = d|(this.s<<(this.DB-p));
+    while(i >= 0) {
+      if(p < 8) {
+        d = (this[i]&((1<<p)-1))<<(8-p);
+        d |= this[--i]>>(p+=this.DB-8);
+      }
+      else {
+        d = (this[i]>>(p-=8))&0xff;
+        if(p <= 0) { p += this.DB; --i; }
+      }
+      if((d&0x80) != 0) d |= -256;
+      if(k == 0 && (this.s&0x80) != (d&0x80)) ++k;
+      if(k > 0 || d != this.s) r[k++] = d;
+    }
+  }
+  return r;
+}
+
+function bnEquals(a) { return(this.compareTo(a)==0); }
+function bnMin(a) { return(this.compareTo(a)<0)?this:a; }
+function bnMax(a) { return(this.compareTo(a)>0)?this:a; }
+
+// (protected) r = this op a (bitwise)
+function bnpBitwiseTo(a,op,r) {
+  var i, f, m = Math.min(a.t,this.t);
+  for(i = 0; i < m; ++i) r[i] = op(this[i],a[i]);
+  if(a.t < this.t) {
+    f = a.s&this.DM;
+    for(i = m; i < this.t; ++i) r[i] = op(this[i],f);
+    r.t = this.t;
+  }
+  else {
+    f = this.s&this.DM;
+    for(i = m; i < a.t; ++i) r[i] = op(f,a[i]);
+    r.t = a.t;
+  }
+  r.s = op(this.s,a.s);
+  r.clamp();
+}
+
+// (public) this & a
+function op_and(x,y) { return x&y; }
+function bnAnd(a) { var r = nbi(); this.bitwiseTo(a,op_and,r); return r; }
+
+// (public) this | a
+function op_or(x,y) { return x|y; }
+function bnOr(a) { var r = nbi(); this.bitwiseTo(a,op_or,r); return r; }
+
+// (public) this ^ a
+function op_xor(x,y) { return x^y; }
+function bnXor(a) { var r = nbi(); this.bitwiseTo(a,op_xor,r); return r; }
+
+// (public) this & ~a
+function op_andnot(x,y) { return x&~y; }
+function bnAndNot(a) { var r = nbi(); this.bitwiseTo(a,op_andnot,r); return r; }
+
+// (public) ~this
+function bnNot() {
+  var r = nbi();
+  for(var i = 0; i < this.t; ++i) r[i] = this.DM&~this[i];
+  r.t = this.t;
+  r.s = ~this.s;
+  return r;
+}
+
+// (public) this << n
+function bnShiftLeft(n) {
+  var r = nbi();
+  if(n < 0) this.rShiftTo(-n,r); else this.lShiftTo(n,r);
+  return r;
+}
+
+// (public) this >> n
+function bnShiftRight(n) {
+  var r = nbi();
+  if(n < 0) this.lShiftTo(-n,r); else this.rShiftTo(n,r);
+  return r;
+}
+
+// return index of lowest 1-bit in x, x < 2^31
+function lbit(x) {
+  if(x == 0) return -1;
+  var r = 0;
+  if((x&0xffff) == 0) { x >>= 16; r += 16; }
+  if((x&0xff) == 0) { x >>= 8; r += 8; }
+  if((x&0xf) == 0) { x >>= 4; r += 4; }
+  if((x&3) == 0) { x >>= 2; r += 2; }
+  if((x&1) == 0) ++r;
+  return r;
+}
+
+// (public) returns index of lowest 1-bit (or -1 if none)
+function bnGetLowestSetBit() {
+  for(var i = 0; i < this.t; ++i)
+    if(this[i] != 0) return i*this.DB+lbit(this[i]);
+  if(this.s < 0) return this.t*this.DB;
+  return -1;
+}
+
+// return number of 1 bits in x
+function cbit(x) {
+  var r = 0;
+  while(x != 0) { x &= x-1; ++r; }
+  return r;
+}
+
+// (public) return number of set bits
+function bnBitCount() {
+  var r = 0, x = this.s&this.DM;
+  for(var i = 0; i < this.t; ++i) r += cbit(this[i]^x);
+  return r;
+}
+
+// (public) true iff nth bit is set
+function bnTestBit(n) {
+  var j = Math.floor(n/this.DB);
+  if(j >= this.t) return(this.s!=0);
+  return((this[j]&(1<<(n%this.DB)))!=0);
+}
+
+// (protected) this op (1<<n)
+function bnpChangeBit(n,op) {
+  var r = BigInteger.ONE.shiftLeft(n);
+  this.bitwiseTo(r,op,r);
+  return r;
+}
+
+// (public) this | (1<<n)
+function bnSetBit(n) { return this.changeBit(n,op_or); }
+
+// (public) this & ~(1<<n)
+function bnClearBit(n) { return this.changeBit(n,op_andnot); }
+
+// (public) this ^ (1<<n)
+function bnFlipBit(n) { return this.changeBit(n,op_xor); }
+
+// (protected) r = this + a
+function bnpAddTo(a,r) {
+  var i = 0, c = 0, m = Math.min(a.t,this.t);
+  while(i < m) {
+    c += this[i]+a[i];
+    r[i++] = c&this.DM;
+    c >>= this.DB;
+  }
+  if(a.t < this.t) {
+    c += a.s;
+    while(i < this.t) {
+      c += this[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c += this.s;
+  }
+  else {
+    c += this.s;
+    while(i < a.t) {
+      c += a[i];
+      r[i++] = c&this.DM;
+      c >>= this.DB;
+    }
+    c += a.s;
+  }
+  r.s = (c<0)?-1:0;
+  if(c > 0) r[i++] = c;
+  else if(c < -1) r[i++] = this.DV+c;
+  r.t = i;
+  r.clamp();
+}
+
+// (public) this + a
+function bnAdd(a) { var r = nbi(); this.addTo(a,r); return r; }
+
+// (public) this - a
+function bnSubtract(a) { var r = nbi(); this.subTo(a,r); return r; }
+
+// (public) this * a
+function bnMultiply(a) { var r = nbi(); this.multiplyTo(a,r); return r; }
+
+// (public) this / a
+function bnDivide(a) { var r = nbi(); this.divRemTo(a,r,null); return r; }
+
+// (public) this % a
+function bnRemainder(a) { var r = nbi(); this.divRemTo(a,null,r); return r; }
+
+// (public) [this/a,this%a]
+function bnDivideAndRemainder(a) {
+  var q = nbi(), r = nbi();
+  this.divRemTo(a,q,r);
+  return new Array(q,r);
+}
+
+// (protected) this *= n, this >= 0, 1 < n < DV
+function bnpDMultiply(n) {
+  this[this.t] = this.am(0,n-1,this,0,0,this.t);
+  ++this.t;
+  this.clamp();
+}
+
+// (protected) this += n << w words, this >= 0
+function bnpDAddOffset(n,w) {
+  if(n == 0) return;
+  while(this.t <= w) this[this.t++] = 0;
+  this[w] += n;
+  while(this[w] >= this.DV) {
+    this[w] -= this.DV;
+    if(++w >= this.t) this[this.t++] = 0;
+    ++this[w];
+  }
+}
+
+// A "null" reducer
+function NullExp() {}
+function nNop(x) { return x; }
+function nMulTo(x,y,r) { x.multiplyTo(y,r); }
+function nSqrTo(x,r) { x.squareTo(r); }
+
+NullExp.prototype.convert = nNop;
+NullExp.prototype.revert = nNop;
+NullExp.prototype.mulTo = nMulTo;
+NullExp.prototype.sqrTo = nSqrTo;
+
+// (public) this^e
+function bnPow(e) { return this.exp(e,new NullExp()); }
+
+// (protected) r = lower n words of "this * a", a.t <= n
+// "this" should be the larger one if appropriate.
+function bnpMultiplyLowerTo(a,n,r) {
+  var i = Math.min(this.t+a.t,n);
+  r.s = 0; // assumes a,this >= 0
+  r.t = i;
+  while(i > 0) r[--i] = 0;
+  var j;
+  for(j = r.t-this.t; i < j; ++i) r[i+this.t] = this.am(0,a[i],r,i,0,this.t);
+  for(j = Math.min(a.t,n); i < j; ++i) this.am(0,a[i],r,i,0,n-i);
+  r.clamp();
+}
+
+// (protected) r = "this * a" without lower n words, n > 0
+// "this" should be the larger one if appropriate.
+function bnpMultiplyUpperTo(a,n,r) {
+  --n;
+  var i = r.t = this.t+a.t-n;
+  r.s = 0; // assumes a,this >= 0
+  while(--i >= 0) r[i] = 0;
+  for(i = Math.max(n-this.t,0); i < a.t; ++i)
+    r[this.t+i-n] = this.am(n-i,a[i],r,0,0,this.t+i-n);
+  r.clamp();
+  r.drShiftTo(1,r);
+}
+
+// Barrett modular reduction
+function Barrett(m) {
+  // setup Barrett
+  this.r2 = nbi();
+  this.q3 = nbi();
+  BigInteger.ONE.dlShiftTo(2*m.t,this.r2);
+  this.mu = this.r2.divide(m);
+  this.m = m;
+}
+
+function barrettConvert(x) {
+  if(x.s < 0 || x.t > 2*this.m.t) return x.mod(this.m);
+  else if(x.compareTo(this.m) < 0) return x;
+  else { var r = nbi(); x.copyTo(r); this.reduce(r); return r; }
+}
+
+function barrettRevert(x) { return x; }
+
+// x = x mod m (HAC 14.42)
+function barrettReduce(x) {
+  x.drShiftTo(this.m.t-1,this.r2);
+  if(x.t > this.m.t+1) { x.t = this.m.t+1; x.clamp(); }
+  this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);
+  this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);
+  while(x.compareTo(this.r2) < 0) x.dAddOffset(1,this.m.t+1);
+  x.subTo(this.r2,x);
+  while(x.compareTo(this.m) >= 0) x.subTo(this.m,x);
+}
+
+// r = x^2 mod m; x != r
+function barrettSqrTo(x,r) { x.squareTo(r); this.reduce(r); }
+
+// r = x*y mod m; x,y != r
+function barrettMulTo(x,y,r) { x.multiplyTo(y,r); this.reduce(r); }
+
+Barrett.prototype.convert = barrettConvert;
+Barrett.prototype.revert = barrettRevert;
+Barrett.prototype.reduce = barrettReduce;
+Barrett.prototype.mulTo = barrettMulTo;
+Barrett.prototype.sqrTo = barrettSqrTo;
+
+// (public) this^e % m (HAC 14.85)
+function bnModPow(e,m) {
+  var i = e.bitLength(), k, r = nbv(1), z;
+  if(i <= 0) return r;
+  else if(i < 18) k = 1;
+  else if(i < 48) k = 3;
+  else if(i < 144) k = 4;
+  else if(i < 768) k = 5;
+  else k = 6;
+  if(i < 8)
+    z = new Classic(m);
+  else if(m.isEven())
+    z = new Barrett(m);
+  else
+    z = new Montgomery(m);
+
+  // precomputation
+  var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
+  g[1] = z.convert(this);
+  if(k > 1) {
+    var g2 = nbi();
+    z.sqrTo(g[1],g2);
+    while(n <= km) {
+      g[n] = nbi();
+      z.mulTo(g2,g[n-2],g[n]);
+      n += 2;
+    }
+  }
+
+  var j = e.t-1, w, is1 = true, r2 = nbi(), t;
+  i = nbits(e[j])-1;
+  while(j >= 0) {
+    if(i >= k1) w = (e[j]>>(i-k1))&km;
+    else {
+      w = (e[j]&((1<<(i+1))-1))<<(k1-i);
+      if(j > 0) w |= e[j-1]>>(this.DB+i-k1);
+    }
+
+    n = k;
+    while((w&1) == 0) { w >>= 1; --n; }
+    if((i -= n) < 0) { i += this.DB; --j; }
+    if(is1) {	// ret == 1, don't bother squaring or multiplying it
+      g[w].copyTo(r);
+      is1 = false;
+    }
+    else {
+      while(n > 1) { z.sqrTo(r,r2); z.sqrTo(r2,r); n -= 2; }
+      if(n > 0) z.sqrTo(r,r2); else { t = r; r = r2; r2 = t; }
+      z.mulTo(r2,g[w],r);
+    }
+
+    while(j >= 0 && (e[j]&(1<<i)) == 0) {
+      z.sqrTo(r,r2); t = r; r = r2; r2 = t;
+      if(--i < 0) { i = this.DB-1; --j; }
+    }
+  }
+  return z.revert(r);
+}
+
+// (public) gcd(this,a) (HAC 14.54)
+function bnGCD(a) {
+  var x = (this.s<0)?this.negate():this.clone();
+  var y = (a.s<0)?a.negate():a.clone();
+  if(x.compareTo(y) < 0) { var t = x; x = y; y = t; }
+  var i = x.getLowestSetBit(), g = y.getLowestSetBit();
+  if(g < 0) return x;
+  if(i < g) g = i;
+  if(g > 0) {
+    x.rShiftTo(g,x);
+    y.rShiftTo(g,y);
+  }
+  while(x.signum() > 0) {
+    if((i = x.getLowestSetBit()) > 0) x.rShiftTo(i,x);
+    if((i = y.getLowestSetBit()) > 0) y.rShiftTo(i,y);
+    if(x.compareTo(y) >= 0) {
+      x.subTo(y,x);
+      x.rShiftTo(1,x);
+    }
+    else {
+      y.subTo(x,y);
+      y.rShiftTo(1,y);
+    }
+  }
+  if(g > 0) y.lShiftTo(g,y);
+  return y;
+}
+
+// (protected) this % n, n < 2^26
+function bnpModInt(n) {
+  if(n <= 0) return 0;
+  var d = this.DV%n, r = (this.s<0)?n-1:0;
+  if(this.t > 0)
+    if(d == 0) r = this[0]%n;
+    else for(var i = this.t-1; i >= 0; --i) r = (d*r+this[i])%n;
+  return r;
+}
+
+// (public) 1/this % m (HAC 14.61)
+function bnModInverse(m) {
+  var ac = m.isEven();
+  if((this.isEven() && ac) || m.signum() == 0) return BigInteger.ZERO;
+  var u = m.clone(), v = this.clone();
+  var a = nbv(1), b = nbv(0), c = nbv(0), d = nbv(1);
+  while(u.signum() != 0) {
+    while(u.isEven()) {
+      u.rShiftTo(1,u);
+      if(ac) {
+        if(!a.isEven() || !b.isEven()) { a.addTo(this,a); b.subTo(m,b); }
+        a.rShiftTo(1,a);
+      }
+      else if(!b.isEven()) b.subTo(m,b);
+      b.rShiftTo(1,b);
+    }
+    while(v.isEven()) {
+      v.rShiftTo(1,v);
+      if(ac) {
+        if(!c.isEven() || !d.isEven()) { c.addTo(this,c); d.subTo(m,d); }
+        c.rShiftTo(1,c);
+      }
+      else if(!d.isEven()) d.subTo(m,d);
+      d.rShiftTo(1,d);
+    }
+    if(u.compareTo(v) >= 0) {
+      u.subTo(v,u);
+      if(ac) a.subTo(c,a);
+      b.subTo(d,b);
+    }
+    else {
+      v.subTo(u,v);
+      if(ac) c.subTo(a,c);
+      d.subTo(b,d);
+    }
+  }
+  if(v.compareTo(BigInteger.ONE) != 0) return BigInteger.ZERO;
+  if(d.compareTo(m) >= 0) return d.subtract(m);
+  if(d.signum() < 0) d.addTo(m,d); else return d;
+  if(d.signum() < 0) return d.add(m); else return d;
+}
+
+var lowprimes = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509];
+var lplim = (1<<26)/lowprimes[lowprimes.length-1];
+
+// (public) test primality with certainty >= 1-.5^t
+function bnIsProbablePrime(t) {
+  var i, x = this.abs();
+  if(x.t == 1 && x[0] <= lowprimes[lowprimes.length-1]) {
+    for(i = 0; i < lowprimes.length; ++i)
+      if(x[0] == lowprimes[i]) return true;
+    return false;
+  }
+  if(x.isEven()) return false;
+  i = 1;
+  while(i < lowprimes.length) {
+    var m = lowprimes[i], j = i+1;
+    while(j < lowprimes.length && m < lplim) m *= lowprimes[j++];
+    m = x.modInt(m);
+    while(i < j) if(m%lowprimes[i++] == 0) return false;
+  }
+  return x.millerRabin(t);
+}
+
+// (protected) true if probably prime (HAC 4.24, Miller-Rabin)
+function bnpMillerRabin(t) {
+  var n1 = this.subtract(BigInteger.ONE);
+  var k = n1.getLowestSetBit();
+  if(k <= 0) return false;
+  var r = n1.shiftRight(k);
+  t = (t+1)>>1;
+  if(t > lowprimes.length) t = lowprimes.length;
+  var a = nbi();
+  for(var i = 0; i < t; ++i) {
+    a.fromInt(lowprimes[i]);
+    var y = a.modPow(r,this);
+    if(y.compareTo(BigInteger.ONE) != 0 && y.compareTo(n1) != 0) {
+      var j = 1;
+      while(j++ < k && y.compareTo(n1) != 0) {
+        y = y.modPowInt(2,this);
+        if(y.compareTo(BigInteger.ONE) == 0) return false;
+      }
+      if(y.compareTo(n1) != 0) return false;
+    }
+  }
+  return true;
+}
+
+// protected
+BigInteger.prototype.chunkSize = bnpChunkSize;
+BigInteger.prototype.toRadix = bnpToRadix;
+BigInteger.prototype.fromRadix = bnpFromRadix;
+BigInteger.prototype.fromNumber = bnpFromNumber;
+BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
+BigInteger.prototype.changeBit = bnpChangeBit;
+BigInteger.prototype.addTo = bnpAddTo;
+BigInteger.prototype.dMultiply = bnpDMultiply;
+BigInteger.prototype.dAddOffset = bnpDAddOffset;
+BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
+BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
+BigInteger.prototype.modInt = bnpModInt;
+BigInteger.prototype.millerRabin = bnpMillerRabin;
+
+// public
+BigInteger.prototype.clone = bnClone;
+BigInteger.prototype.intValue = bnIntValue;
+BigInteger.prototype.byteValue = bnByteValue;
+BigInteger.prototype.shortValue = bnShortValue;
+BigInteger.prototype.signum = bnSigNum;
+BigInteger.prototype.toByteArray = bnToByteArray;
+BigInteger.prototype.equals = bnEquals;
+BigInteger.prototype.min = bnMin;
+BigInteger.prototype.max = bnMax;
+BigInteger.prototype.and = bnAnd;
+BigInteger.prototype.or = bnOr;
+BigInteger.prototype.xor = bnXor;
+BigInteger.prototype.andNot = bnAndNot;
+BigInteger.prototype.not = bnNot;
+BigInteger.prototype.shiftLeft = bnShiftLeft;
+BigInteger.prototype.shiftRight = bnShiftRight;
+BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
+BigInteger.prototype.bitCount = bnBitCount;
+BigInteger.prototype.testBit = bnTestBit;
+BigInteger.prototype.setBit = bnSetBit;
+BigInteger.prototype.clearBit = bnClearBit;
+BigInteger.prototype.flipBit = bnFlipBit;
+BigInteger.prototype.add = bnAdd;
+BigInteger.prototype.subtract = bnSubtract;
+BigInteger.prototype.multiply = bnMultiply;
+BigInteger.prototype.divide = bnDivide;
+BigInteger.prototype.remainder = bnRemainder;
+BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
+BigInteger.prototype.modPow = bnModPow;
+BigInteger.prototype.modInverse = bnModInverse;
+BigInteger.prototype.pow = bnPow;
+BigInteger.prototype.gcd = bnGCD;
+BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
+
+// BigInteger interfaces not implemented in jsbn:
+
+// BigInteger(int signum, byte[] magnitude)
+// double doubleValue()
+// float floatValue()
+// int hashCode()
+// long longValue()
+// static BigInteger valueOf(long val)
+/**
+ * @author: Meki Cherkaoui, Jeff Thompson, Wentao Shang
+ * See COPYING for copyright and distribution information.
+ * This class represents the top-level object for communicating with an NDN host.
+ */
+
+var LOG = 0;
+
+/**
+ * settings is an associative array with the following defaults:
+ * {
+ *   getTransport: function() { return new WebSocketTransport(); },
+ *   getHostAndPort: transport.defaultGetHostAndPort,
+ *   host: null, // 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."); },
+ *   verify: true // If false, don't verify and call upcall with Closure.UPCALL_CONTENT_UNVERIFIED.
+ * }
+ * 
+ * getHostAndPort is a function, on each call it returns a new { host: host, port: port } or
+ *   null if there are no more hosts.
+ *   
+ * This throws an exception if NDN.supported is false.
+ */
+var NDN = function NDN(settings) {
+    if (!NDN.supported)
+        throw new Error("The necessary JavaScript support is not available on this platform.");
+    
+    settings = (settings || {});
+    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 : null);
+	this.port = (settings.port || 9696);
+    this.readyStatus = NDN.UNOPEN;
+    this.verify = (settings.verify !== undefined ? settings.verify : true);
+    // 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
+NDN.OPENED = 1;  // connection to ccnd opened
+NDN.CLOSED = 2;  // connection to ccnd closed
+
+/*
+ * Return true if necessary JavaScript support is available, else log an error and return false.
+ */
+NDN.getSupported = function() {
+    try {
+        var dummy = new Uint8Array(1).subarray(0, 1);
+    } catch (ex) {
+        console.log("NDN not available: Uint8Array not supported. " + ex);
+        return false;
+    }
+    
+    return true;
+};
+
+NDN.supported = NDN.getSupported();
+
+NDN.ccndIdFetcher = new Name('/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY');
+
+NDN.prototype.createRoute = function(host, port) {
+	this.host=host;
+	this.port=port;
+};
+
+
+NDN.KeyStore = new Array();
+
+var KeyStoreEntry = function KeyStoreEntry(name, rsa, time) {
+	this.keyName = name;  // KeyName
+	this.rsaKey = rsa;    // RSA key
+	this.timeStamp = time;  // Time Stamp
+};
+
+NDN.addKeyEntry = function(/* KeyStoreEntry */ keyEntry) {
+	var result = NDN.getKeyByName(keyEntry.keyName);
+	if (result == null) 
+		NDN.KeyStore.push(keyEntry);
+	else
+		result = keyEntry;
+};
+
+NDN.getKeyByName = function(/* KeyName */ name) {
+	var result = null;
+	
+	for (var i = 0; i < NDN.KeyStore.length; i++) {
+		if (NDN.KeyStore[i].keyName.contentName.match(name.contentName)) {
+            if (result == null || 
+                NDN.KeyStore[i].keyName.contentName.components.length > result.keyName.contentName.components.length)
+                result = NDN.KeyStore[i];
+        }
+	}
+    
+	return result;
+};
+
+// For fetching data
+NDN.PITTable = new Array();
+
+var PITEntry = function PITEntry(interest, closure) {
+	this.interest = interest;  // Interest
+	this.closure = closure;    // Closure
+	this.timerID = -1;  // Timer ID
+};
+
+/*
+ * Return the entry from NDN.PITTable where the name conforms to the interest selectors, and
+ * the interest name is the longest that matches name.
+ */
+NDN.getEntryForExpressedInterest = function(/*Name*/ name) {
+    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;
+};
+
+// 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.
+ */
+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),
+ *                 new UpcallInfo(this, interest, 0, contentObject)).                 
+ */
+NDN.prototype.expressInterest = function(
+        // Name
+        name,
+        // Closure
+        closure,
+        // Interest
+        template) {
+	var interest = new Interest(name);
+    if (template != null) {
+		interest.minSuffixComponents = template.minSuffixComponents;
+		interest.maxSuffixComponents = template.maxSuffixComponents;
+		interest.publisherPublicKeyDigest = template.publisherPublicKeyDigest;
+		interest.exclude = template.exclude;
+		interest.childSelector = template.childSelector;
+		interest.answerOriginKind = template.answerOriginKind;
+		interest.scope = template.scope;
+		interest.interestLifetime = template.interestLifetime;
+    }
+    else
+        interest.interestLifetime = 4000;   // default interest timeout value in milliseconds.
+
+	if (this.host == null || this.port == null) {
+        if (this.getHostAndPort == null)
+            console.log('ERROR: host OR port NOT SET');
+        else {
+            var thisNDN = this;
+            this.connectAndExecute
+                (function() { thisNDN.reconnectAndExpressInterest(interest, closure); });
+        }
+    }
+    else
+        this.reconnectAndExpressInterest(interest, closure);
+};
+
+/*
+ * If the host and port are different than the ones in this.transport, then call
+ *   this.transport.connect to change the connection (or connect for the first time).
+ * Then call expressInterestHelper.
+ */
+NDN.prototype.reconnectAndExpressInterest = function(interest, closure) {
+    if (this.transport.connectedHost != this.host || this.transport.connectedPort != this.port) {
+        var thisNDN = this;
+        this.transport.connect(thisNDN, function() { thisNDN.expressInterestHelper(interest, closure); });
+    }
+    else
+        this.expressInterestHelper(interest, closure);
+};
+
+/*
+ * Do the work of reconnectAndExpressInterest once we know we are connected.  Set the PITTable and call
+ *   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 timeoutMilliseconds = (interest.interestLifetime || 4000);
+        var timeoutCallback = function() {
+			if (LOG > 3) console.log("Interest time out: " + interest.name.to_uri());
+				
+			// 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);
+			if (index >= 0) 
+	            NDN.PITTable.splice(index, 1);
+				
+			// Raise closure callback
+			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(binaryInterest);
+};
+
+NDN.prototype.registerPrefix = function(name, closure, flag) {
+    var thisNDN = this;
+    var onConnected = function() {
+    	if (thisNDN.ccndid == null) {
+            // Fetch ccndid first, then register.
+            var interest = new Interest(NDN.ccndIdFetcher);
+    		interest.interestLifetime = 4000; // milliseconds
+            if (LOG>3) console.log('Expressing interest for ccndid from ccnd.');
+            thisNDN.reconnectAndExpressInterest
+               (interest, new NDN.FetchCcndidClosure(thisNDN, name, closure, flag));
+        }
+        else	
+            thisNDN.registerPrefixHelper(name, closure, flag);
+    };
+
+	if (this.host == null || this.port == null) {
+        if (this.getHostAndPort == null)
+            console.log('ERROR: host OR port NOT SET');
+        else
+            this.connectAndExecute(onConnected);
+    }
+    else
+        onConnected();
+};
+
+/*
+ * This is a closure to receive the ContentObject for NDN.ccndIdFetcher and call
+ *   registerPrefixHelper(name, callerClosure, flag).
+ */
+NDN.FetchCcndidClosure = function FetchCcndidClosure(ndn, name, callerClosure, flag) {
+    // Inherit from Closure.
+    Closure.call(this);
+    
+    this.ndn = ndn;
+    this.name = name;
+    this.callerClosure = callerClosure;
+    this.flag = flag;
+};
+
+NDN.FetchCcndidClosure.prototype.upcall = function(kind, upcallInfo) {
+    if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
+        console.log("Timeout while requesting the ccndid.  Cannot registerPrefix for " +
+            this.name.to_uri() + " .");
+        return Closure.RESULT_OK;
+    }
+    if (!(kind == Closure.UPCALL_CONTENT ||
+          kind == Closure.UPCALL_CONTENT_UNVERIFIED))
+        // The upcall is not for us.
+        return Closure.RESULT_ERR;
+       
+    var co = upcallInfo.contentObject;
+    if (!co.signedInfo || !co.signedInfo.publisher 
+		|| !co.signedInfo.publisher.publisherPublicKeyDigest)
+        console.log
+          ("ContentObject doesn't have a publisherPublicKeyDigest. Cannot set ccndid and registerPrefix for "
+           + this.name.to_uri() + " .");
+    else {
+		if (LOG>3) console.log('Got ccndid from ccnd.');
+		this.ndn.ccndid = co.signedInfo.publisher.publisherPublicKeyDigest;
+		if (LOG>3) console.log(this.ndn.ccndid);
+        
+        this.ndn.registerPrefixHelper(this.name, this.callerClosure, this.flag);
+	}
+    
+    return Closure.RESULT_OK;
+};
+
+/*
+ * Do the work of registerPrefix once we know we are connected with a ccndid.
+ */
+NDN.prototype.registerPrefixHelper = function(name, closure, flag) {
+	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));
+};
+
+/*
+ * 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) {
+    if (LOG>3) console.log('Complete element received. Length ' + element.length + '. Start decoding.');
+	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);
+				
+		var pitEntry = NDN.getEntryForExpressedInterest(co.name);
+		if (pitEntry != null) {
+			// Cancel interest timer
+			clearTimeout(pitEntry.timerID);
+            
+			// Remove PIT entry from NDN.PITTable
+			var index = NDN.PITTable.indexOf(pitEntry);
+			if (index >= 0)
+				NDN.PITTable.splice(index, 1);
+						
+			var currentClosure = pitEntry.closure;
+										
+			if (this.verify == false) {
+				// Pass content up without verifying the signature
+				currentClosure.upcall(Closure.UPCALL_CONTENT_UNVERIFIED, new UpcallInfo(this, null, 0, co));
+				return;
+			}
+				
+			// 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.');
+};
+
+/*
+ * 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 execute onConnected().
+ */
+NDN.prototype.connectAndExecute = function(onConnected) {
+    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;   
+    if (LOG>3) console.log("Connect: trying host from getHostAndPort: " + this.host);
+    
+    // Fetch any content.
+    var interest = new Interest(new Name("/"));
+	interest.interestLifetime = 4000; // milliseconds    
+
+    var thisNDN = this;
+	var timerID = setTimeout(function() {
+        if (LOG>3) console.log("Connect: timeout waiting for host " + thisNDN.host);
+        // Try again.
+        thisNDN.connectAndExecute(onConnected);
+	}, 3000);
+  
+    this.reconnectAndExpressInterest
+        (interest, new NDN.ConnectClosure(this, onConnected, timerID));
+};
+
+NDN.ConnectClosure = function ConnectClosure(ndn, onConnected, timerID) {
+    // Inherit from Closure.
+    Closure.call(this);
+    
+    this.ndn = ndn;
+    this.onConnected = onConnected;
+    this.timerID = timerID;
+};
+
+NDN.ConnectClosure.prototype.upcall = function(kind, upcallInfo) {
+    if (!(kind == Closure.UPCALL_CONTENT ||
+          kind == Closure.UPCALL_CONTENT_UNVERIFIED))
+        // The upcall is not for us.
+        return Closure.RESULT_ERR;
+        
+    // The host is alive, so cancel the timeout and continue with onConnected().
+    clearTimeout(this.timerID);
+
+    // Call NDN.onopen after success
+	this.ndn.readyStatus = NDN.OPENED;
+	this.ndn.onopen();
+
+    this.onConnected();
+
+    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) {
+    // 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));
+            var element = DataUtils.concatArrays(this.dataParts);
+            this.dataParts = [];
+            try {
+                this.elementListener.onReceivedElement(element);
+            } catch (ex) {
+                console.log("BinaryXmlElementReader: ignoring exception from onReceivedElement: " + ex);
+            }
+        
+            // Need to read a new object.
+            rawData = rawData.subarray(this.structureDecoder.offset, rawData.length);
+            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);
+			if (LOG>3) console.log('Incomplete packet received. Length ' + rawData.length + '. Wait for more input.');
+            return;
+        }
+    }    
+}
\ No newline at end of file
diff --git a/gui/html/ndn-js.js b/gui/html/ndn-js.js
index 8ce7d0a..df44082 100644
--- a/gui/html/ndn-js.js
+++ b/gui/html/ndn-js.js
@@ -1,19 +1,9 @@
-var Closure=function(){this.ndn_data=null;this.ndn_data_dirty=!1;this.timerID=-1};Closure.RESULT_ERR=-1;Closure.RESULT_OK=0;Closure.RESULT_REEXPRESS=1;Closure.RESULT_INTEREST_CONSUMED=2;Closure.RESULT_VERIFY=3;Closure.RESULT_FETCHKEY=4;Closure.UPCALL_FINAL=0;Closure.UPCALL_INTEREST=1;Closure.UPCALL_CONSUMED_INTEREST=2;Closure.UPCALL_CONTENT=3;Closure.UPCALL_INTEREST_TIMED_OUT=4;Closure.UPCALL_CONTENT_UNVERIFIED=5;Closure.UPCALL_CONTENT_BAD=6;Closure.prototype.upcall=function(){return Closure.RESULT_OK};
+var Closure=function(){this.ndn_data=null;this.ndn_data_dirty=!1};Closure.RESULT_ERR=-1;Closure.RESULT_OK=0;Closure.RESULT_REEXPRESS=1;Closure.RESULT_INTEREST_CONSUMED=2;Closure.RESULT_VERIFY=3;Closure.RESULT_FETCHKEY=4;Closure.UPCALL_FINAL=0;Closure.UPCALL_INTEREST=1;Closure.UPCALL_CONSUMED_INTEREST=2;Closure.UPCALL_CONTENT=3;Closure.UPCALL_INTEREST_TIMED_OUT=4;Closure.UPCALL_CONTENT_UNVERIFIED=5;Closure.UPCALL_CONTENT_BAD=6;Closure.prototype.upcall=function(){return Closure.RESULT_OK};
 var UpcallInfo=function(a,b,c,d){this.ndn=a;this.interest=b;this.matchedComps=c;this.contentObject=d};UpcallInfo.prototype.toString=function(){var a="ndn = "+this.ndn,a=a+("\nInterest = "+this.interest),a=a+("\nmatchedComps = "+this.matchedComps);return a+="\nContentObject: "+this.contentObject};
-var LOG=0,NDN=function NDN(b){b=b||{};this.host=b.host||"localhost";this.port=b.port||9696;this.transport=(b.getTransport||function(){return new WebSocketTransport})();this.readyStatus=NDN.UNOPEN;this.onopen=b.onopen||function(){3<LOG&&console.log("NDN connection established.")};this.onclose=b.onclose||function(){3<LOG&&console.log("NDN connection closed.")}};NDN.UNOPEN=0;NDN.OPENED=1;NDN.CLOSED=2;NDN.prototype.createRoute=function(a,b){this.host=a;this.port=b};
-NDN.prototype.expressInterest=function(a,b,c){null==this.host||null==this.port?dump("ERROR host OR port NOT SET\n"):(a=new Interest(a),null!=c?(a.minSuffixComponents=c.minSuffixComponents,a.maxSuffixComponents=c.maxSuffixComponents,a.publisherPublicKeyDigest=c.publisherPublicKeyDigest,a.exclude=c.exclude,a.childSelector=c.childSelector,a.answerOriginKind=c.answerOriginKind,a.scope=c.scope,a.interestLifetime=c.interestLifetime):a.interestLifetime=4,this.transport.expressInterest(this,a,b))};
-NDN.prototype.registerPrefix=function(a,b,c){return this.transport.registerPrefix(this,a,b,c)};var WebSocketTransport=function(){this.ccndid=this.ws=null;this.maxBufferSize=1E4;this.buffer=new Uint8Array(this.maxBufferSize);this.bufferOffset=0;this.structureDecoder=new BinaryXMLStructureDecoder},ccndIdFetcher="/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY";
-WebSocketTransport.prototype.connectWebSocket=function(a){null!=this.ws&&delete this.ws;this.ws=new WebSocket("ws://"+a.host+":"+a.port);0<LOG&&console.log("ws connection created.");this.ws.binaryType="arraybuffer";var b=this;this.ws.onmessage=function(c){c=c.data;if(null==c||void 0==c||""==c)console.log("INVALID ANSWER");else if(c instanceof ArrayBuffer){c=new Uint8Array(c);3<LOG&&console.log("BINARY RESPONSE IS "+DataUtils.toHex(c));try{if(c.length+b.bufferOffset>=b.buffer.byteLength){3<LOG&&console.log("NDN.ws.onmessage: buffer overflow. Accumulate received length: "+
-b.bufferOffset+". Current packet length: "+c.length+".");delete b.structureDecoder;delete b.buffer;b.structureDecoder=new BinaryXMLStructureDecoder;b.buffer=new Uint8Array(b.maxBufferSize);b.bufferOffset=0;return}b.buffer.set(c,b.bufferOffset);b.bufferOffset+=c.length;if(!b.structureDecoder.findElementEnd(b.buffer.subarray(0,b.bufferOffset))){3<LOG&&console.log("Incomplete packet received. Length "+c.length+". Wait for more input.");return}3<LOG&&console.log("Complete packet received. Length "+c.length+
-". Start decoding.")}catch(d){console.log("NDN.ws.onmessage exception: "+d);return}c=new BinaryXMLDecoder(b.buffer);if(c.peekStartElement(CCNProtocolDTags.Interest)){3<LOG&&console.log("Interest packet received.");var e=new Interest;e.from_ccnb(c);3<LOG&&console.log(e);var f=escape(e.name.getName());3<LOG&&console.log(f);f=getEntryForRegisteredPrefix(f);null!=f&&f.closure.upcall(Closure.UPCALL_INTEREST,new UpcallInfo(a,e,0,null))}else if(c.peekStartElement(CCNProtocolDTags.ContentObject))if(3<LOG&&
-console.log("ContentObject packet received."),e=new ContentObject,e.from_ccnb(c),3<LOG&&console.log(e),f=e.name.getName(),3<LOG&&console.log(f),null==b.ccndid&&null!=f.match(ccndIdFetcher))!e.signedInfo||!e.signedInfo.publisher||!e.signedInfo.publisher.publisherPublicKeyDigest?(console.log("Cannot contact router, close NDN now."),a.readyStatus=NDN.CLOSED,a.onclose()):(b.ccndid=e.signedInfo.publisher.publisherPublicKeyDigest,3<LOG&&console.log(b.ccndid),a.readyStatus=NDN.OPENED,a.onopen());else{if(f=
-getEntryForExpressedInterest(f),null!=f){clearTimeout(f.closure.timerID);var g=PITTable.indexOf(f);PITTable.splice(g,1);f.closure.upcall(Closure.UPCALL_CONTENT,new UpcallInfo(a,null,0,e))}}else console.log("Incoming packet is not Interest or ContentObject. Discard now.");delete c;delete b.structureDecoder;delete b.buffer;b.structureDecoder=new BinaryXMLStructureDecoder;b.buffer=new Uint8Array(b.maxBufferSize);b.bufferOffset=0}};this.ws.onopen=function(a){3<LOG&&console.log(a);3<LOG&&console.log("ws.onopen: WebSocket connection opened.");
-3<LOG&&console.log("ws.onopen: ReadyState: "+this.readyState);a=new Interest(new Name(ccndIdFetcher));a.interestLifetime=4;var a=encodeToBinaryInterest(a),d=new Uint8Array(a.length);d.set(a);b.ws.send(d.buffer)};this.ws.onerror=function(a){console.log("ws.onerror: ReadyState: "+this.readyState);console.log(a);console.log("ws.onerror: WebSocket error: "+a.data)};this.ws.onclose=function(){console.log("ws.onclose: WebSocket connection closed.");b.ws=null;a.readyStatus=NDN.CLOSED;a.onclose()}};
-var PITTable=[],PITEntry=function(a,b){this.interest=a;this.closure=b};function getEntryForExpressedInterest(a){for(var b=0;b<PITTable.length;b++)if(null!=a.match(PITTable[b].interest))return PITTable[b];return null}
-WebSocketTransport.prototype.expressInterest=function(a,b,c){if(null!=this.ws){var d=encodeToBinaryInterest(b),e=new Uint8Array(d.length);e.set(d);var f=new PITEntry(b.name.getName(),c);PITTable.push(f);this.ws.send(e.buffer);3<LOG&&console.log("ws.send() returned.");c.timerID=setTimeout(function(){3<LOG&&console.log("Interest time out.");var d=PITTable.indexOf(f);PITTable.splice(d,1);c.upcall(Closure.UPCALL_INTEREST_TIMED_OUT,new UpcallInfo(a,b,0,null))},1E3*b.interestLifetime)}else console.log("WebSocket connection is not established.")};
-var CSTable=[],CSEntry=function(a,b){this.name=a;this.closure=b};function getEntryForRegisteredPrefix(a){for(var b=0;b<CSTable.length;b++)if(null!=CSTable[b].name.match(a))return CSTable[b];return null}
-WebSocketTransport.prototype.registerPrefix=function(a,b,c){if(null!=this.ws){if(null==this.ccndid)return console.log("ccnd node ID unkonwn. Cannot register prefix."),-1;var a=new ForwardingEntry("selfreg",b,null,null,3,2147483647),a=encodeForwardingEntry(a),d=new SignedInfo;d.setFields();a=new ContentObject(new Name,d,a,new Signature);a.sign();a=encodeToBinaryContentObject(a);a=new Name(["ccnx",this.ccndid,"selfreg",a]);a=new Interest(a);a.scope=1;d=encodeToBinaryInterest(a);a=new Uint8Array(d.length);
-a.set(d);3<LOG&&console.log("Send Interest registration packet.");b=new CSEntry(b.getName(),c);CSTable.push(b);this.ws.send(a.buffer);return 0}console.log("WebSocket connection is not established.");return-1};
+var WebSocketTransport=function(){if(!WebSocket)throw Error("WebSocket support is not available on this platform.");this.elementReader=this.connectedPort=this.connectedHost=this.ws=null;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)};
+WebSocketTransport.prototype.connect=function(a,b){null!=this.ws&&delete this.ws;this.ws=new WebSocket("ws://"+a.host+":"+a.port);0<LOG&&console.log("ws connection created.");this.connectedHost=a.host;this.connectedPort=a.port;this.ws.binaryType="arraybuffer";this.elementReader=new BinaryXmlElementReader(a);var c=this;this.ws.onmessage=function(a){a=a.data;if(null==a||void 0==a||""==a)console.log("INVALID ANSWER");else if(a instanceof ArrayBuffer){a=new Uint8Array(a);3<LOG&&console.log("BINARY RESPONSE IS "+
+DataUtils.toHex(a));try{c.elementReader.onReceivedData(a)}catch(b){console.log("NDN.ws.onmessage exception: "+b)}}};this.ws.onopen=function(a){3<LOG&&console.log(a);3<LOG&&console.log("ws.onopen: WebSocket connection opened.");3<LOG&&console.log("ws.onopen: ReadyState: "+this.readyState);b()};this.ws.onerror=function(a){console.log("ws.onerror: ReadyState: "+this.readyState);console.log(a);console.log("ws.onerror: WebSocket error: "+a.data)};this.ws.onclose=function(){console.log("ws.onclose: WebSocket connection closed.");
+c.ws=null;a.readyStatus=NDN.CLOSED;a.onclose()}};WebSocketTransport.prototype.send=function(a){if(null!=this.ws){var b=new Uint8Array(a.length);b.set(a);this.ws.send(b.buffer);3<LOG&&console.log("ws.send() returned.")}else console.log("WebSocket connection is not established.")};
 var CCNProtocolDTags={Any:13,Name:14,Component:15,Certificate:16,Collection:17,CompleteName:18,Content:19,SignedInfo:20,ContentDigest:21,ContentHash:22,Count:24,Header:25,Interest:26,Key:27,KeyLocator:28,KeyName:29,Length:30,Link:31,LinkAuthenticator:32,NameComponentCount:33,RootDigest:36,Signature:37,Start:38,Timestamp:39,Type:40,Nonce:41,Scope:42,Exclude:43,Bloom:44,BloomSeed:45,AnswerOriginKind:47,InterestLifetime:48,Witness:53,SignatureBits:54,DigestAlgorithm:55,BlockSize:56,FreshnessSeconds:58,
 FinalBlockID:59,PublisherPublicKeyDigest:60,PublisherCertificateDigest:61,PublisherIssuerKeyDigest:62,PublisherIssuerCertificateDigest:63,ContentObject:64,WrappedKey:65,WrappingKeyIdentifier:66,WrapAlgorithm:67,KeyAlgorithm:68,Label:69,EncryptedKey:70,EncryptedNonceKey:71,WrappingKeyName:72,Action:73,FaceID:74,IPProto:75,Host:76,Port:77,MulticastInterface:78,ForwardingFlags:79,FaceInstance:80,ForwardingEntry:81,MulticastTTL:82,MinSuffixComponents:83,MaxSuffixComponents:84,ChildSelector:85,RepositoryInfo:86,
 Version:87,RepositoryVersion:88,GlobalPrefix:89,LocalName:90,Policy:91,Namespace:92,GlobalPrefixName:93,PolicyVersion:94,KeyValueSet:95,KeyValuePair:96,IntegerValue:97,DecimalValue:98,StringValue:99,BinaryValue:100,NameValue:101,Entry:102,ACL:103,ParameterizedName:104,Prefix:105,Suffix:106,Root:107,ProfileName:108,Parameters:109,InfoString:110,StatusResponse:112,StatusCode:113,StatusText:114,SyncNode:115,SyncNodeKind:116,SyncNodeElement:117,SyncVersion:118,SyncNodeElements:119,SyncContentHash:120,
@@ -21,63 +11,72 @@
 null,null,"RootDigest","Signature","Start","Timestamp","Type","Nonce","Scope","Exclude","Bloom","BloomSeed",null,"AnswerOriginKind","InterestLifetime",null,null,null,null,"Witness","SignatureBits","DigestAlgorithm","BlockSize",null,"FreshnessSeconds","FinalBlockID","PublisherPublicKeyDigest","PublisherCertificateDigest","PublisherIssuerKeyDigest","PublisherIssuerCertificateDigest","ContentObject","WrappedKey","WrappingKeyIdentifier","WrapAlgorithm","KeyAlgorithm","Label","EncryptedKey","EncryptedNonceKey",
 "WrappingKeyName","Action","FaceID","IPProto","Host","Port","MulticastInterface","ForwardingFlags","FaceInstance","ForwardingEntry","MulticastTTL","MinSuffixComponents","MaxSuffixComponents","ChildSelector","RepositoryInfo","Version","RepositoryVersion","GlobalPrefix","LocalName","Policy","Namespace","GlobalPrefixName","PolicyVersion","KeyValueSet","KeyValuePair","IntegerValue","DecimalValue","StringValue","BinaryValue","NameValue","Entry","ACL","ParameterizedName","Prefix","Suffix","Root","ProfileName",
 "Parameters","InfoString",null,"StatusResponse","StatusCode","StatusText","SyncNode","SyncNodeKind","SyncNodeElement","SyncVersion","SyncNodeElements","SyncContentHash","SyncLeafCount","SyncTreeDepth","SyncByteCount","ConfigSlice","ConfigSliceList","ConfigSliceOp"],CCNTime=function(a){this.NANOS_MAX=999877929;"number"==typeof a?this.msec=a:1<LOG&&console.log("UNRECOGNIZED TYPE FOR TIME")};CCNTime.prototype.getJavascriptDate=function(){var a=new Date;a.setTime(this.msec);return a};
-var Name=function Name(b){if("string"==typeof b)3<LOG&&console.log("Content Name String "+b),this.components=Name.createNameArray(b);else if("object"===typeof b){4<LOG&&console.log("Content Name Array "+b);this.components=[];for(var c=0;c<b.length;++c)this.add(b[c])}else null==b?this.components=[]:1<LOG&&console.log("NO CONTENT NAME GIVEN")};Name.prototype.getName=function(){return this.to_uri()};
-Name.createNameArray=function(a){a=a.trim();if(0>=a.length)return[];var b=a.indexOf(":");if(0<=b){var c=a.indexOf("/");if(0>c||b<c)a=a.substr(b+1,a.length-b-1).trim()}if("/"==a[0])if(2<=a.length&&"/"==a[1]){b=a.indexOf("/",2);if(0>b)return[];a=a.substr(b+1,a.length-b-1).trim()}else a=a.substr(1,a.length-1).trim();a=a.split("/");for(b=0;b<a.length;++b){c=unescape(a[b].trim());if(null==c.match(/[^.]/))if(2>=c.length){a.splice(b,1);--b;continue}else a[b]=c.substr(3,c.length-3);else a[b]=c;a[b]=DataUtils.toNumbersFromString(a[b])}return a};
+var ExponentialReExpressClosure=function(a,b){Closure.call(this);this.callerClosure=a;b=b||{};this.maxInterestLifetime=b.maxInterestLifetime||16E3};
+ExponentialReExpressClosure.prototype.upcall=function(a,b){try{if(a==Closure.UPCALL_INTEREST_TIMED_OUT){var c=b.interest.interestLifetime;if(null==c)return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT,b);c*=2;if(c>this.maxInterestLifetime)return this.callerClosure.upcall(Closure.UPCALL_INTEREST_TIMED_OUT,b);var d=b.interest.clone();d.interestLifetime=c;b.ndn.expressInterest(d.name,this,d);return Closure.RESULT_OK}return this.callerClosure.upcall(a,b)}catch(e){return console.log("ExponentialReExpressClosure.upcall exception: "+
+e),Closure.RESULT_ERR}};var Name=function Name(b){if("string"==typeof b)3<LOG&&console.log("Content Name String "+b),this.components=Name.createNameArray(b);else if("object"===typeof b){4<LOG&&console.log("Content Name Array "+b);this.components=[];for(var c=0;c<b.length;++c)this.add(b[c])}else null==b?this.components=[]:1<LOG&&console.log("NO CONTENT NAME GIVEN")};Name.prototype.getName=function(){return this.to_uri()};
+Name.createNameArray=function(a){a=a.trim();if(0>=a.length)return[];var b=a.indexOf(":");if(0<=b){var c=a.indexOf("/");if(0>c||b<c)a=a.substr(b+1,a.length-b-1).trim()}if("/"==a[0])if(2<=a.length&&"/"==a[1]){b=a.indexOf("/",2);if(0>b)return[];a=a.substr(b+1,a.length-b-1).trim()}else a=a.substr(1,a.length-1).trim();a=a.split("/");for(b=0;b<a.length;++b)c=Name.fromEscapedString(a[b]),null==c?(a.splice(b,1),--b):a[b]=c;return a};
 Name.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());for(this.components=[];a.peekStartElement(CCNProtocolDTags.Component);)this.add(a.readBinaryElement(CCNProtocolDTags.Component));a.readEndElement()};Name.prototype.to_ccnb=function(a){if(null==this.components)throw Error("CANNOT ENCODE EMPTY CONTENT NAME");a.writeStartElement(this.getElementLabel());for(var b=this.components.length,c=0;c<b;c++)a.writeElement(CCNProtocolDTags.Component,this.components[c]);a.writeEndElement()};
 Name.prototype.getElementLabel=function(){return CCNProtocolDTags.Name};
-Name.prototype.add=function(a){var b;if("string"==typeof a)b=DataUtils.stringToUtf8Array(a);else if("object"==typeof a&&a instanceof Uint8Array)b=new Uint8Array(a);else if("object"==typeof a&&a instanceof ArrayBuffer)b=new Uint8Array(new ArrayBuffer(a.byteLength)),b.set(new Uint8Array(a));else if("object"==typeof a)b=new Uint8Array(a);else throw Error("Cannot add Name element at index "+this.components.length+": Invalid type");return this.components.push(b)};
-Name.prototype.to_uri=function(){for(var a="",b=0;b<this.components.length;++b)a+="/"+Name.toEscapedString(this.components[b]);return a};Name.prototype.getPrefix=function(a){return new Name(this.components.slice(0,a))};Name.prototype.getComponent=function(a){var b=new ArrayBuffer(this.components[a].length);(new Uint8Array(b)).set(this.components[a]);return b};
-Name.prototype.indexOfFileName=function(){for(var a=this.components.length-1;0<=a;--a){var b=this.components[a];if(!(0>=b.length)&&!(0==b[0]||192==b[0]||193==b[0]||245<=b[0]&&255>=b[0]))return a}return-1};
-Name.prototype.getContentDigestValue=function(){for(var a=Name.ContentDigestPrefix.length+32+Name.ContentDigestSuffix.length,b=this.components.length-1;0<=b;--b)if(this.components[b].length==a&&DataUtils.arraysEqual(this.components[b].subarray(0,Name.ContentDigestPrefix.length),Name.ContentDigestPrefix)&&DataUtils.arraysEqual(this.components[b].subarray(this.components[b].length-Name.ContentDigestSuffix.length,this.components[b].length),Name.ContentDigestSuffix))return this.components[b].subarray(Name.ContentDigestPrefix.length,
-Name.ContentDigestPrefix.length+32);return null};Name.ContentDigestPrefix=new Uint8Array([193,46,77,46,71,193,1,170,2,133]);Name.ContentDigestSuffix=new Uint8Array([0]);Name.toEscapedString=function(a){for(var b="",c=!1,d=0;d<a.length;++d)if(46!=a[d]){c=!0;break}if(c)for(d=0;d<a.length;++d)c=a[d],b=48<=c&&57>=c||65<=c&&90>=c||97<=c&&122>=c||43==c||45==c||46==c||95==c?b+String.fromCharCode(c):b+("%"+(16>c?"0":"")+c.toString(16).toUpperCase());else{b="...";for(d=0;d<a.length;++d)b+="."}return b};
-var ContentObject=function(a,b,c,d){this.name="string"===typeof a?new Name(a):a;this.signedInfo=b;this.content=c;this.signature=d;this.rawSignatureData=this.endContent=this.startSignedInfo=this.endSIG=this.startSIG=null};
+Name.prototype.add=function(a){var b;if("string"==typeof a)b=DataUtils.stringToUtf8Array(a),this.components.push(b);else if("object"==typeof a&&a instanceof Uint8Array)b=new Uint8Array(a),this.components.push(b);else if("object"==typeof a&&a instanceof ArrayBuffer)b=new Uint8Array(new ArrayBuffer(a.byteLength)),b.set(new Uint8Array(a)),this.components.push(b);else if("object"==typeof a&&a instanceof Name){components=a;this==a&&(components=new Name(a.components));for(a=0;a<components.components.length;++a)b=
+new Uint8Array(components.components[a]),this.components.push(b)}else if("object"==typeof a)b=new Uint8Array(a),this.components.push(b);else throw Error("Cannot add Name element at index "+this.components.length+": Invalid type");return this};Name.prototype.addSegment=function(a){for(var b=1,c=a;0<c;)b++,c>>=8;b=new Uint8Array(b);c=0;b[c]=0;for(c++;0<a;)b[c]=a&255,a>>=8,c++;this.components.push(b);return this};
+Name.prototype.to_uri=function(){if(0==this.components.length)return"/";for(var a="",b=0;b<this.components.length;++b)a+="/"+Name.toEscapedString(this.components[b]);return a};Name.prototype.getPrefix=function(a){return new Name(this.components.slice(0,a))};Name.prototype.getComponent=function(a){var b=new ArrayBuffer(this.components[a].length);(new Uint8Array(b)).set(this.components[a]);return b};
+Name.prototype.indexOfFileName=function(){for(var a=this.components.length-1;0<=a;--a){var b=this.components[a];if(!(0>=b.length)&&!(0==b[0]||192==b[0]||193==b[0]||245<=b[0]&&255>=b[0]))return a}return-1};Name.prototype.equalsName=function(a){if(this.components.length!=a.components.length)return!1;for(var b=this.components.length-1;0<=b;--b)if(!DataUtils.arraysEqual(this.components[b],a.components[b]))return!1;return!0};
+Name.prototype.getContentDigestValue=function(){for(var a=this.components.length-1;0<=a;--a){var b=Name.getComponentContentDigestValue(this.components[a]);if(null!=b)return b}return null};
+Name.getComponentContentDigestValue=function(a){return a.length==Name.ContentDigestPrefix.length+32+Name.ContentDigestSuffix.length&&DataUtils.arraysEqual(a.subarray(0,Name.ContentDigestPrefix.length),Name.ContentDigestPrefix)&&DataUtils.arraysEqual(a.subarray(a.length-Name.ContentDigestSuffix.length,a.length),Name.ContentDigestSuffix)?a.subarray(Name.ContentDigestPrefix.length,Name.ContentDigestPrefix.length+32):null};Name.ContentDigestPrefix=new Uint8Array([193,46,77,46,71,193,1,170,2,133]);
+Name.ContentDigestSuffix=new Uint8Array([0]);Name.toEscapedString=function(a){for(var b="",c=!1,d=0;d<a.length;++d)if(46!=a[d]){c=!0;break}if(c)for(d=0;d<a.length;++d)c=a[d],b=48<=c&&57>=c||65<=c&&90>=c||97<=c&&122>=c||43==c||45==c||46==c||95==c?b+String.fromCharCode(c):b+("%"+(16>c?"0":"")+c.toString(16).toUpperCase());else{b="...";for(d=0;d<a.length;++d)b+="."}return b};
+Name.fromEscapedString=function(a){a=unescape(a.trim());return null==a.match(/[^.]/)?2>=a.length?null:DataUtils.toNumbersFromString(a.substr(3,a.length-3)):DataUtils.toNumbersFromString(a)};Name.prototype.match=function(a){var b=this.components,a=a.components;if(b.length>a.length)return!1;for(var c=0;c<b.length;++c)if(!DataUtils.arraysEqual(b[c],a[c]))return!1;return!0};
+var ContentObject=function(a,b,c,d){this.name="string"==typeof a?new Name(a):a;this.signedInfo=b;this.content="string"==typeof c?DataUtils.toNumbersFromString(c):c;this.signature=d;this.rawSignatureData=this.endContent=this.endSIG=this.startSIG=null};
 ContentObject.prototype.sign=function(){var a=this.encodeObject(this.name),b=this.encodeObject(this.signedInfo),c=this.encodeContent(),d=new ArrayBuffer(a.length+b.length+c.length),d=new Uint8Array(d);d.set(a,0);d.set(b,a.length);d.set(c,a.length+b.length);4<LOG&&console.log("Signature Data is (binary) "+d);4<LOG&&console.log("Signature Data is (RawString)");4<LOG&&console.log(DataUtils.toString(d));a=new RSAKey;a.readPrivateKeyFromPEMString(globalKeyManager.privateKey);a=a.signByteArrayWithSHA256(d);
 4<LOG&&console.log("SIGNATURE SAVED IS");4<LOG&&console.log(a);4<LOG&&console.log(DataUtils.toNumbers(a.trim()));this.signature.signature=DataUtils.toNumbers(a.trim())};ContentObject.prototype.encodeObject=function(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()};ContentObject.prototype.encodeContent=function(){var a=new BinaryXMLEncoder;a.writeElement(CCNProtocolDTags.Content,this.content);return a.getReducedOstream()};
 ContentObject.prototype.saveRawData=function(a){this.rawSignatureData=a.subarray(this.startSIG,this.endSIG)};
 ContentObject.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.Signature)&&(this.signature=new Signature,this.signature.from_ccnb(a));this.startSIG=a.offset;this.name=new Name;this.name.from_ccnb(a);a.peekStartElement(CCNProtocolDTags.SignedInfo)&&(this.signedInfo=new SignedInfo,this.signedInfo.from_ccnb(a));this.content=a.readBinaryElement(CCNProtocolDTags.Content);this.endSIG=a.offset;a.readEndElement();this.saveRawData(a.istream)};
 ContentObject.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());null!=this.signature&&this.signature.to_ccnb(a);this.startSIG=a.offset;null!=this.name&&this.name.to_ccnb(a);null!=this.signedInfo&&this.signedInfo.to_ccnb(a);a.writeElement(CCNProtocolDTags.Content,this.content);this.endSIG=a.offset;a.writeEndElement();this.saveRawData(a.ostream)};ContentObject.prototype.getElementLabel=function(){return CCNProtocolDTags.ContentObject};
 var Signature=function(a,b,c){this.Witness=a;this.signature=b;this.digestAlgorithm=c};
-Signature.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());4<LOG&&console.log("STARTED DECODING SIGNATURE ");a.peekStartElement(CCNProtocolDTags.DigestAlgorithm)&&(4<LOG&&console.log("DIGIEST ALGORITHM FOUND"),this.digestAlgorithm=a.readUTF8Element(CCNProtocolDTags.DigestAlgorithm));a.peekStartElement(CCNProtocolDTags.Witness)&&(4<LOG&&console.log("WITNESS FOUND FOUND"),this.Witness=a.readBinaryElement(CCNProtocolDTags.Witness));this.signature=a.readBinaryElement(CCNProtocolDTags.SignatureBits);
-4<LOG&&console.log("READ SIGNATURE ");a.readEndElement()};
+Signature.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());4<LOG&&console.log("STARTED DECODING SIGNATURE");a.peekStartElement(CCNProtocolDTags.DigestAlgorithm)&&(4<LOG&&console.log("DIGIEST ALGORITHM FOUND"),this.digestAlgorithm=a.readUTF8Element(CCNProtocolDTags.DigestAlgorithm));a.peekStartElement(CCNProtocolDTags.Witness)&&(4<LOG&&console.log("WITNESS FOUND"),this.Witness=a.readBinaryElement(CCNProtocolDTags.Witness));4<LOG&&console.log("SIGNATURE FOUND");this.signature=
+a.readBinaryElement(CCNProtocolDTags.SignatureBits);a.readEndElement()};
 Signature.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode: field values missing.");a.writeStartElement(this.getElementLabel());null!=this.digestAlgorithm&&!this.digestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM)&&a.writeElement(CCNProtocolDTags.DigestAlgorithm,OIDLookup.getDigestOID(this.DigestAlgorithm));null!=this.Witness&&a.writeElement(CCNProtocolDTags.Witness,this.Witness);a.writeElement(CCNProtocolDTags.SignatureBits,this.signature);a.writeEndElement()};
 Signature.prototype.getElementLabel=function(){return CCNProtocolDTags.Signature};Signature.prototype.validate=function(){return null!=this.signature};
-var ContentType={DATA:0,ENCR:1,GONE:2,KEY:3,LINK:4,NACK:5},ContentTypeValue={"0":787648,1:1101969,2:1631044,3:2639423,4:2917194,5:3408010},ContentTypeValueReverse={787648:0,1101969:1,1631044:2,2639423:3,2917194:4,3408010:5},SignedInfo=function(a,b,c,d,e,f){this.publisher=a;this.timestamp=b;this.type=c;this.locator=d;this.freshnessSeconds=e;this.finalBlockID=f};
+var ContentType={DATA:0,ENCR:1,GONE:2,KEY:3,LINK:4,NACK:5},ContentTypeValue={"0":787648,1:1101969,2:1631044,3:2639423,4:2917194,5:3408010},ContentTypeValueReverse={787648:0,1101969:1,1631044:2,2639423:3,2917194:4,3408010:5},SignedInfo=function(a,b,c,d,e,f){this.publisher=a;this.timestamp=b;this.type=c;this.locator=d;this.freshnessSeconds=e;this.finalBlockID=f;this.setFields()};
 SignedInfo.prototype.setFields=function(){var a=globalKeyManager.publicKey;4<LOG&&console.log("PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ");4<LOG&&console.log(a);var a=DataUtils.toNumbers(globalKeyManager.publicKey),b=hex_sha256_from_bytes(a);this.publisher=new PublisherPublicKeyDigest(DataUtils.toNumbers(b));b=(new Date).getTime();this.timestamp=new CCNTime(b);4<LOG&&console.log("TIME msec is");4<LOG&&console.log(this.timestamp.msec);this.type=0;4<LOG&&console.log("PUBLIC KEY TO WRITE TO CONTENT OBJECT IS ");
 4<LOG&&console.log(a);this.locator=new KeyLocator(a,KeyLocatorType.KEY)};
-SignedInfo.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(3<LOG&&console.log("DECODING PUBLISHER KEY"),this.publisher=new PublisherPublicKeyDigest,this.publisher.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.Timestamp)&&(this.timestamp=a.readDateTime(CCNProtocolDTags.Timestamp),4<LOG&&console.log("TIMESTAMP FOUND IS  "+this.timestamp));if(a.peekStartElement(CCNProtocolDTags.Type)){if(binType=a.readBinaryElement(CCNProtocolDTags.Type),
-4<LOG&&console.log("Binary Type of of Signed Info is "+binType),this.type=binType,null==this.type)throw Error("Cannot parse signedInfo type: bytes.");}else this.type=ContentType.DATA;a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.freshnessSeconds=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds),4<LOG&&console.log("FRESHNESS IN SECONDS IS "+this.freshnessSeconds));a.peekStartElement(CCNProtocolDTags.FinalBlockID)&&(this.finalBlockID=a.readBinaryElement(CCNProtocolDTags.FinalBlockID));
-a.peekStartElement(CCNProtocolDTags.KeyLocator)&&(this.locator=new KeyLocator,this.locator.from_ccnb(a));a.readEndElement()};
+SignedInfo.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(4<LOG&&console.log("DECODING PUBLISHER KEY"),this.publisher=new PublisherPublicKeyDigest,this.publisher.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.Timestamp)&&(4<LOG&&console.log("DECODING TIMESTAMP"),this.timestamp=a.readDateTime(CCNProtocolDTags.Timestamp));if(a.peekStartElement(CCNProtocolDTags.Type)){var b=a.readBinaryElement(CCNProtocolDTags.Type);
+4<LOG&&console.log("Binary Type of of Signed Info is "+b);this.type=b;if(null==this.type)throw Error("Cannot parse signedInfo type: bytes.");}else this.type=ContentType.DATA;a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.freshnessSeconds=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds),4<LOG&&console.log("FRESHNESS IN SECONDS IS "+this.freshnessSeconds));a.peekStartElement(CCNProtocolDTags.FinalBlockID)&&(4<LOG&&console.log("DECODING FINAL BLOCKID"),this.finalBlockID=a.readBinaryElement(CCNProtocolDTags.FinalBlockID));
+a.peekStartElement(CCNProtocolDTags.KeyLocator)&&(4<LOG&&console.log("DECODING KEY LOCATOR"),this.locator=new KeyLocator,this.locator.from_ccnb(a));a.readEndElement()};
 SignedInfo.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode : field values missing.");a.writeStartElement(this.getElementLabel());null!=this.publisher&&(3<LOG&&console.log("ENCODING PUBLISHER KEY"+this.publisher.publisherPublicKeyDigest),this.publisher.to_ccnb(a));null!=this.timestamp&&a.writeDateTime(CCNProtocolDTags.Timestamp,this.timestamp);null!=this.type&&0!=this.type&&a.writeElement(CCNProtocolDTags.type,this.type);null!=this.freshnessSeconds&&a.writeElement(CCNProtocolDTags.FreshnessSeconds,
 this.freshnessSeconds);null!=this.finalBlockID&&a.writeElement(CCNProtocolDTags.FinalBlockID,this.finalBlockID);null!=this.locator&&this.locator.to_ccnb(a);a.writeEndElement()};SignedInfo.prototype.valueToType=function(){return null};SignedInfo.prototype.getElementLabel=function(){return CCNProtocolDTags.SignedInfo};SignedInfo.prototype.validate=function(){return null==this.publisher||null==this.timestamp||null==this.locator?!1:!0};
 var DateFormat=function(){var a=/d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,b=/\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,c=/[^-+\dA-Z]/g,d=function(a,b){a=String(a);for(b=b||2;a.length<b;)a="0"+a;return a};return function(e,f,g){var h=dateFormat;1==arguments.length&&("[object String]"==Object.prototype.toString.call(e)&&!/\d/.test(e))&&(f=e,e=void 0);e=e?new Date(e):new Date;if(isNaN(e))throw SyntaxError("invalid date");
-f=String(h.masks[f]||f||h.masks["default"]);"UTC:"==f.slice(0,4)&&(f=f.slice(4),g=!0);var j=g?"getUTC":"get",l=e[j+"Date"](),n=e[j+"Day"](),m=e[j+"Month"](),p=e[j+"FullYear"](),k=e[j+"Hours"](),q=e[j+"Minutes"](),s=e[j+"Seconds"](),j=e[j+"Milliseconds"](),r=g?0:e.getTimezoneOffset(),t={d:l,dd:d(l),ddd:h.i18n.dayNames[n],dddd:h.i18n.dayNames[n+7],m:m+1,mm:d(m+1),mmm:h.i18n.monthNames[m],mmmm:h.i18n.monthNames[m+12],yy:String(p).slice(2),yyyy:p,h:k%12||12,hh:d(k%12||12),H:k,HH:d(k),M:q,MM:d(q),s:s,
-ss:d(s),l:d(j,3),L:d(99<j?Math.round(j/10):j),t:12>k?"a":"p",tt:12>k?"am":"pm",T:12>k?"A":"P",TT:12>k?"AM":"PM",Z:g?"UTC":(String(e).match(b)||[""]).pop().replace(c,""),o:(0<r?"-":"+")+d(100*Math.floor(Math.abs(r)/60)+Math.abs(r)%60,4),S:["th","st","nd","rd"][3<l%10?0:(10!=l%100-l%10)*l%10]};return f.replace(a,function(a){return a in t?t[a]:a.slice(1,a.length-1)})}}();
+f=String(h.masks[f]||f||h.masks["default"]);"UTC:"==f.slice(0,4)&&(f=f.slice(4),g=!0);var i=g?"getUTC":"get",k=e[i+"Date"](),m=e[i+"Day"](),l=e[i+"Month"](),n=e[i+"FullYear"](),j=e[i+"Hours"](),p=e[i+"Minutes"](),r=e[i+"Seconds"](),i=e[i+"Milliseconds"](),q=g?0:e.getTimezoneOffset(),s={d:k,dd:d(k),ddd:h.i18n.dayNames[m],dddd:h.i18n.dayNames[m+7],m:l+1,mm:d(l+1),mmm:h.i18n.monthNames[l],mmmm:h.i18n.monthNames[l+12],yy:String(n).slice(2),yyyy:n,h:j%12||12,hh:d(j%12||12),H:j,HH:d(j),M:p,MM:d(p),s:r,
+ss:d(r),l:d(i,3),L:d(99<i?Math.round(i/10):i),t:12>j?"a":"p",tt:12>j?"am":"pm",T:12>j?"A":"P",TT:12>j?"AM":"PM",Z:g?"UTC":(String(e).match(b)||[""]).pop().replace(c,""),o:(0<q?"-":"+")+d(100*Math.floor(Math.abs(q)/60)+Math.abs(q)%60,4),S:["th","st","nd","rd"][3<k%10?0:(10!=k%100-k%10)*k%10]};return f.replace(a,function(a){return a in s?s[a]:a.slice(1,a.length-1)})}}();
 DateFormat.masks={"default":"ddd mmm dd yyyy HH:MM:ss",shortDate:"m/d/yy",mediumDate:"mmm d, yyyy",longDate:"mmmm d, yyyy",fullDate:"dddd, mmmm d, yyyy",shortTime:"h:MM TT",mediumTime:"h:MM:ss TT",longTime:"h:MM:ss TT Z",isoDate:"yyyy-mm-dd",isoTime:"HH:MM:ss",isoDateTime:"yyyy-mm-dd'T'HH:MM:ss",isoUtcDateTime:"UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"};DateFormat.i18n={dayNames:"Sun Mon Tue Wed Thu Fri Sat Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),monthNames:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec January February March April May June July August September October November December".split(" ")};
-Date.prototype.format=function(a,b){return dateFormat(this,a,b)};var Interest=function(a,b,c,d,e,f,g,h,j,l,n){this.name=a;this.faceInstance=b;this.maxSuffixComponents=d;this.minSuffixComponents=c;this.publisherPublicKeyDigest=e;this.exclude=f;this.childSelector=g;this.answerOriginKind=h;this.scope=j;this.interestLifetime=l;this.nonce=n};Interest.RECURSIVE_POSTFIX="*";Interest.CHILD_SELECTOR_LEFT=0;Interest.CHILD_SELECTOR_RIGHT=1;Interest.ANSWER_CONTENT_STORE=1;Interest.ANSWER_GENERATED=2;
+Date.prototype.format=function(a,b){return dateFormat(this,a,b)};var Interest=function(a,b,c,d,e,f,g,h,i,k,m){this.name=a;this.faceInstance=b;this.maxSuffixComponents=d;this.minSuffixComponents=c;this.publisherPublicKeyDigest=e;this.exclude=f;this.childSelector=g;this.answerOriginKind=h;this.scope=i;this.interestLifetime=k;this.nonce=m};Interest.RECURSIVE_POSTFIX="*";Interest.CHILD_SELECTOR_LEFT=0;Interest.CHILD_SELECTOR_RIGHT=1;Interest.ANSWER_CONTENT_STORE=1;Interest.ANSWER_GENERATED=2;
 Interest.ANSWER_STALE=4;Interest.MARK_STALE=16;Interest.DEFAULT_ANSWER_ORIGIN_KIND=Interest.ANSWER_CONTENT_STORE|Interest.ANSWER_GENERATED;
 Interest.prototype.from_ccnb=function(a){a.readStartElement(CCNProtocolDTags.Interest);this.name=new Name;this.name.from_ccnb(a);a.peekStartElement(CCNProtocolDTags.MinSuffixComponents)&&(this.minSuffixComponents=a.readIntegerElement(CCNProtocolDTags.MinSuffixComponents));a.peekStartElement(CCNProtocolDTags.MaxSuffixComponents)&&(this.maxSuffixComponents=a.readIntegerElement(CCNProtocolDTags.MaxSuffixComponents));a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(this.publisherPublicKeyDigest=
 new PublisherPublicKeyDigest,this.publisherPublicKeyDigest.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.Exclude)&&(this.exclude=new Exclude,this.exclude.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.ChildSelector)&&(this.childSelector=a.readIntegerElement(CCNProtocolDTags.ChildSelector));a.peekStartElement(CCNProtocolDTags.AnswerOriginKind)&&(this.answerOriginKind=a.readIntegerElement(CCNProtocolDTags.AnswerOriginKind));a.peekStartElement(CCNProtocolDTags.Scope)&&(this.scope=a.readIntegerElement(CCNProtocolDTags.Scope));
-a.peekStartElement(CCNProtocolDTags.InterestLifetime)&&(this.interestLifetime=DataUtils.bigEndianToUnsignedInt(a.readBinaryElement(CCNProtocolDTags.InterestLifetime))/4096);a.peekStartElement(CCNProtocolDTags.Nonce)&&(this.nonce=a.readBinaryElement(CCNProtocolDTags.Nonce));a.readEndElement()};
+a.peekStartElement(CCNProtocolDTags.InterestLifetime)&&(this.interestLifetime=1E3*DataUtils.bigEndianToUnsignedInt(a.readBinaryElement(CCNProtocolDTags.InterestLifetime))/4096);a.peekStartElement(CCNProtocolDTags.Nonce)&&(this.nonce=a.readBinaryElement(CCNProtocolDTags.Nonce));a.readEndElement()};
 Interest.prototype.to_ccnb=function(a){a.writeStartElement(CCNProtocolDTags.Interest);this.name.to_ccnb(a);null!=this.minSuffixComponents&&a.writeElement(CCNProtocolDTags.MinSuffixComponents,this.minSuffixComponents);null!=this.maxSuffixComponents&&a.writeElement(CCNProtocolDTags.MaxSuffixComponents,this.maxSuffixComponents);null!=this.publisherPublicKeyDigest&&this.publisherPublicKeyDigest.to_ccnb(a);null!=this.exclude&&this.exclude.to_ccnb(a);null!=this.childSelector&&a.writeElement(CCNProtocolDTags.ChildSelector,
-this.childSelector);this.DEFAULT_ANSWER_ORIGIN_KIND!=this.answerOriginKind&&null!=this.answerOriginKind&&a.writeElement(CCNProtocolDTags.AnswerOriginKind,this.answerOriginKind);null!=this.scope&&a.writeElement(CCNProtocolDTags.Scope,this.scope);null!=this.interestLifetime&&a.writeElement(CCNProtocolDTags.InterestLifetime,DataUtils.nonNegativeIntToBigEndian(4096*this.interestLifetime));null!=this.nonce&&a.writeElement(CCNProtocolDTags.Nonce,this.nonce);a.writeEndElement()};
-Interest.prototype.matches_name=function(a){var b=this.name.components,a=a.components;if(b.length>a.length)return!1;for(var c=0;c<b.length;++c)if(!DataUtils.arraysEqual(b[c],a[c]))return!1;return!0};var Exclude=function(a){this.OPTIMUM_FILTER_SIZE=100;this.values=a};Exclude.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.readEndElement()};
-Exclude.prototype.to_ccnb=function(a){if(!validate())throw new ContentEncodingException("Cannot encode "+this.getClass().getName()+": field values missing.");empty()||(a.writeStartElement(getElementLabel()),a.writeEndElement())};Exclude.prototype.getElementLabel=function(){return CCNProtocolDTags.Exclude};var ExcludeAny=function(){};ExcludeAny.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.readEndElement()};
-ExcludeAny.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());a.writeEndElement()};ExcludeAny.prototype.getElementLabel=function(){return CCNProtocolDTags.Any};var ExcludeComponent=function(a){this.body=a};ExcludeComponent.prototype.from_ccnb=function(a){this.body=a.readBinaryElement(this.getElementLabel())};ExcludeComponent.prototype.to_ccnb=function(a){a.writeElement(this.getElementLabel(),this.body)};ExcludeComponent.prototype.getElementLabel=function(){return CCNProtocolDTags.Component};
-var Key=function(){},KeyLocatorType={NAME:1,KEY:2,CERTIFICATE:3},KeyLocator=function(a,b){this.type=b;b==KeyLocatorType.NAME?this.keyName=a:b==KeyLocatorType.KEY?(4<LOG&&console.log("SET KEY"),this.publicKey=a):b==KeyLocatorType.CERTIFICATE&&(this.certificate=a)};
-KeyLocator.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());if(a.peekStartElement(CCNProtocolDTags.Key)){try{this.publicKey=encodedKey=a.readBinaryElement(CCNProtocolDTags.Key),this.type=2,4<LOG&&console.log("PUBLIC KEY FOUND: "+this.publicKey)}catch(b){throw Error("Cannot parse key: ",b);}if(null==this.publicKey)throw Error("Cannot parse key: ");}else if(a.peekStartElement(CCNProtocolDTags.Certificate)){try{this.certificate=encodedCert=a.readBinaryElement(CCNProtocolDTags.Certificate),
-this.type=3,4<LOG&&console.log("CERTIFICATE FOUND: "+this.certificate)}catch(c){throw Error("Cannot decode certificate: "+c);}if(null==this.certificate)throw Error("Cannot parse certificate! ");}else this.type=1,this.keyName=new KeyName,this.keyName.from_ccnb(a);a.readEndElement()};
+this.childSelector);this.DEFAULT_ANSWER_ORIGIN_KIND!=this.answerOriginKind&&null!=this.answerOriginKind&&a.writeElement(CCNProtocolDTags.AnswerOriginKind,this.answerOriginKind);null!=this.scope&&a.writeElement(CCNProtocolDTags.Scope,this.scope);null!=this.interestLifetime&&a.writeElement(CCNProtocolDTags.InterestLifetime,DataUtils.nonNegativeIntToBigEndian(4096*(this.interestLifetime/1E3)));null!=this.nonce&&a.writeElement(CCNProtocolDTags.Nonce,this.nonce);a.writeEndElement()};
+Interest.prototype.matches_name=function(a){return!this.name.match(a)||null!=this.minSuffixComponents&&!(a.components.length+1-this.name.components.length>=this.minSuffixComponents)||null!=this.maxSuffixComponents&&!(a.components.length+1-this.name.components.length<=this.maxSuffixComponents)||null!=this.exclude&&a.components.length>this.name.components.length&&this.exclude.matches(a.components[this.name.components.length])?!1:!0};
+Interest.prototype.clone=function(){return new Interest(this.name,this.faceInstance,this.minSuffixComponents,this.maxSuffixComponents,this.publisherPublicKeyDigest,this.exclude,this.childSelector,this.answerOriginKind,this.scope,this.interestLifetime,this.nonce)};var Exclude=function(a){this.values=a||[]};Exclude.ANY="*";
+Exclude.prototype.from_ccnb=function(a){for(a.readStartElement(CCNProtocolDTags.Exclude);;)if(a.peekStartElement(CCNProtocolDTags.Component))this.values.push(a.readBinaryElement(CCNProtocolDTags.Component));else if(a.peekStartElement(CCNProtocolDTags.Any))a.readStartElement(CCNProtocolDTags.Any),a.readEndElement(),this.values.push(Exclude.ANY);else if(a.peekStartElement(CCNProtocolDTags.Bloom))a.readBinaryElement(CCNProtocolDTags.Bloom),this.values.push(Exclude.ANY);else break;a.readEndElement()};
+Exclude.prototype.to_ccnb=function(a){if(!(null==this.values||0==this.values.length)){a.writeStartElement(CCNProtocolDTags.Exclude);for(var b=0;b<this.values.length;++b)this.values[b]==Exclude.ANY?(a.writeStartElement(CCNProtocolDTags.Any),a.writeEndElement()):a.writeElement(CCNProtocolDTags.Component,this.values[b]);a.writeEndElement()}};
+Exclude.prototype.to_uri=function(){if(null==this.values||0==this.values.length)return"";for(var a="",b=0;b<this.values.length;++b)0<b&&(a+=","),a=this.values[b]==Exclude.ANY?a+"*":a+Name.toEscapedString(this.values[b]);return a};
+Exclude.prototype.matches=function(a){for(var b=0;b<this.values.length;++b)if(this.values[b]==Exclude.ANY){var c=null;0<b&&(c=this.values[b-1]);var d,e=null;for(d=b+1;d<this.values.length;++d)if(this.values[d]!=Exclude.ANY){e=this.values[d];break}if(null!=e){if(null!=c){if(0<Exclude.compareComponents(a,c)&&0>Exclude.compareComponents(a,e))return!0}else if(0>Exclude.compareComponents(a,e))return!0;b=d-1}else if(null!=c){if(0<Exclude.compareComponents(a,c))return!0}else return!0}else if(DataUtils.arraysEqual(a,
+this.values[b]))return!0;return!1};Exclude.compareComponents=function(a,b){if(a.length<b.length)return-1;if(a.length>b.length)return 1;for(var c=0;c<a.length;++c){if(a[c]<b[c])return-1;if(a[c]>b[c])return 1}return 0};
+var Key=function(){},KeyLocatorType={KEY:1,CERTIFICATE:2,KEYNAME:3},KeyLocator=function(a,b){this.type=b;b==KeyLocatorType.KEYNAME?(3<LOG&&console.log("KeyLocator: SET KEYNAME"),this.keyName=a):b==KeyLocatorType.KEY?(3<LOG&&console.log("KeyLocator: SET KEY"),this.publicKey=a):b==KeyLocatorType.CERTIFICATE&&(3<LOG&&console.log("KeyLocator: SET CERTIFICATE"),this.certificate=a)};
+KeyLocator.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());if(a.peekStartElement(CCNProtocolDTags.Key)){try{this.publicKey=a.readBinaryElement(CCNProtocolDTags.Key),this.type=KeyLocatorType.KEY,4<LOG&&console.log("PUBLIC KEY FOUND: "+this.publicKey)}catch(b){throw Error("Cannot parse key: ",b);}if(null==this.publicKey)throw Error("Cannot parse key: ");}else if(a.peekStartElement(CCNProtocolDTags.Certificate)){try{this.certificate=a.readBinaryElement(CCNProtocolDTags.Certificate),
+this.type=KeyLocatorType.CERTIFICATE,4<LOG&&console.log("CERTIFICATE FOUND: "+this.certificate)}catch(c){throw Error("Cannot decode certificate: "+c);}if(null==this.certificate)throw Error("Cannot parse certificate! ");}else this.type=KeyLocatorType.KEYNAME,this.keyName=new KeyName,this.keyName.from_ccnb(a);a.readEndElement()};
 KeyLocator.prototype.to_ccnb=function(a){4<LOG&&console.log("type is is "+this.type);if(!this.validate())throw new ContentEncodingException("Cannot encode "+this.getClass().getName()+": field values missing.");a.writeStartElement(this.getElementLabel());if(this.type==KeyLocatorType.KEY)5<LOG&&console.log("About to encode a public key"+this.publicKey),a.writeElement(CCNProtocolDTags.Key,this.publicKey);else if(this.type==KeyLocatorType.CERTIFICATE)try{a.writeElement(CCNProtocolDTags.Certificate,this.certificate)}catch(b){throw Error("CertificateEncodingException attempting to write key locator: "+
-b);}else this.type==KeyLocatorType.NAME&&this.keyName.to_ccnb(a);a.writeEndElement()};KeyLocator.prototype.getElementLabel=function(){return CCNProtocolDTags.KeyLocator};KeyLocator.prototype.validate=function(){return null!=this.keyName||null!=this.publicKey||null!=this.certificate};var KeyName=function(){this.contentName=this.contentName;this.publisherID=this.publisherID};
+b);}else this.type==KeyLocatorType.KEYNAME&&this.keyName.to_ccnb(a);a.writeEndElement()};KeyLocator.prototype.getElementLabel=function(){return CCNProtocolDTags.KeyLocator};KeyLocator.prototype.validate=function(){return null!=this.keyName||null!=this.publicKey||null!=this.certificate};var KeyName=function(){this.contentName=this.contentName;this.publisherID=this.publisherID};
 KeyName.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());this.contentName=new Name;this.contentName.from_ccnb(a);4<LOG&&console.log("KEY NAME FOUND: ");PublisherID.peek(a)&&(this.publisherID=new PublisherID,this.publisherID.from_ccnb(a));a.readEndElement()};
 KeyName.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode : field values missing.");a.writeStartElement(this.getElementLabel());this.contentName.to_ccnb(a);null!=this.publisherID&&this.publisherID.to_ccnb(a);a.writeEndElement()};KeyName.prototype.getElementLabel=function(){return CCNProtocolDTags.KeyName};KeyName.prototype.validate=function(){return null!=this.contentName};
 var PublisherType=function(a){this.KEY=CCNProtocolDTags.PublisherPublicKeyDigest;this.CERTIFICATE=CCNProtocolDTags.PublisherCertificateDigest;this.ISSUER_KEY=CCNProtocolDTags.PublisherIssuerKeyDigest;this.ISSUER_CERTIFICATE=CCNProtocolDTags.PublisherIssuerCertificateDigest;this.Tag=a},isTypeTagVal=function(a){return a==CCNProtocolDTags.PublisherPublicKeyDigest||a==CCNProtocolDTags.PublisherCertificateDigest||a==CCNProtocolDTags.PublisherIssuerKeyDigest||a==CCNProtocolDTags.PublisherIssuerCertificateDigest?
 !0:!1},PublisherID=function(){this.PUBLISHER_ID_DIGEST_ALGORITHM="SHA-256";this.PUBLISHER_ID_LEN=32;this.publisherType=this.publisherID=null};
 PublisherID.prototype.from_ccnb=function(a){var b=a.peekStartElementAsLong();if(null==b)throw Error("Cannot parse publisher ID.");this.publisherType=new PublisherType(b);if(!isTypeTagVal(b))throw Error("Invalid publisher ID, got unexpected type: "+b);this.publisherID=a.readBinaryElement(b);if(null==this.publisherID)throw new ContentDecodingException(Error("Cannot parse publisher ID of type : "+b+"."));};
-PublisherID.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode "+this.getClass().getName()+": field values missing.");a.writeElement(this.getElementLabel(),this.publisherID)};PublisherID.peek=function(a){nextTag=a.peekStartElementAsLong();return null==nextTag?!1:isTypeTagVal(nextTag)};PublisherID.prototype.getElementLabel=function(){return this.publisherType.Tag};PublisherID.prototype.validate=function(){return null!=id()&&null!=type()};
+PublisherID.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode "+this.getClass().getName()+": field values missing.");a.writeElement(this.getElementLabel(),this.publisherID)};PublisherID.peek=function(a){a=a.peekStartElementAsLong();return null==a?!1:isTypeTagVal(a)};PublisherID.prototype.getElementLabel=function(){return this.publisherType.Tag};PublisherID.prototype.validate=function(){return null!=id()&&null!=type()};
 var PublisherPublicKeyDigest=function(a){this.PUBLISHER_ID_LEN=64;this.publisherPublicKeyDigest=a};
 PublisherPublicKeyDigest.prototype.from_ccnb=function(a){this.publisherPublicKeyDigest=a.readBinaryElement(this.getElementLabel());4<LOG&&console.log("Publisher public key digest is "+this.publisherPublicKeyDigest);if(null==this.publisherPublicKeyDigest)throw Error("Cannot parse publisher key digest.");this.publisherPublicKeyDigest.length!=this.PUBLISHER_ID_LEN&&0<LOG&&console.log("LENGTH OF PUBLISHER ID IS WRONG! Expected "+this.PUBLISHER_ID_LEN+", got "+this.publisherPublicKeyDigest.length)};
 PublisherPublicKeyDigest.prototype.to_ccnb=function(a){if(!this.validate())throw Error("Cannot encode : field values missing.");3<LOG&&console.log("PUBLISHER KEY DIGEST IS"+this.publisherPublicKeyDigest);a.writeElement(this.getElementLabel(),this.publisherPublicKeyDigest)};PublisherPublicKeyDigest.prototype.getElementLabel=function(){return CCNProtocolDTags.PublisherPublicKeyDigest};PublisherPublicKeyDigest.prototype.validate=function(){return null!=this.publisherPublicKeyDigest};
-var NetworkProtocol={TCP:6,UDP:17},FaceInstance=function(a,b,c,d,e,f,g,h,j){this.action=a;this.publisherPublicKeyDigest=b;this.faceID=c;this.ipProto=d;this.host=e;this.Port=f;this.multicastInterface=g;this.multicastTTL=h;this.freshnessSeconds=j};
+var NetworkProtocol={TCP:6,UDP:17},FaceInstance=function(a,b,c,d,e,f,g,h,i){this.action=a;this.publisherPublicKeyDigest=b;this.faceID=c;this.ipProto=d;this.host=e;this.Port=f;this.multicastInterface=g;this.multicastTTL=h;this.freshnessSeconds=i};
 FaceInstance.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.Action)&&(this.action=a.readUTF8Element(CCNProtocolDTags.Action));a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(this.publisherPublicKeyDigest=new PublisherPublicKeyDigest,this.publisherPublicKeyDigest.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.FaceID)&&(this.faceID=a.readIntegerElement(CCNProtocolDTags.FaceID));if(a.peekStartElement(CCNProtocolDTags.IPProto)){var b=
 a.readIntegerElement(CCNProtocolDTags.IPProto);this.ipProto=null;if(NetworkProtocol.TCP==b)this.ipProto=NetworkProtocol.TCP;else if(NetworkProtocol.UDP==b)this.ipProto=NetworkProtocol.UDP;else throw Error("FaceInstance.decoder.  Invalid "+CCNProtocolDTags.tagToString(CCNProtocolDTags.IPProto)+" field: "+b);}a.peekStartElement(CCNProtocolDTags.Host)&&(this.host=a.readUTF8Element(CCNProtocolDTags.Host));a.peekStartElement(CCNProtocolDTags.Port)&&(this.Port=a.readIntegerElement(CCNProtocolDTags.Port));
 a.peekStartElement(CCNProtocolDTags.MulticastInterface)&&(this.multicastInterface=a.readUTF8Element(CCNProtocolDTags.MulticastInterface));a.peekStartElement(CCNProtocolDTags.MulticastTTL)&&(this.multicastTTL=a.readIntegerElement(CCNProtocolDTags.MulticastTTL));a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.freshnessSeconds=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds));a.readEndElement()};
@@ -87,28 +86,27 @@
 ForwardingEntry.prototype.from_ccnb=function(a){a.readStartElement(this.getElementLabel());a.peekStartElement(CCNProtocolDTags.Action)&&(this.action=a.readUTF8Element(CCNProtocolDTags.Action));a.peekStartElement(CCNProtocolDTags.Name)&&(this.prefixName=new Name,this.prefixName.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)&&(this.CcndId=new PublisherPublicKeyDigest,this.CcndId.from_ccnb(a));a.peekStartElement(CCNProtocolDTags.FaceID)&&(this.faceID=a.readIntegerElement(CCNProtocolDTags.FaceID));
 a.peekStartElement(CCNProtocolDTags.ForwardingFlags)&&(this.flags=a.readIntegerElement(CCNProtocolDTags.ForwardingFlags));a.peekStartElement(CCNProtocolDTags.FreshnessSeconds)&&(this.lifetime=a.readIntegerElement(CCNProtocolDTags.FreshnessSeconds));a.readEndElement()};
 ForwardingEntry.prototype.to_ccnb=function(a){a.writeStartElement(this.getElementLabel());null!=this.action&&0!=this.action.length&&a.writeElement(CCNProtocolDTags.Action,this.action);null!=this.prefixName&&this.prefixName.to_ccnb(a);null!=this.CcndId&&this.CcndId.to_ccnb(a);null!=this.faceID&&a.writeElement(CCNProtocolDTags.FaceID,this.faceID);null!=this.flags&&a.writeElement(CCNProtocolDTags.ForwardingFlags,this.flags);null!=this.lifetime&&a.writeElement(CCNProtocolDTags.FreshnessSeconds,this.lifetime);
-a.writeEndElement()};ForwardingEntry.prototype.getElementLabel=function(){return CCNProtocolDTags.ForwardingEntry};
-var XML_EXT=0,XML_TAG=1,XML_DTAG=2,XML_ATTR=3,XML_DATTR=4,XML_BLOB=5,XML_UDATA=6,XML_CLOSE=0,XML_SUBTYPE_PROCESSING_INSTRUCTIONS=16,XML_TT_BITS=3,XML_TT_MASK=(1<<XML_TT_BITS)-1,XML_TT_VAL_BITS=XML_TT_BITS+1,XML_TT_VAL_MASK=(1<<XML_TT_VAL_BITS)-1,XML_REG_VAL_BITS=7,XML_REG_VAL_MASK=(1<<XML_REG_VAL_BITS)-1,XML_TT_NO_MORE=1<<XML_REG_VAL_BITS,BYTE_MASK=255,LONG_BYTES=8,LONG_BITS=64,bits_11=2047,bits_18=262143,bits_32=4294967295,BinaryXMLEncoder=function(){this.ostream=new Uint8Array(1E4);this.offset=
-0;this.CODEC_NAME="Binary"};BinaryXMLEncoder.prototype.writeUString=function(a){this.encodeUString(a,XML_UDATA)};BinaryXMLEncoder.prototype.writeBlob=function(a){3<LOG&&console.log(a);this.encodeBlob(a,a.length)};BinaryXMLEncoder.prototype.writeStartElement=function(a,b){null==a?this.encodeUString(a,XML_TAG):this.encodeTypeAndVal(XML_DTAG,a);null!=b&&this.writeAttributes(b)};BinaryXMLEncoder.prototype.writeEndElement=function(){this.ostream[this.offset]=XML_CLOSE;this.offset+=1};
-BinaryXMLEncoder.prototype.writeAttributes=function(a){if(null!=a)for(var b=0;b<a.length;b++){var c=a[b].k,d=a[b].v,e=stringToTag(c);null==e?this.encodeUString(c,XML_ATTR):this.encodeTypeAndVal(XML_DATTR,e);this.encodeUString(d)}};stringToTag=function(a){return 0<=a&&a<CCNProtocolDTagsStrings.length?CCNProtocolDTagsStrings[a]:a==CCNProtocolDTags.CCNProtocolDataUnit?CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT:null};
-tagToString=function(a){for(var b=0;b<CCNProtocolDTagsStrings.length;++b)if(null!=CCNProtocolDTagsStrings[b]&&CCNProtocolDTagsStrings[b]==a)return b;return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT==a?CCNProtocolDTags.CCNProtocolDataUnit:null};
+a.writeEndElement()};ForwardingEntry.prototype.getElementLabel=function(){return CCNProtocolDTags.ForwardingEntry};var DynamicUint8Array=function(a){a||(a=16);this.array=new Uint8Array(a);this.length=a};DynamicUint8Array.prototype.ensureLength=function(a){if(!(this.array.length>=a)){var b=2*this.array.length;a>b&&(b=a);a=new Uint8Array(b);a.set(this.array);this.array=a;this.length=b}};DynamicUint8Array.prototype.set=function(a,b){this.ensureLength(a.length+b);this.array.set(a,b)};
+DynamicUint8Array.prototype.subarray=function(a,b){return this.array.subarray(a,b)};
+var XML_EXT=0,XML_TAG=1,XML_DTAG=2,XML_ATTR=3,XML_DATTR=4,XML_BLOB=5,XML_UDATA=6,XML_CLOSE=0,XML_SUBTYPE_PROCESSING_INSTRUCTIONS=16,XML_TT_BITS=3,XML_TT_MASK=(1<<XML_TT_BITS)-1,XML_TT_VAL_BITS=XML_TT_BITS+1,XML_TT_VAL_MASK=(1<<XML_TT_VAL_BITS)-1,XML_REG_VAL_BITS=7,XML_REG_VAL_MASK=(1<<XML_REG_VAL_BITS)-1,XML_TT_NO_MORE=1<<XML_REG_VAL_BITS,BYTE_MASK=255,LONG_BYTES=8,LONG_BITS=64,bits_11=2047,bits_18=262143,bits_32=4294967295,BinaryXMLEncoder=function(){this.ostream=new DynamicUint8Array(100);this.offset=
+0;this.CODEC_NAME="Binary"};BinaryXMLEncoder.prototype.writeUString=function(a){this.encodeUString(a,XML_UDATA)};BinaryXMLEncoder.prototype.writeBlob=function(a){3<LOG&&console.log(a);this.encodeBlob(a,a.length)};BinaryXMLEncoder.prototype.writeStartElement=function(a,b){null==a?this.encodeUString(a,XML_TAG):this.encodeTypeAndVal(XML_DTAG,a);null!=b&&this.writeAttributes(b)};
+BinaryXMLEncoder.prototype.writeEndElement=function(){this.ostream.ensureLength(this.offset+1);this.ostream.array[this.offset]=XML_CLOSE;this.offset+=1};BinaryXMLEncoder.prototype.writeAttributes=function(a){if(null!=a)for(var b=0;b<a.length;b++){var c=a[b].k,d=a[b].v,e=stringToTag(c);null==e?this.encodeUString(c,XML_ATTR):this.encodeTypeAndVal(XML_DATTR,e);this.encodeUString(d)}};
+stringToTag=function(a){return 0<=a&&a<CCNProtocolDTagsStrings.length?CCNProtocolDTagsStrings[a]:a==CCNProtocolDTags.CCNProtocolDataUnit?CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT:null};tagToString=function(a){for(var b=0;b<CCNProtocolDTagsStrings.length;++b)if(null!=CCNProtocolDTagsStrings[b]&&CCNProtocolDTagsStrings[b]==a)return b;return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT==a?CCNProtocolDTags.CCNProtocolDataUnit:null};
 BinaryXMLEncoder.prototype.writeElement=function(a,b,c){this.writeStartElement(a,c);"number"===typeof b?(4<LOG&&console.log("GOING TO WRITE THE NUMBER .charCodeAt(0) "+b.toString().charCodeAt(0)),4<LOG&&console.log("GOING TO WRITE THE NUMBER "+b.toString()),4<LOG&&console.log("type of number is "+typeof b.toString()),this.writeUString(b.toString())):"string"===typeof b?(4<LOG&&console.log("GOING TO WRITE THE STRING  "+b),4<LOG&&console.log("type of STRING is "+typeof b),this.writeUString(b)):(4<LOG&&
 console.log("GOING TO WRITE A BLOB  "+b),this.writeBlob(b));this.writeEndElement()};var TypeAndVal=function(a,b){this.type=a;this.val=b};
-BinaryXMLEncoder.prototype.encodeTypeAndVal=function(a,b){4<LOG&&console.log("Encoding type "+a+" and value "+b);4<LOG&&console.log("OFFSET IS "+this.offset);if(a>XML_UDATA||0>a||0>b)throw Error("Tag and value must be positive, and tag valid.");var c=this.numEncodingBytes(b);if(this.offset+c>this.ostream.length)throw Error("Buffer space of "+(this.ostream.length-this.offset)+" bytes insufficient to hold "+c+" of encoded type and value.");this.ostream[this.offset+c-1]=BYTE_MASK&(XML_TT_MASK&a|(XML_TT_VAL_MASK&
-b)<<XML_TT_BITS)|XML_TT_NO_MORE;for(var b=b>>>XML_TT_VAL_BITS,d=this.offset+c-2;0!=b&&d>=this.offset;)this.ostream[d]=BYTE_MASK&b&XML_REG_VAL_MASK,b>>>=XML_REG_VAL_BITS,--d;if(0!=b)throw Error("This should not happen: miscalculated encoding");this.offset+=c;return c};
-BinaryXMLEncoder.prototype.encodeUString=function(a,b){if(null!=a&&!(b==XML_TAG||b==XML_ATTR&&0==a.length)){3<LOG&&console.log("The string to write is ");3<LOG&&console.log(a);var c=DataUtils.stringToUtf8Array(a);this.encodeTypeAndVal(b,b==XML_TAG||b==XML_ATTR?c.length-1:c.length);3<LOG&&console.log("THE string to write is ");3<LOG&&console.log(c);this.writeString(c,this.offset);this.offset+=c.length}};
-BinaryXMLEncoder.prototype.encodeBlob=function(a,b){null!=a&&(4<LOG&&console.log("LENGTH OF XML_BLOB IS "+b),this.encodeTypeAndVal(XML_BLOB,b),this.writeBlobArray(a,this.offset),this.offset+=b)};var ENCODING_LIMIT_1_BYTE=(1<<XML_TT_VAL_BITS)-1,ENCODING_LIMIT_2_BYTES=(1<<XML_TT_VAL_BITS+XML_REG_VAL_BITS)-1,ENCODING_LIMIT_3_BYTES=(1<<XML_TT_VAL_BITS+2*XML_REG_VAL_BITS)-1;
+BinaryXMLEncoder.prototype.encodeTypeAndVal=function(a,b){4<LOG&&console.log("Encoding type "+a+" and value "+b);4<LOG&&console.log("OFFSET IS "+this.offset);if(a>XML_UDATA||0>a||0>b)throw Error("Tag and value must be positive, and tag valid.");var c=this.numEncodingBytes(b);this.ostream.ensureLength(this.offset+c);this.ostream.array[this.offset+c-1]=BYTE_MASK&(XML_TT_MASK&a|(XML_TT_VAL_MASK&b)<<XML_TT_BITS)|XML_TT_NO_MORE;for(var b=b>>>XML_TT_VAL_BITS,d=this.offset+c-2;0!=b&&d>=this.offset;)this.ostream.array[d]=
+BYTE_MASK&b&XML_REG_VAL_MASK,b>>>=XML_REG_VAL_BITS,--d;if(0!=b)throw Error("This should not happen: miscalculated encoding");this.offset+=c;return c};
+BinaryXMLEncoder.prototype.encodeUString=function(a,b){if(null!=a&&!(b==XML_TAG||b==XML_ATTR&&0==a.length)){3<LOG&&console.log("The string to write is ");3<LOG&&console.log(a);var c=DataUtils.stringToUtf8Array(a);this.encodeTypeAndVal(b,b==XML_TAG||b==XML_ATTR?c.length-1:c.length);3<LOG&&console.log("THE string to write is ");3<LOG&&console.log(c);this.writeString(c);this.offset+=c.length}};
+BinaryXMLEncoder.prototype.encodeBlob=function(a,b){null!=a&&(4<LOG&&console.log("LENGTH OF XML_BLOB IS "+b),this.encodeTypeAndVal(XML_BLOB,b),this.writeBlobArray(a),this.offset+=b)};var ENCODING_LIMIT_1_BYTE=(1<<XML_TT_VAL_BITS)-1,ENCODING_LIMIT_2_BYTES=(1<<XML_TT_VAL_BITS+XML_REG_VAL_BITS)-1,ENCODING_LIMIT_3_BYTES=(1<<XML_TT_VAL_BITS+2*XML_REG_VAL_BITS)-1;
 BinaryXMLEncoder.prototype.numEncodingBytes=function(a){if(a<=ENCODING_LIMIT_1_BYTE)return 1;if(a<=ENCODING_LIMIT_2_BYTES)return 2;if(a<=ENCODING_LIMIT_3_BYTES)return 3;for(var b=1,a=a>>>XML_TT_VAL_BITS;0!=a;)b++,a>>>=XML_REG_VAL_BITS;return b};
 BinaryXMLEncoder.prototype.writeDateTime=function(a,b){4<LOG&&console.log("ENCODING DATE with LONG VALUE");4<LOG&&console.log(b.msec);var c=Math.round(4096*(b.msec/1E3)).toString(16),c=DataUtils.toNumbers("0".concat(c,"0"));4<LOG&&console.log("ENCODING DATE with BINARY VALUE");4<LOG&&console.log(c);4<LOG&&console.log("ENCODING DATE with BINARY VALUE(HEX)");4<LOG&&console.log(DataUtils.toHex(c));this.writeElement(a,c)};
-BinaryXMLEncoder.prototype.writeString=function(a){if("string"===typeof a){4<LOG&&console.log("GOING TO WRITE A STRING");4<LOG&&console.log(a);for(i=0;i<a.length;i++)4<LOG&&console.log("input.charCodeAt(i)="+a.charCodeAt(i)),this.ostream[this.offset+i]=a.charCodeAt(i)}else 4<LOG&&console.log("GOING TO WRITE A STRING IN BINARY FORM"),4<LOG&&console.log(a),this.writeBlobArray(a)};BinaryXMLEncoder.prototype.writeBlobArray=function(a){4<LOG&&console.log("GOING TO WRITE A BLOB");this.ostream.set(a,this.offset)};
-BinaryXMLEncoder.prototype.getReducedOstream=function(){return this.ostream.subarray(0,this.offset)};XML_EXT=0;XML_TAG=1;XML_DTAG=2;XML_ATTR=3;XML_DATTR=4;XML_BLOB=5;XML_UDATA=6;XML_CLOSE=0;XML_SUBTYPE_PROCESSING_INSTRUCTIONS=16;XML_TT_BITS=3;XML_TT_MASK=(1<<XML_TT_BITS)-1;XML_TT_VAL_BITS=XML_TT_BITS+1;XML_TT_VAL_MASK=(1<<XML_TT_VAL_BITS)-1;XML_REG_VAL_BITS=7;XML_REG_VAL_MASK=(1<<XML_REG_VAL_BITS)-1;XML_TT_NO_MORE=1<<XML_REG_VAL_BITS;BYTE_MASK=255;LONG_BYTES=8;LONG_BITS=64;bits_11=2047;bits_18=262143;
-bits_32=4294967295;tagToString=function(a){return 0<=a&&a<CCNProtocolDTagsStrings.length?CCNProtocolDTagsStrings[a]:a==CCNProtocolDTags.CCNProtocolDataUnit?CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT:null};stringToTag=function(a){for(var b=0;b<CCNProtocolDTagsStrings.length;++b)if(null!=CCNProtocolDTagsStrings[b]&&CCNProtocolDTagsStrings[b]==a)return b;return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT==a?CCNProtocolDTags.CCNProtocolDataUnit:null};
-var BinaryXMLDecoder=function(a){this.istream=a;this.offset=0};
-BinaryXMLDecoder.prototype.readAttributes=function(a){if(null!=a)try{for(var b=this.peekTypeAndVal();null!=b&&(XML_ATTR==b.type()||XML_DATTR==b.type());){var c=this.decodeTypeAndVal(),d=null;if(XML_ATTR==c.type())d=this.decodeUString(c.val()+1);else if(XML_DATTR==c.type()&&(d=tagToString(c.val()),null==d))throw new ContentDecodingException(Error("Unknown DATTR value"+c.val()));var e=this.decodeUString();a.put(d,e);b=this.peekTypeAndVal()}}catch(f){throw new ContentDecodingException(Error("readStartElement",f));
-}};BinaryXMLDecoder.prototype.initializeDecoding=function(){};BinaryXMLDecoder.prototype.readStartDocument=function(){};BinaryXMLDecoder.prototype.readEndDocument=function(){};
-BinaryXMLDecoder.prototype.readStartElement=function(a,b){tv=this.decodeTypeAndVal();if(null==tv)throw new ContentDecodingException(Error("Expected start element: "+a+" got something not a tag."));var c=null;tv.type()==XML_TAG?(c="string"==typeof tv.val()?parseInt(tv.val())+1:tv.val()+1,c=this.decodeUString(c)):tv.type()==XML_DTAG&&(c=tv.val());if(null==c||c!=a)throw console.log("expecting "+a+" but got "+c),new ContentDecodingException(Error("Expected start element: "+a+" got: "+c+"("+tv.val()+")"));
+BinaryXMLEncoder.prototype.writeString=function(a){if("string"===typeof a){4<LOG&&console.log("GOING TO WRITE A STRING");4<LOG&&console.log(a);this.ostream.ensureLength(this.offset+a.length);for(var b=0;b<a.length;b++)4<LOG&&console.log("input.charCodeAt(i)="+a.charCodeAt(b)),this.ostream.array[this.offset+b]=a.charCodeAt(b)}else 4<LOG&&console.log("GOING TO WRITE A STRING IN BINARY FORM"),4<LOG&&console.log(a),this.writeBlobArray(a)};
+BinaryXMLEncoder.prototype.writeBlobArray=function(a){4<LOG&&console.log("GOING TO WRITE A BLOB");this.ostream.set(a,this.offset)};BinaryXMLEncoder.prototype.getReducedOstream=function(){return this.ostream.subarray(0,this.offset)};XML_EXT=0;XML_TAG=1;XML_DTAG=2;XML_ATTR=3;XML_DATTR=4;XML_BLOB=5;XML_UDATA=6;XML_CLOSE=0;XML_SUBTYPE_PROCESSING_INSTRUCTIONS=16;XML_TT_BITS=3;XML_TT_MASK=(1<<XML_TT_BITS)-1;XML_TT_VAL_BITS=XML_TT_BITS+1;XML_TT_VAL_MASK=(1<<XML_TT_VAL_BITS)-1;XML_REG_VAL_BITS=7;
+XML_REG_VAL_MASK=(1<<XML_REG_VAL_BITS)-1;XML_TT_NO_MORE=1<<XML_REG_VAL_BITS;BYTE_MASK=255;LONG_BYTES=8;LONG_BITS=64;bits_11=2047;bits_18=262143;bits_32=4294967295;tagToString=function(a){return 0<=a&&a<CCNProtocolDTagsStrings.length?CCNProtocolDTagsStrings[a]:a==CCNProtocolDTags.CCNProtocolDataUnit?CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT:null};
+stringToTag=function(a){for(var b=0;b<CCNProtocolDTagsStrings.length;++b)if(null!=CCNProtocolDTagsStrings[b]&&CCNProtocolDTagsStrings[b]==a)return b;return CCNProtocolDTags.CCNPROTOCOL_DATA_UNIT==a?CCNProtocolDTags.CCNProtocolDataUnit:null};var BinaryXMLDecoder=function(a){this.istream=a;this.offset=0};BinaryXMLDecoder.prototype.initializeDecoding=function(){};BinaryXMLDecoder.prototype.readStartDocument=function(){};BinaryXMLDecoder.prototype.readEndDocument=function(){};
+BinaryXMLDecoder.prototype.readStartElement=function(a,b){var c=this.decodeTypeAndVal();if(null==c)throw new ContentDecodingException(Error("Expected start element: "+a+" got something not a tag."));var d=null;c.type()==XML_TAG?(d="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1,d=this.decodeUString(d)):c.type()==XML_DTAG&&(d=c.val());if(null==d||d!=a)throw console.log("expecting "+a+" but got "+d),new ContentDecodingException(Error("Expected start element: "+a+" got: "+d+"("+c.val()+")"));
 null!=b&&readAttributes(b)};
-BinaryXMLDecoder.prototype.readAttributes=function(a){if(null!=a)try{for(var b=this.peekTypeAndVal();null!=b&&(XML_ATTR==b.type()||XML_DATTR==b.type());){var c=this.decodeTypeAndVal(),d=null;if(XML_ATTR==c.type()){var e;e="string"==typeof tv.val()?parseInt(tv.val())+1:tv.val()+1;d=this.decodeUString(e)}else if(XML_DATTR==c.type()&&(d=tagToString(c.val()),null==d))throw new ContentDecodingException(Error("Unknown DATTR value"+c.val()));var f=this.decodeUString();a.push([d,f]);b=this.peekTypeAndVal()}}catch(g){throw new ContentDecodingException(Error("readStartElement",
+BinaryXMLDecoder.prototype.readAttributes=function(a){if(null!=a)try{for(var b=this.peekTypeAndVal();null!=b&&(XML_ATTR==b.type()||XML_DATTR==b.type());){var c=this.decodeTypeAndVal(),d=null;if(XML_ATTR==c.type()){var e;e="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1;d=this.decodeUString(e)}else if(XML_DATTR==c.type()&&(d=tagToString(c.val()),null==d))throw new ContentDecodingException(Error("Unknown DATTR value"+c.val()));var f=this.decodeUString();a.push([d,f]);b=this.peekTypeAndVal()}}catch(g){throw new ContentDecodingException(Error("readStartElement",
 g));}};BinaryXMLDecoder.prototype.peekStartElementAsString=function(){var a=null,b=this.offset;try{var c=this.decodeTypeAndVal();if(null!=c)if(c.type()==XML_TAG){var d;d="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1;a=this.decodeUString(d)}else c.type()==XML_DTAG&&(a=tagToString(c.val()))}catch(e){}finally{try{this.offset=b}catch(f){throw Log.logStackTrace(Log.FAC_ENCODING,Level.WARNING,f),new ContentDecodingException(Error("Cannot reset stream! "+f.getMessage(),f));}}return a};
 BinaryXMLDecoder.prototype.peekStartElement=function(a){if("string"==typeof a){var b=this.peekStartElementAsString();return null!=b&&b==a?!0:!1}if("number"==typeof a)return b=this.peekStartElementAsLong(),null!=b&&b==a?!0:!1;throw new ContentDecodingException(Error("SHOULD BE STRING OR NUMBER"));};
 BinaryXMLDecoder.prototype.peekStartElementAsLong=function(){var a=null,b=this.offset;try{var c=this.decodeTypeAndVal();if(null!=c)if(c.type()==XML_TAG){if(c.val()+1>DEBUG_MAX_LEN)throw new ContentDecodingException(Error("Decoding error: length "+c.val()+1+" longer than expected maximum length!"));var d;d="string"==typeof c.val()?parseInt(c.val())+1:c.val()+1;var e=this.decodeUString(d),a=stringToTag(e)}else c.type()==XML_DTAG&&(a=c.val())}catch(f){}finally{try{this.offset=b}catch(g){throw Log.logStackTrace(Log.FAC_ENCODING,
@@ -116,40 +114,42 @@
 BinaryXMLDecoder.prototype.readEndElement=function(){4<LOG&&console.log("this.offset is "+this.offset);var a=this.istream[this.offset];this.offset++;4<LOG&&console.log("XML_CLOSE IS "+XML_CLOSE);4<LOG&&console.log("next is "+a);if(a!=XML_CLOSE)throw console.log("Expected end element, got: "+a),new ContentDecodingException(Error("Expected end element, got: "+a));};BinaryXMLDecoder.prototype.readUString=function(){var a=this.decodeUString();this.readEndElement();return a};
 BinaryXMLDecoder.prototype.readBlob=function(){var a=this.decodeBlob();this.readEndElement();return a};BinaryXMLDecoder.prototype.readDateTime=function(a){var a=this.readBinaryElement(a),a=DataUtils.toHex(a),a=parseInt(a,16),b=1E3*(a/4096);3<LOG&&console.log("DECODED DATE WITH VALUE");3<LOG&&console.log(b);b=new CCNTime(b);if(null==b)throw new ContentDecodingException(Error("Cannot parse timestamp: "+DataUtils.printHexBytes(a)));return b};
 BinaryXMLDecoder.prototype.decodeTypeAndVal=function(){var a=-1,b=0,c=!0;do{var d=this.istream[this.offset];if(0>d||0==d&&0==b)return null;(c=0==(d&XML_TT_NO_MORE))?(b<<=XML_REG_VAL_BITS,b|=d&XML_REG_VAL_MASK):(a=d&XML_TT_MASK,b<<=XML_TT_VAL_BITS,b|=d>>>XML_TT_BITS&XML_TT_VAL_MASK);this.offset++}while(c);3<LOG&&console.log("TYPE is "+a+" VAL is "+b);return new TypeAndVal(a,b)};BinaryXMLDecoder.peekTypeAndVal=function(){var a=null,b=this.offset;try{a=this.decodeTypeAndVal()}finally{this.offset=b}return a};
-BinaryXMLDecoder.prototype.decodeBlob=function(a){if(null==a)return a=this.decodeTypeAndVal(),a="string"==typeof a.val()?parseInt(a.val()):a.val(),this.decodeBlob(a);var b=this.istream.subarray(this.offset,this.offset+a);this.offset+=a;return b};var count=0;
+BinaryXMLDecoder.prototype.decodeBlob=function(a){if(null==a)return a=this.decodeTypeAndVal(),a="string"==typeof a.val()?parseInt(a.val()):a.val(),this.decodeBlob(a);var b=this.istream.subarray(this.offset,this.offset+a);this.offset+=a;return b};
 BinaryXMLDecoder.prototype.decodeUString=function(a){if(null==a){var a=this.offset,b=this.decodeTypeAndVal();3<LOG&&console.log("TV is "+b);3<LOG&&console.log(b);3<LOG&&console.log("Type of TV is "+typeof b);return null==b||XML_UDATA!=b.type()?(this.offset=a,""):this.decodeUString(b.val())}a=this.decodeBlob(a);return DataUtils.toString(a)};TypeAndVal=function(a,b){this.t=a;this.v=b};TypeAndVal.prototype.type=function(){return this.t};TypeAndVal.prototype.val=function(){return this.v};
 BinaryXMLDecoder.prototype.readIntegerElement=function(a){4<LOG&&console.log("READING INTEGER "+a);4<LOG&&console.log("TYPE OF "+typeof a);a=this.readUTF8Element(a);return parseInt(a)};BinaryXMLDecoder.prototype.readUTF8Element=function(a,b){this.readStartElement(a,b);return this.readUString()};BinaryXMLDecoder.prototype.seek=function(a){this.offset=a};function ContentDecodingException(a){this.message=a.message;for(var b in a)this[b]=a[b]}ContentDecodingException.prototype=Error();
-ContentDecodingException.prototype.name="ContentDecodingException";var BinaryXMLStructureDecoder=function(){this.gotElementEnd=!1;this.level=this.offset=0;this.state=BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;this.headerLength=0;this.useHeaderBuffer=!1;this.headerBuffer=new Uint8Array(5);this.nBytesToRead=0};BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE=0;BinaryXMLStructureDecoder.READ_BYTES=1;
+ContentDecodingException.prototype.name="ContentDecodingException";var BinaryXMLStructureDecoder=function(){this.gotElementEnd=!1;this.level=this.offset=0;this.state=BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE;this.headerLength=0;this.useHeaderBuffer=!1;this.headerBuffer=new DynamicUint8Array(5);this.nBytesToRead=0};BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE=0;BinaryXMLStructureDecoder.READ_BYTES=1;
 BinaryXMLStructureDecoder.prototype.findElementEnd=function(a){if(this.gotElementEnd)return!0;for(var b=new BinaryXMLDecoder(a);;){if(this.offset>=a.length)return!1;switch(this.state){case BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE:if(0==this.headerLength&&a[this.offset]==XML_CLOSE){++this.offset;--this.level;if(0==this.level)return!0;if(0>this.level)throw Error("BinaryXMLStructureDecoder: Unexepected close tag at offset "+(this.offset-1));this.startHeader();break}for(var c=this.headerLength;;){if(this.offset>=
-a.length){this.useHeaderBuffer=!0;var d=this.headerLength-c;this.setHeaderBuffer(a.subarray(this.offset-d,d),c);return!1}d=a[this.offset++];++this.headerLength;if(d&XML_TT_NO_MORE)break}this.useHeaderBuffer?(d=this.headerLength-c,this.setHeaderBuffer(a.subarray(this.offset-d,d),c),c=(new BinaryXMLDecoder(this.headerBuffer)).decodeTypeAndVal()):(b.seek(this.offset-this.headerLength),c=b.decodeTypeAndVal());if(null==c)throw Error("BinaryXMLStructureDecoder: Can't read header starting at offset "+(this.offset-
-this.headerLength));d=c.t;if(d==XML_DATTR)this.startHeader();else if(d==XML_DTAG||d==XML_EXT)++this.level,this.startHeader();else if(d==XML_TAG||d==XML_ATTR)d==XML_TAG&&++this.level,this.nBytesToRead=c.v+1,this.state=BinaryXMLStructureDecoder.READ_BYTES;else if(d==XML_BLOB||d==XML_UDATA)this.nBytesToRead=c.v,this.state=BinaryXMLStructureDecoder.READ_BYTES;else throw Error("BinaryXMLStructureDecoder: Unrecognized header type "+d);break;case BinaryXMLStructureDecoder.READ_BYTES:c=a.length-this.offset;
-if(c<this.nBytesToRead)return this.offset+=c,this.nBytesToRead-=c,!1;this.offset+=this.nBytesToRead;this.startHeader();break;default:throw Error("BinaryXMLStructureDecoder: Unrecognized state "+this.state);}}};BinaryXMLStructureDecoder.prototype.startHeader=function(){this.headerLength=0;this.useHeaderBuffer=!1;this.state=BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE};BinaryXMLStructureDecoder.prototype.seek=function(a){this.offset=a};
-BinaryXMLStructureDecoder.prototype.setHeaderBuffer=function(a,b){var c=a.length+b;c>this.headerBuffer.length&&(c=new Uint8Array(c+5),c.set(this.headerBuffer),this.headerBuffer=c);this.headerBuffer.set(a,b)};var DataUtils=function(){};DataUtils.keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
-DataUtils.stringtoBase64=function(a){var a=escape(a),b="",c,d,e="",f,g,h="",j=0;do c=a.charCodeAt(j++),d=a.charCodeAt(j++),e=a.charCodeAt(j++),f=c>>2,c=(c&3)<<4|d>>4,g=(d&15)<<2|e>>6,h=e&63,isNaN(d)?g=h=64:isNaN(e)&&(h=64),b=b+DataUtils.keyStr.charAt(f)+DataUtils.keyStr.charAt(c)+DataUtils.keyStr.charAt(g)+DataUtils.keyStr.charAt(h);while(j<a.length);return b};
+a.length){this.useHeaderBuffer=!0;var d=this.headerLength-c;this.headerBuffer.set(a.subarray(this.offset-d,d),c);return!1}d=a[this.offset++];++this.headerLength;if(d&XML_TT_NO_MORE)break}this.useHeaderBuffer?(d=this.headerLength-c,this.headerBuffer.set(a.subarray(this.offset-d,d),c),c=(new BinaryXMLDecoder(this.headerBuffer.array)).decodeTypeAndVal()):(b.seek(this.offset-this.headerLength),c=b.decodeTypeAndVal());if(null==c)throw Error("BinaryXMLStructureDecoder: Can't read header starting at offset "+
+(this.offset-this.headerLength));d=c.t;if(d==XML_DATTR)this.startHeader();else if(d==XML_DTAG||d==XML_EXT)++this.level,this.startHeader();else if(d==XML_TAG||d==XML_ATTR)d==XML_TAG&&++this.level,this.nBytesToRead=c.v+1,this.state=BinaryXMLStructureDecoder.READ_BYTES;else if(d==XML_BLOB||d==XML_UDATA)this.nBytesToRead=c.v,this.state=BinaryXMLStructureDecoder.READ_BYTES;else throw Error("BinaryXMLStructureDecoder: Unrecognized header type "+d);break;case BinaryXMLStructureDecoder.READ_BYTES:c=a.length-
+this.offset;if(c<this.nBytesToRead)return this.offset+=c,this.nBytesToRead-=c,!1;this.offset+=this.nBytesToRead;this.startHeader();break;default:throw Error("BinaryXMLStructureDecoder: Unrecognized state "+this.state);}}};BinaryXMLStructureDecoder.prototype.startHeader=function(){this.headerLength=0;this.useHeaderBuffer=!1;this.state=BinaryXMLStructureDecoder.READ_HEADER_OR_CLOSE};BinaryXMLStructureDecoder.prototype.seek=function(a){this.offset=a};var DataUtils=function(){};DataUtils.keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+DataUtils.stringtoBase64=function(a){var a=escape(a),b="",c,d,e="",f,g,h="",i=0;do c=a.charCodeAt(i++),d=a.charCodeAt(i++),e=a.charCodeAt(i++),f=c>>2,c=(c&3)<<4|d>>4,g=(d&15)<<2|e>>6,h=e&63,isNaN(d)?g=h=64:isNaN(e)&&(h=64),b=b+DataUtils.keyStr.charAt(f)+DataUtils.keyStr.charAt(c)+DataUtils.keyStr.charAt(g)+DataUtils.keyStr.charAt(h);while(i<a.length);return b};
 DataUtils.base64toString=function(a){var b="",c,d,e="",f,g="",h=0;/[^A-Za-z0-9\+\/\=]/g.exec(a)&&alert("There were invalid base64 characters in the input text.\nValid base64 characters are A-Z, a-z, 0-9, '+', '/',and '='\nExpect errors in decoding.");a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");do c=DataUtils.keyStr.indexOf(a.charAt(h++)),d=DataUtils.keyStr.indexOf(a.charAt(h++)),f=DataUtils.keyStr.indexOf(a.charAt(h++)),g=DataUtils.keyStr.indexOf(a.charAt(h++)),c=c<<2|d>>4,d=(d&15)<<4|f>>2,e=(f&3)<<6|g,
 b+=String.fromCharCode(c),64!=f&&(b+=String.fromCharCode(d)),64!=g&&(b+=String.fromCharCode(e));while(h<a.length);return unescape(b)};DataUtils.toHex=function(a){4<LOG&&console.log("ABOUT TO CONVERT "+a);for(var b="",c=0;c<a.length;c++)b+=(16>a[c]?"0":"")+a[c].toString(16);4<LOG&&console.log("Converted to: "+b);return b};DataUtils.stringToHex=function(a){for(var b="",c=0;c<a.length;++c)var d=a.charCodeAt(c),b=b+((16>d?"0":"")+d.toString(16));return b};
 DataUtils.toString=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a[c]);return b};DataUtils.toNumbers=function(a){if("string"==typeof a){var b=new Uint8Array(Math.floor(a.length/2)),c=0;a.replace(/(..)/g,function(a){b[c++]=parseInt(a,16)});return b}};DataUtils.hexToRawString=function(a){if("string"==typeof a){var b="";a.replace(/(..)/g,function(a){b+=String.fromCharCode(parseInt(a,16))});return b}};
 DataUtils.toNumbersFromString=function(a){for(var b=new Uint8Array(a.length),c=0;c<a.length;c++)b[c]=a.charCodeAt(c);return b};DataUtils.stringToUtf8Array=function(a){return DataUtils.toNumbersFromString(str2rstr_utf8(a))};DataUtils.concatArrays=function(a){for(var b=0,c=0;c<a.length;++c)b+=a[c].length;for(var b=new Uint8Array(b),d=0,c=0;c<a.length;++c)b.set(a[c],d),d+=a[c].length;return b};
 DataUtils.decodeUtf8=function(a){for(var b="",c=0,d=0,e=0;c<a.length;)if(d=a.charCodeAt(c),128>d)b+=String.fromCharCode(d),c++;else if(191<d&&224>d)e=a.charCodeAt(c+1),b+=String.fromCharCode((d&31)<<6|e&63),c+=2;else var e=a.charCodeAt(c+1),f=a.charCodeAt(c+2),b=b+String.fromCharCode((d&15)<<12|(e&63)<<6|f&63),c=c+3;return b};DataUtils.arraysEqual=function(a,b){if(a.length!=b.length)return!1;for(var c=0;c<a.length;++c)if(a[c]!=b[c])return!1;return!0};
-DataUtils.bigEndianToUnsignedInt=function(a){for(var b=0,c=0;c<a.length;++c)b<<=8,b+=a[c];return b};DataUtils.nonNegativeIntToBigEndian=function(a){a=Math.round(a);if(0>=a)return new Uint8Array(0);for(var b=new Uint8Array(8),c=0;0!=a;)++c,b[8-c]=a&255,a>>=8;return b.subarray(8-c,8)};function encodeToHexInterest(a){return DataUtils.toHex(encodeToBinaryInterest(a))}function encodeToBinaryInterest(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}
-function encodeToHexContentObject(a){return DataUtils.toHex(encodeToBinaryContentObject(a))}function encodeToBinaryContentObject(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}function encodeForwardingEntry(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}function decodeHexFaceInstance(a){a=DataUtils.toNumbers(a);decoder=new BinaryXMLDecoder(a);3<LOG&&console.log("DECODING HEX FACE INSTANCE  \n"+a);a=new FaceInstance;a.from_ccnb(decoder);return a}
-function decodeHexInterest(a){a=DataUtils.toNumbers(a);decoder=new BinaryXMLDecoder(a);3<LOG&&console.log("DECODING HEX INTERST  \n"+a);a=new Interest;a.from_ccnb(decoder);return a}function decodeHexContentObject(a){a=DataUtils.toNumbers(a);decoder=new BinaryXMLDecoder(a);3<LOG&&console.log("DECODED HEX CONTENT OBJECT \n"+a);co=new ContentObject;co.from_ccnb(decoder);return co}
-function decodeHexForwardingEntry(a){a=DataUtils.toNumbers(a);decoder=new BinaryXMLDecoder(a);3<LOG&&console.log("DECODED HEX FORWARDING ENTRY \n"+a);forwardingEntry=new ForwardingEntry;forwardingEntry.from_ccnb(decoder);return forwardingEntry}
+DataUtils.bigEndianToUnsignedInt=function(a){for(var b=0,c=0;c<a.length;++c)b<<=8,b+=a[c];return b};DataUtils.nonNegativeIntToBigEndian=function(a){a=Math.round(a);if(0>=a)return new Uint8Array(0);for(var b=new Uint8Array(8),c=0;0!=a;)++c,b[8-c]=a&255,a>>=8;return b.subarray(8-c,8)};DataUtils.shuffle=function(a){for(var b=a.length-1;1<=b;--b){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c];a[c]=d}};function encodeToHexInterest(a){return DataUtils.toHex(encodeToBinaryInterest(a))}
+function encodeToBinaryInterest(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}function encodeToHexContentObject(a){return DataUtils.toHex(encodeToBinaryContentObject(a))}function encodeToBinaryContentObject(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}function encodeForwardingEntry(a){var b=new BinaryXMLEncoder;a.to_ccnb(b);return b.getReducedOstream()}
+function decodeHexFaceInstance(a){var b=DataUtils.toNumbers(a),a=new BinaryXMLDecoder(b);3<LOG&&console.log("DECODING HEX FACE INSTANCE  \n"+b);b=new FaceInstance;b.from_ccnb(a);return b}function decodeHexInterest(a){var b=DataUtils.toNumbers(a),a=new BinaryXMLDecoder(b);3<LOG&&console.log("DECODING HEX INTERST  \n"+b);b=new Interest;b.from_ccnb(a);return b}
+function decodeHexContentObject(a){var b=DataUtils.toNumbers(a),a=new BinaryXMLDecoder(b);3<LOG&&console.log("DECODED HEX CONTENT OBJECT \n"+b);b=new ContentObject;b.from_ccnb(a);return b}function decodeHexForwardingEntry(a){var b=DataUtils.toNumbers(a),a=new BinaryXMLDecoder(b);3<LOG&&console.log("DECODED HEX FORWARDING ENTRY \n"+b);b=new ForwardingEntry;b.from_ccnb(a);return b}
+function decodeSubjectPublicKeyInfo(a){var a=DataUtils.toHex(a).toLowerCase(),a=_x509_getPublicKeyHexArrayFromCertHex(a,_x509_getSubjectPublicKeyPosFromCertHex(a,0)),b=new RSAKey;b.setPublic(a[0],a[1]);return b}
 function contentObjectToHtml(a){var b="";if(-1==a)b+="NO CONTENT FOUND";else if(-2==a)b+="CONTENT NAME IS EMPTY";else{null!=a.name&&null!=a.name.components&&(b+="NAME: "+a.name.to_uri(),b+="<br /><br />");null!=a.content&&(b+="CONTENT(ASCII): "+DataUtils.toString(a.content),b+="<br />",b+="<br />");null!=a.content&&(b+="CONTENT(hex): "+DataUtils.toHex(a.content),b+="<br />",b+="<br />");null!=a.signature&&null!=a.signature.signature&&(b+="SIGNATURE(hex): "+DataUtils.toHex(a.signature.signature),b+=
 "<br />",b+="<br />");null!=a.signedInfo&&(null!=a.signedInfo.publisher&&null!=a.signedInfo.publisher.publisherPublicKeyDigest)&&(b+="Publisher Public Key Digest(hex): "+DataUtils.toHex(a.signedInfo.publisher.publisherPublicKeyDigest),b+="<br />",b+="<br />");if(null!=a.signedInfo&&null!=a.signedInfo.timestamp){var c=new Date;c.setTime(a.signedInfo.timestamp.msec);b+="TimeStamp: "+c;b+="<br />";b+="TimeStamp(number): "+a.signedInfo.timestamp.msec;b+="<br />"}null!=a.signedInfo&&null!=a.signedInfo.finalBlockID&&
-(b+="FinalBlockID: "+DataUtils.toHex(a.signedInfo.finalBlockID),b+="<br />");if(null!=a.signedInfo&&null!=a.signedInfo.locator&&null!=a.signedInfo.locator.certificate){var c=DataUtils.toString(a.signedInfo.locator.certificate),d=rstr2b64(c),e=DataUtils.toHex(a.signedInfo.locator.certificate).toLowerCase(),f=DataUtils.toString(a.signedInfo.locator.certificate),c=DataUtils.toHex(a.signature.signature).toLowerCase(),g=DataUtils.toString(a.rawSignatureData),b=b+("DER Certificate: "+d),b=b+"<br />",b=
-b+"<br />";2<LOG&&console.log(" ContentName + SignedInfo + Content = "+g);2<LOG&&console.log("HEX OF ContentName + SignedInfo + Content = ");2<LOG&&console.log(DataUtils.stringtoBase64(g));2<LOG&&console.log(" PublicKey = "+d);2<LOG&&console.log(" PublicKeyHex = "+e);2<LOG&&console.log(" PublicKeyString = "+f);2<LOG&&console.log(" Signature is");2<LOG&&console.log(c);e=new X509;e.readCertPEM(d);c=e.subjectPublicKeyRSA.verifyByteArray(a.rawSignatureData,c);2<LOG&&console.log("result is "+c);d=e.subjectPublicKeyRSA.n;
-e=e.subjectPublicKeyRSA.e;2<LOG&&console.log("PUBLIC KEY n after is ");2<LOG&&console.log(d);2<LOG&&console.log("EXPONENT e after is ");2<LOG&&console.log(e);b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID";b+="<br />";b+="<br />"}null!=a.signedInfo&&(null!=a.signedInfo.locator&&null!=a.signedInfo.locator.publicKey)&&(d=rstr2b64(DataUtils.toString(a.signedInfo.locator.publicKey)),e=DataUtils.toHex(a.signedInfo.locator.publicKey).toLowerCase(),f=DataUtils.toString(a.signedInfo.locator.publicKey),c=DataUtils.toHex(a.signature.signature).toLowerCase(),
-g=DataUtils.toString(a.rawSignatureData),b+="DER Certificate: "+d,b+="<br />",b+="<br />",2<LOG&&console.log(" ContentName + SignedInfo + Content = "+g),2<LOG&&console.log(" PublicKey = "+d),2<LOG&&console.log(" PublicKeyHex = "+e),2<LOG&&console.log(" PublicKeyString = "+f),2<LOG&&console.log(" Signature "+c),2<LOG&&console.log(" Signature NOW IS"),2<LOG&&console.log(a.signature.signature),d=e.slice(56,314),b+="PUBLISHER KEY(hex): "+d,b+="<br />",b+="<br />",2<LOG&&console.log("PUBLIC KEY IN HEX is "),
-2<LOG&&console.log(d),f=e.slice(318,324),2<LOG&&console.log("kp size is "+d.length),b+="exponent: "+f,b+="<br />",b+="<br />",2<LOG&&console.log("EXPONENT is "),2<LOG&&console.log(f),e=new RSAKey,e.setPublic(d,f),c=e.verifyByteArray(a.rawSignatureData,c),2<LOG&&console.log("PUBLIC KEY n after is "),2<LOG&&console.log(e.n),2<LOG&&console.log("EXPONENT e after is "),2<LOG&&console.log(e.e),b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID",b+="<br />",b+="<br />")}return b}
-var KeyManager=function(){this.certificate="MIIBmzCCAQQCCQC32FyQa61S7jANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdheGVsY2R2MB4XDTEyMDQyODIzNDQzN1oXDTEyMDUyODIzNDQzN1owEjEQMA4GA1UEAxMHYXhlbGNkdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4X0wp9goqxuECxdULcr2IHr9Ih4Iaypg0Wy39URIup8/CLzQmdsh3RYqd55hqonu5VTTpH3iMLx6xZDVJAZ8OJi7pvXcQ2C4Re2kjL2c8SanI0RfDhlS1zJadfr1VhRPmpivcYawJ4aFuOLAi+qHFxtN7lhcGCgpW1OV60oXd58CAwEAATANBgkqhkiG9w0BAQUFAAOBgQDLOrA1fXzSrpftUB5Ro6DigX1Bjkf7F5Bkd69hSVp+jYeJFBBlsILQAfSxUZPQtD+2Yc3iCmSYNyxqu9PcufDRJlnvB7PG29+L3y9lR37tetzUV9eTscJ7rdp8Wt6AzpW32IJ/54yKNfP7S6ZIoIG+LP6EIxq6s8K1MXRt8uBJKw==";
-this.publicKey="30819F300D06092A864886F70D010101050003818D0030818902818100E17D30A7D828AB1B840B17542DCAF6207AFD221E086B2A60D16CB7F54448BA9F3F08BCD099DB21DD162A779E61AA89EEE554D3A47DE230BC7AC590D524067C3898BBA6F5DC4360B845EDA48CBD9CF126A723445F0E1952D7325A75FAF556144F9A98AF7186B0278685B8E2C08BEA87171B4DEE585C1828295B5395EB4A17779F0203010001";this.privateKey="MIICXQIBAAKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQABAoGAGkv6T6jC3WmhFZYL6CdCWvlc6gysmKrhjarrLTxgavtFY6R5g2ft5BXAsCCVbUkWxkIFSKqxpVNl0gKZCNGEzPDN6mHJOQI/h0rlxNIHAuGfoAbCzALnqmyZivhJAPGijAyKuU9tczsst5+Kpn+bn7ehzHQuj7iwJonS5WbojqECQQD851K8TpW2GrRizNgG4dx6orZxAaon/Jnl8lS7soXhllQty7qG+oDfzznmdMsiznCqEABzHUUKOVGE9RWPN3aRAkEA5D/w9N55d0ibnChFJlc8cUAoaqH+w+U3oQP2Lb6AZHJpLptN4y4b/uf5d4wYU5/i/gC7SSBH3wFhh9bjRLUDLwJAVOx8vN0Kqt7myfKNbCo19jxjVSlA8TKCn1Oznl/BU1I+rC4oUaEW25DjmX6IpAR8kq7S59ThVSCQPjxqY/A08QJBAIRaF2zGPITQk3r/VumemCvLWiRK/yG0noc9dtibqHOWbCtcXtOm/xDWjq+lis2i3ssOvYrvrv0/HcDY+Dv1An0CQQCLJtMsfSg4kvG/FRY5UMhtMuwo8ovYcMXt4Xv/LWaMhndD67b2UGawQCRqr5ghRTABWdDD/HuuMBjrkPsX0861"};
-KeyManager.prototype.verify=function(a,b){var c=this.certificate,d=new X509;d.readCertPEM(c);return d.subjectPublicKeyRSA.verifyString(a,b)};KeyManager.prototype.sign=function(a){var b=this.privateKey,c=new RSAKey;c.readPrivateKeyFromPEMString(b);return c.signString(a,"sha256")};var globalKeyManager=new KeyManager,hexcase=0,b64pad="";function hex_sha256_from_bytes(a){return rstr2hex(binb2rstr(binb_sha256(byteArray2binb(a),8*a.length)))}
-function hex_sha256(a){return rstr2hex(rstr_sha256(str2rstr_utf8(a)))}function b64_sha256(a){return rstr2b64(rstr_sha256(str2rstr_utf8(a)))}function any_sha256(a,b){return rstr2any(rstr_sha256(str2rstr_utf8(a)),b)}function hex_hmac_sha256(a,b){return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}function b64_hmac_sha256(a,b){return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}
-function any_hmac_sha256(a,b,c){return rstr2any(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)),c)}function sha256_vm_test(){return"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"==hex_sha256("abc").toLowerCase()}function rstr_sha256(a){return binb2rstr(binb_sha256(rstr2binb(a),8*a.length))}
+(b+="FinalBlockID: "+DataUtils.toHex(a.signedInfo.finalBlockID),b+="<br />");if(null!=a.signedInfo&&null!=a.signedInfo.locator&&null!=a.signedInfo.locator.certificate){var d=DataUtils.toHex(a.signedInfo.locator.certificate).toLowerCase(),c=DataUtils.toHex(a.signature.signature).toLowerCase(),e=DataUtils.toString(a.rawSignatureData),b=b+("Hex Certificate: "+d),b=b+"<br />",b=b+"<br />",e=new X509;e.readCertHex(d);b+="Public key (hex) modulus: "+e.subjectPublicKeyRSA.n.toString(16)+"<br/>";b+="exponent: "+
+e.subjectPublicKeyRSA.e.toString(16)+"<br/>";b+="<br/>";c=e.subjectPublicKeyRSA.verifyByteArray(a.rawSignatureData,null,c);2<LOG&&console.log("result is "+c);d=e.subjectPublicKeyRSA.n;e=e.subjectPublicKeyRSA.e;2<LOG&&console.log("PUBLIC KEY n after is ");2<LOG&&console.log(d);2<LOG&&console.log("EXPONENT e after is ");2<LOG&&console.log(e);b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID";b+="<br />";b+="<br />"}if(null!=a.signedInfo&&null!=a.signedInfo.locator&&null!=a.signedInfo.locator.publicKey){var f=
+DataUtils.toHex(a.signedInfo.locator.publicKey).toLowerCase(),g=DataUtils.toString(a.signedInfo.locator.publicKey),c=DataUtils.toHex(a.signature.signature).toLowerCase(),e=DataUtils.toString(a.rawSignatureData),d=null,h="";null!=a.signature.Witness&&(d=new Witness,d.decode(a.signature.Witness),h=DataUtils.toHex(a.signature.Witness));b+="Public key: "+f;b+="<br />";b+="<br />";2<LOG&&console.log(" ContentName + SignedInfo + Content = "+e);2<LOG&&console.log(" PublicKeyHex = "+f);2<LOG&&console.log(" PublicKeyString = "+
+g);2<LOG&&console.log(" Signature "+c);2<LOG&&console.log(" Witness "+h);2<LOG&&console.log(" Signature NOW IS");2<LOG&&console.log(a.signature.signature);e=decodeSubjectPublicKeyInfo(a.signedInfo.locator.publicKey);b+="Public key (hex) modulus: "+e.n.toString(16)+"<br/>";b+="exponent: "+e.e.toString(16)+"<br/>";b+="<br/>";c=e.verifyByteArray(a.rawSignatureData,d,c);2<LOG&&console.log("PUBLIC KEY n after is ");2<LOG&&console.log(e.n);2<LOG&&console.log("EXPONENT e after is ");2<LOG&&console.log(e.e);
+b=c?b+"SIGNATURE VALID":b+"SIGNATURE INVALID";b+="<br />";b+="<br />"}}return b}
+var KeyManager=function(){this.certificate="MIIBmzCCAQQCCQC32FyQa61S7jANBgkqhkiG9w0BAQUFADASMRAwDgYDVQQDEwdheGVsY2R2MB4XDTEyMDQyODIzNDQzN1oXDTEyMDUyODIzNDQzN1owEjEQMA4GA1UEAxMHYXhlbGNkdjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4X0wp9goqxuECxdULcr2IHr9Ih4Iaypg0Wy39URIup8/CLzQmdsh3RYqd55hqonu5VTTpH3iMLx6xZDVJAZ8OJi7pvXcQ2C4Re2kjL2c8SanI0RfDhlS1zJadfr1VhRPmpivcYawJ4aFuOLAi+qHFxtN7lhcGCgpW1OV60oXd58CAwEAATANBgkqhkiG9w0BAQUFAAOBgQDLOrA1fXzSrpftUB5Ro6DigX1Bjkf7F5Bkd69hSVp+jYeJFBBlsILQAfSxUZPQtD+2Yc3iCmSYNyxqu9PcufDRJlnvB7PG29+L3y9lR37tetzUV9eTscJ7rdp8Wt6AzpW32IJ/54yKNfP7S6ZIoIG+LP6EIxq6s8K1MXRt8uBJKw==";this.publicKey=
+"30819F300D06092A864886F70D010101050003818D0030818902818100E17D30A7D828AB1B840B17542DCAF6207AFD221E086B2A60D16CB7F54448BA9F3F08BCD099DB21DD162A779E61AA89EEE554D3A47DE230BC7AC590D524067C3898BBA6F5DC4360B845EDA48CBD9CF126A723445F0E1952D7325A75FAF556144F9A98AF7186B0278685B8E2C08BEA87171B4DEE585C1828295B5395EB4A17779F0203010001";this.privateKey="MIICXQIBAAKBgQDhfTCn2CirG4QLF1QtyvYgev0iHghrKmDRbLf1REi6nz8IvNCZ2yHdFip3nmGqie7lVNOkfeIwvHrFkNUkBnw4mLum9dxDYLhF7aSMvZzxJqcjRF8OGVLXMlp1+vVWFE+amK9xhrAnhoW44sCL6ocXG03uWFwYKClbU5XrShd3nwIDAQABAoGAGkv6T6jC3WmhFZYL6CdCWvlc6gysmKrhjarrLTxgavtFY6R5g2ft5BXAsCCVbUkWxkIFSKqxpVNl0gKZCNGEzPDN6mHJOQI/h0rlxNIHAuGfoAbCzALnqmyZivhJAPGijAyKuU9tczsst5+Kpn+bn7ehzHQuj7iwJonS5WbojqECQQD851K8TpW2GrRizNgG4dx6orZxAaon/Jnl8lS7soXhllQty7qG+oDfzznmdMsiznCqEABzHUUKOVGE9RWPN3aRAkEA5D/w9N55d0ibnChFJlc8cUAoaqH+w+U3oQP2Lb6AZHJpLptN4y4b/uf5d4wYU5/i/gC7SSBH3wFhh9bjRLUDLwJAVOx8vN0Kqt7myfKNbCo19jxjVSlA8TKCn1Oznl/BU1I+rC4oUaEW25DjmX6IpAR8kq7S59ThVSCQPjxqY/A08QJBAIRaF2zGPITQk3r/VumemCvLWiRK/yG0noc9dtibqHOWbCtcXtOm/xDWjq+lis2i3ssOvYrvrv0/HcDY+Dv1An0CQQCLJtMsfSg4kvG/FRY5UMhtMuwo8ovYcMXt4Xv/LWaMhndD67b2UGawQCRqr5ghRTABWdDD/HuuMBjrkPsX0861"};
+KeyManager.prototype.verify=function(a,b){var c=this.certificate,d=new X509;d.readCertPEM(c);return d.subjectPublicKeyRSA.verifyString(a,b)};KeyManager.prototype.sign=function(a){var b=this.privateKey,c=new RSAKey;c.readPrivateKeyFromPEMString(b);return c.signString(a,"sha256")};var globalKeyManager=new KeyManager,MerklePath=function(){this.index=null;this.digestList=[]},Witness=function(){this.oid=null;this.path=new MerklePath};
+function parseOID(a,b,c){for(var d,e=0,f=0;b<c;++b){var g=a[b],e=e<<7|g&127,f=f+7;g&128||(d=void 0==d?parseInt(e/40)+"."+e%40:d+("."+(31<=f?"bigint":e)),e=f=0);d+=String.fromCharCode()}return d}function parseInteger(a,b,c){for(var d=0;b<c;++b)d=d<<8|a[b];return d}
+Witness.prototype.decode=function(a){for(var b=0,c=0;b<a.length;){var d=0;if(48==a[b])0!=(a[b+1]&128)&&(d=a[b+1]&127),c++;else if(6==a[b])d=a[b+1],this.oid=parseOID(a,b+2,b+2+d);else if(2==a[b])d=a[b+1],this.path.index=parseInteger(a,b+2,b+2+d);else if(4==a[b]&&(0!=(a[b+1]&128)&&(d=a[b+1]&127),4==c)){var d=a[b+1],e=DataUtils.toHex(a.subarray(b+2,b+2+d));this.path.digestList.push(e)}b=b+2+d}};var hexcase=0,b64pad="";
+function hex_sha256_from_bytes(a){return rstr2hex(binb2rstr(binb_sha256(byteArray2binb(a),8*a.length)))}function hex_sha256(a){return rstr2hex(rstr_sha256(str2rstr_utf8(a)))}function b64_sha256(a){return rstr2b64(rstr_sha256(str2rstr_utf8(a)))}function any_sha256(a,b){return rstr2any(rstr_sha256(str2rstr_utf8(a)),b)}function hex_hmac_sha256(a,b){return rstr2hex(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}
+function b64_hmac_sha256(a,b){return rstr2b64(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)))}function any_hmac_sha256(a,b,c){return rstr2any(rstr_hmac_sha256(str2rstr_utf8(a),str2rstr_utf8(b)),c)}function sha256_vm_test(){return"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"==hex_sha256("abc").toLowerCase()}function rstr_sha256(a){return binb2rstr(binb_sha256(rstr2binb(a),8*a.length))}
 function rstr_hmac_sha256(a,b){var c=rstr2binb(a);16<c.length&&(c=binb_sha256(c,8*a.length));for(var d=Array(16),e=Array(16),f=0;16>f;f++)d[f]=c[f]^909522486,e[f]=c[f]^1549556828;c=binb_sha256(d.concat(rstr2binb(b)),512+8*b.length);return binb2rstr(binb_sha256(e.concat(c),768))}function rstr2hex(a){try{hexcase}catch(b){hexcase=0}for(var c=hexcase?"0123456789ABCDEF":"0123456789abcdef",d="",e,f=0;f<a.length;f++)e=a.charCodeAt(f),d+=c.charAt(e>>>4&15)+c.charAt(e&15);return d}
 function rstr2b64(a){try{b64pad}catch(b){b64pad=""}for(var c="",d=a.length,e=0;e<d;e+=3)for(var f=a.charCodeAt(e)<<16|(e+1<d?a.charCodeAt(e+1)<<8:0)|(e+2<d?a.charCodeAt(e+2):0),g=0;4>g;g++)c=8*e+6*g>8*a.length?c+b64pad:c+"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".charAt(f>>>6*(3-g)&63);return c}
-function rstr2any(a,b){var c=b.length,d=[],e,f,g,h,j=Array(Math.ceil(a.length/2));for(e=0;e<j.length;e++)j[e]=a.charCodeAt(2*e)<<8|a.charCodeAt(2*e+1);for(;0<j.length;){h=[];for(e=g=0;e<j.length;e++)if(g=(g<<16)+j[e],f=Math.floor(g/c),g-=f*c,0<h.length||0<f)h[h.length]=f;d[d.length]=g;j=h}c="";for(e=d.length-1;0<=e;e--)c+=b.charAt(d[e]);d=Math.ceil(8*a.length/(Math.log(b.length)/Math.log(2)));for(e=c.length;e<d;e++)c=b[0]+c;return c}
+function rstr2any(a,b){var c=b.length,d=[],e,f,g,h,i=Array(Math.ceil(a.length/2));for(e=0;e<i.length;e++)i[e]=a.charCodeAt(2*e)<<8|a.charCodeAt(2*e+1);for(;0<i.length;){h=[];for(e=g=0;e<i.length;e++)if(g=(g<<16)+i[e],f=Math.floor(g/c),g-=f*c,0<h.length||0<f)h[h.length]=f;d[d.length]=g;i=h}c="";for(e=d.length-1;0<=e;e--)c+=b.charAt(d[e]);d=Math.ceil(8*a.length/(Math.log(b.length)/Math.log(2)));for(e=c.length;e<d;e++)c=b[0]+c;return c}
 function str2rstr_utf8(a){for(var b="",c=-1,d,e;++c<a.length;)d=a.charCodeAt(c),e=c+1<a.length?a.charCodeAt(c+1):0,55296<=d&&(56319>=d&&56320<=e&&57343>=e)&&(d=65536+((d&1023)<<10)+(e&1023),c++),127>=d?b+=String.fromCharCode(d):2047>=d?b+=String.fromCharCode(192|d>>>6&31,128|d&63):65535>=d?b+=String.fromCharCode(224|d>>>12&15,128|d>>>6&63,128|d&63):2097151>=d&&(b+=String.fromCharCode(240|d>>>18&7,128|d>>>12&63,128|d>>>6&63,128|d&63));return b}
 function str2rstr_utf16le(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a.charCodeAt(c)&255,a.charCodeAt(c)>>>8&255);return b}function str2rstr_utf16be(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(a.charCodeAt(c)>>>8&255,a.charCodeAt(c)&255);return b}function rstr2binb(a){for(var b=Array(a.length>>2),c=0;c<8*a.length;c+=8)b[c>>5]|=(a.charCodeAt(c/8)&255)<<24-c%32;return b}
 function byteArray2binb(a){for(var b=Array(a.length>>2),c=0;c<8*a.length;c+=8)b[c>>5]|=(a[c/8]&255)<<24-c%32;return b}function binb2rstr(a){for(var b="",c=0;c<32*a.length;c+=8)b+=String.fromCharCode(a[c>>5]>>>24-c%32&255);return b}function sha256_S(a,b){return a>>>b|a<<32-b}function sha256_R(a,b){return a>>>b}function sha256_Ch(a,b,c){return a&b^~a&c}function sha256_Maj(a,b,c){return a&b^a&c^b&c}function sha256_Sigma0256(a){return sha256_S(a,2)^sha256_S(a,13)^sha256_S(a,22)}
@@ -157,14 +157,14 @@
 function sha256_Gamma1512(a){return sha256_S(a,19)^sha256_S(a,61)^sha256_R(a,6)}
 var sha256_K=[1116352408,1899447441,-1245643825,-373957723,961987163,1508970993,-1841331548,-1424204075,-670586216,310598401,607225278,1426881987,1925078388,-2132889090,-1680079193,-1046744716,-459576895,-272742522,264347078,604807628,770255983,1249150122,1555081692,1996064986,-1740746414,-1473132947,-1341970488,-1084653625,-958395405,-710438585,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,-2117940946,-1838011259,-1564481375,-1474664885,-1035236496,-949202525,
 -778901479,-694614492,-200395387,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,-2067236844,-1933114872,-1866530822,-1538233109,-1090935817,-965641998];function binb_sha256(a,b){var c=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225],d=Array(64);a[b>>5]|=128<<24-b%32;a[(b+64>>9<<4)+15]=b;for(var e=0;e<a.length;e+=16)processBlock_sha256(a,e,c,d);return c}
-function processBlock_sha256(a,b,c,d){var e,f,g,h,j,l,n,m,p,k,q;e=c[0];f=c[1];g=c[2];h=c[3];j=c[4];l=c[5];n=c[6];m=c[7];for(p=0;64>p;p++)d[p]=16>p?a[p+b]:safe_add(safe_add(safe_add(sha256_Gamma1256(d[p-2]),d[p-7]),sha256_Gamma0256(d[p-15])),d[p-16]),k=safe_add(safe_add(safe_add(safe_add(m,sha256_Sigma1256(j)),sha256_Ch(j,l,n)),sha256_K[p]),d[p]),q=safe_add(sha256_Sigma0256(e),sha256_Maj(e,f,g)),m=n,n=l,l=j,j=safe_add(h,k),h=g,g=f,f=e,e=safe_add(k,q);c[0]=safe_add(e,c[0]);c[1]=safe_add(f,c[1]);c[2]=
-safe_add(g,c[2]);c[3]=safe_add(h,c[3]);c[4]=safe_add(j,c[4]);c[5]=safe_add(l,c[5]);c[6]=safe_add(n,c[6]);c[7]=safe_add(m,c[7])}function safe_add(a,b){var c=(a&65535)+(b&65535);return(a>>16)+(b>>16)+(c>>16)<<16|c&65535}var Sha256=function(){this.W=Array(64);this.hash=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225];this.nTotalBytes=0;this.buffer=new Uint8Array(64);this.nBufferBytes=0};
+function processBlock_sha256(a,b,c,d){var e,f,g,h,i,k,m,l,n,j,p;e=c[0];f=c[1];g=c[2];h=c[3];i=c[4];k=c[5];m=c[6];l=c[7];for(n=0;64>n;n++)d[n]=16>n?a[n+b]:safe_add(safe_add(safe_add(sha256_Gamma1256(d[n-2]),d[n-7]),sha256_Gamma0256(d[n-15])),d[n-16]),j=safe_add(safe_add(safe_add(safe_add(l,sha256_Sigma1256(i)),sha256_Ch(i,k,m)),sha256_K[n]),d[n]),p=safe_add(sha256_Sigma0256(e),sha256_Maj(e,f,g)),l=m,m=k,k=i,i=safe_add(h,j),h=g,g=f,f=e,e=safe_add(j,p);c[0]=safe_add(e,c[0]);c[1]=safe_add(f,c[1]);c[2]=
+safe_add(g,c[2]);c[3]=safe_add(h,c[3]);c[4]=safe_add(i,c[4]);c[5]=safe_add(k,c[5]);c[6]=safe_add(m,c[6]);c[7]=safe_add(l,c[7])}function safe_add(a,b){var c=(a&65535)+(b&65535);return(a>>16)+(b>>16)+(c>>16)<<16|c&65535}var Sha256=function(){this.W=Array(64);this.hash=[1779033703,-1150833019,1013904242,-1521486534,1359893119,-1694144372,528734635,1541459225];this.nTotalBytes=0;this.buffer=new Uint8Array(64);this.nBufferBytes=0};
 Sha256.prototype.update=function(a){this.nTotalBytes+=a.length;if(0<this.nBufferBytes){var b=this.buffer.length-this.nBufferBytes;if(a.length<b){this.buffer.set(a,this.nBufferBytes);this.nBufferBytes+=a.length;return}this.buffer.set(a.subarray(0,b),this.nBufferBytes);processBlock_sha256(byteArray2binb(this.buffer),0,this.hash,this.W);this.nBufferBytes=0;a=a.subarray(b,a.length);if(0==a.length)return}b=a.length>>6;if(0<b){for(var b=64*b,c=byteArray2binb(a.subarray(0,b)),d=0;d<c.length;d+=16)processBlock_sha256(c,
 d,this.hash,this.W);a=a.subarray(b,a.length)}0<a.length&&(this.buffer.set(a),this.nBufferBytes=a.length)};Sha256.prototype.finalize=function(){var a=byteArray2binb(this.buffer.subarray(0,this.nBufferBytes)),b=8*this.nBufferBytes;a[b>>5]|=128<<24-b%32;a[(b+64>>9<<4)+15]=8*this.nTotalBytes;for(b=0;b<a.length;b+=16)processBlock_sha256(a,b,this.hash,this.W);return Sha256.binb2Uint8Array(this.hash)};
 Sha256.binb2Uint8Array=function(a){for(var b=new Uint8Array(4*a.length),c=0,d=0;d<32*a.length;d+=8)b[c++]=a[d>>5]>>>24-d%32&255;return b};var b64map="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",b64pad="=";
 function hex2b64(a){var b,c,d="";for(b=0;b+3<=a.length;b+=3)c=parseInt(a.substring(b,b+3),16),d+=b64map.charAt(c>>6)+b64map.charAt(c&63);b+1==a.length?(c=parseInt(a.substring(b,b+1),16),d+=b64map.charAt(c<<2)):b+2==a.length&&(c=parseInt(a.substring(b,b+2),16),d+=b64map.charAt(c>>2)+b64map.charAt((c&3)<<4));for(;0<(d.length&3);)d+=b64pad;return d}
-function b64tohex(a){var b="",c,d=0,e;for(c=0;c<a.length&&a.charAt(c)!=b64pad;++c)v=b64map.indexOf(a.charAt(c)),0>v||(0==d?(b+=int2char(v>>2),e=v&3,d=1):1==d?(b+=int2char(e<<2|v>>4),e=v&15,d=2):2==d?(b+=int2char(e),b+=int2char(v>>2),e=v&3,d=3):(b+=int2char(e<<2|v>>4),b+=int2char(v&15),d=0));1==d&&(b+=int2char(e<<2));return b}function b64toBA(a){var a=b64tohex(a),b,c=[];for(b=0;2*b<a.length;++b)c[b]=parseInt(a.substring(2*b,2*b+2),16);return c}function parseBigInt(a,b){return new BigInteger(a,b)}
-function linebrk(a,b){for(var c="",d=0;d+b<a.length;)c+=a.substring(d,d+b)+"\n",d+=b;return c+a.substring(d,a.length)}function byte2Hex(a){return 16>a?"0"+a.toString(16):a.toString(16)}
+function b64tohex(a){var b="",c,d=0,e;for(c=0;c<a.length&&a.charAt(c)!=b64pad;++c){var f=b64map.indexOf(a.charAt(c));0>f||(0==d?(b+=int2char(f>>2),e=f&3,d=1):1==d?(b+=int2char(e<<2|f>>4),e=f&15,d=2):2==d?(b+=int2char(e),b+=int2char(f>>2),e=f&3,d=3):(b+=int2char(e<<2|f>>4),b+=int2char(f&15),d=0))}1==d&&(b+=int2char(e<<2));return b}function b64toBA(a){var a=b64tohex(a),b,c=[];for(b=0;2*b<a.length;++b)c[b]=parseInt(a.substring(2*b,2*b+2),16);return c}
+function parseBigInt(a,b){return new BigInteger(a,b)}function linebrk(a,b){for(var c="",d=0;d+b<a.length;)c+=a.substring(d,d+b)+"\n",d+=b;return c+a.substring(d,a.length)}function byte2Hex(a){return 16>a?"0"+a.toString(16):a.toString(16)}
 function pkcs1pad2(a,b){if(b<a.length+11)return alert("Message too long for RSA"),null;for(var c=[],d=a.length-1;0<=d&&0<b;){var e=a.charCodeAt(d--);128>e?c[--b]=e:127<e&&2048>e?(c[--b]=e&63|128,c[--b]=e>>6|192):(c[--b]=e&63|128,c[--b]=e>>6&63|128,c[--b]=e>>12|224)}c[--b]=0;d=new SecureRandom;for(e=[];2<b;){for(e[0]=0;0==e[0];)d.nextBytes(e);c[--b]=e[0]}c[--b]=2;c[--b]=0;return new BigInteger(c)}function RSAKey(){this.n=null;this.e=0;this.coeff=this.dmq1=this.dmp1=this.q=this.p=this.d=null}
 function RSASetPublic(a,b){null!=a&&null!=b&&0<a.length&&0<b.length?(this.n=parseBigInt(a,16),this.e=parseInt(b,16)):alert("Invalid RSA public key")}function RSADoPublic(a){return a.modPowInt(this.e,this.n)}function RSAEncrypt(a){a=pkcs1pad2(a,this.n.bitLength()+7>>3);if(null==a)return null;a=this.doPublic(a);if(null==a)return null;a=a.toString(16);return 0==(a.length&1)?a:"0"+a}RSAKey.prototype.doPublic=RSADoPublic;RSAKey.prototype.setPublic=RSASetPublic;RSAKey.prototype.encrypt=RSAEncrypt;
 function pkcs1unpad2(a,b){for(var c=a.toByteArray(),d=0;d<c.length&&0==c[d];)++d;if(c.length-d!=b-1||2!=c[d])return null;for(++d;0!=c[d];)if(++d>=c.length)return null;for(var e="";++d<c.length;){var f=c[d]&255;128>f?e+=String.fromCharCode(f):191<f&&224>f?(e+=String.fromCharCode((f&31)<<6|c[d+1]&63),++d):(e+=String.fromCharCode((f&15)<<12|(c[d+1]&63)<<6|c[d+2]&63),d+=2)}return e}
@@ -173,8 +173,8 @@
 function RSAGenerate(a,b){var c=new SecureRandom,d=a>>1;this.e=parseInt(b,16);for(var e=new BigInteger(b,16);;){for(;!(this.p=new BigInteger(a-d,1,c),0==this.p.subtract(BigInteger.ONE).gcd(e).compareTo(BigInteger.ONE)&&this.p.isProbablePrime(10)););for(;!(this.q=new BigInteger(d,1,c),0==this.q.subtract(BigInteger.ONE).gcd(e).compareTo(BigInteger.ONE)&&this.q.isProbablePrime(10)););if(0>=this.p.compareTo(this.q)){var f=this.p;this.p=this.q;this.q=f}var f=this.p.subtract(BigInteger.ONE),g=this.q.subtract(BigInteger.ONE),
 h=f.multiply(g);if(0==h.gcd(e).compareTo(BigInteger.ONE)){this.n=this.p.multiply(this.q);this.d=e.modInverse(h);this.dmp1=this.d.mod(f);this.dmq1=this.d.mod(g);this.coeff=this.q.modInverse(this.p);break}}}function RSADoPrivate(a){if(null==this.p||null==this.q)return a.modPow(this.d,this.n);for(var b=a.mod(this.p).modPow(this.dmp1,this.p),a=a.mod(this.q).modPow(this.dmq1,this.q);0>b.compareTo(a);)b=b.add(this.p);return b.subtract(a).multiply(this.coeff).mod(this.p).multiply(this.q).add(a)}
 function RSADecrypt(a){a=parseBigInt(a,16);a=this.doPrivate(a);return null==a?null:pkcs1unpad2(a,this.n.bitLength()+7>>3)}RSAKey.prototype.doPrivate=RSADoPrivate;RSAKey.prototype.setPrivate=RSASetPrivate;RSAKey.prototype.setPrivateEx=RSASetPrivateEx;RSAKey.prototype.generate=RSAGenerate;RSAKey.prototype.decrypt=RSADecrypt;function _rsapem_pemToBase64(a){a=a.replace("-----BEGIN RSA PRIVATE KEY-----","");a=a.replace("-----END RSA PRIVATE KEY-----","");return a=a.replace(/[ \n]+/g,"")}
-function _rsapem_getPosArrayOfChildrenFromHex(a){var b=[],c=ASN1HEX.getStartPosOfV_AtObj(a,0),d=ASN1HEX.getPosOfNextSibling_AtObj(a,c),e=ASN1HEX.getPosOfNextSibling_AtObj(a,d),f=ASN1HEX.getPosOfNextSibling_AtObj(a,e),g=ASN1HEX.getPosOfNextSibling_AtObj(a,f),h=ASN1HEX.getPosOfNextSibling_AtObj(a,g),j=ASN1HEX.getPosOfNextSibling_AtObj(a,h),l=ASN1HEX.getPosOfNextSibling_AtObj(a,j),a=ASN1HEX.getPosOfNextSibling_AtObj(a,l);b.push(c,d,e,f,g,h,j,l,a);return b}
-function _rsapem_getHexValueArrayOfChildrenFromHex(a){var b=_rsapem_getPosArrayOfChildrenFromHex(a),c=ASN1HEX.getHexOfV_AtObj(a,b[0]),d=ASN1HEX.getHexOfV_AtObj(a,b[1]),e=ASN1HEX.getHexOfV_AtObj(a,b[2]),f=ASN1HEX.getHexOfV_AtObj(a,b[3]),g=ASN1HEX.getHexOfV_AtObj(a,b[4]),h=ASN1HEX.getHexOfV_AtObj(a,b[5]),j=ASN1HEX.getHexOfV_AtObj(a,b[6]),l=ASN1HEX.getHexOfV_AtObj(a,b[7]),a=ASN1HEX.getHexOfV_AtObj(a,b[8]),b=[];b.push(c,d,e,f,g,h,j,l,a);return b}
+function _rsapem_getPosArrayOfChildrenFromHex(a){var b=[],c=ASN1HEX.getStartPosOfV_AtObj(a,0),d=ASN1HEX.getPosOfNextSibling_AtObj(a,c),e=ASN1HEX.getPosOfNextSibling_AtObj(a,d),f=ASN1HEX.getPosOfNextSibling_AtObj(a,e),g=ASN1HEX.getPosOfNextSibling_AtObj(a,f),h=ASN1HEX.getPosOfNextSibling_AtObj(a,g),i=ASN1HEX.getPosOfNextSibling_AtObj(a,h),k=ASN1HEX.getPosOfNextSibling_AtObj(a,i),a=ASN1HEX.getPosOfNextSibling_AtObj(a,k);b.push(c,d,e,f,g,h,i,k,a);return b}
+function _rsapem_getHexValueArrayOfChildrenFromHex(a){var b=_rsapem_getPosArrayOfChildrenFromHex(a),c=ASN1HEX.getHexOfV_AtObj(a,b[0]),d=ASN1HEX.getHexOfV_AtObj(a,b[1]),e=ASN1HEX.getHexOfV_AtObj(a,b[2]),f=ASN1HEX.getHexOfV_AtObj(a,b[3]),g=ASN1HEX.getHexOfV_AtObj(a,b[4]),h=ASN1HEX.getHexOfV_AtObj(a,b[5]),i=ASN1HEX.getHexOfV_AtObj(a,b[6]),k=ASN1HEX.getHexOfV_AtObj(a,b[7]),a=ASN1HEX.getHexOfV_AtObj(a,b[8]),b=[];b.push(c,d,e,f,g,h,i,k,a);return b}
 function _rsapem_readPrivateKeyFromPEMString(a){a=_rsapem_pemToBase64(a);a=b64tohex(a);a=_rsapem_getHexValueArrayOfChildrenFromHex(a);this.setPrivateEx(a[1],a[2],a[3],a[4],a[5],a[6],a[7],a[8])}RSAKey.prototype.readPrivateKeyFromPEMString=_rsapem_readPrivateKeyFromPEMString;var _RSASIGN_DIHEAD=[];_RSASIGN_DIHEAD.sha1="3021300906052b0e03021a05000414";_RSASIGN_DIHEAD.sha256="3031300d060960864801650304020105000420";_RSASIGN_DIHEAD.sha384="3041300d060960864801650304020205000430";
 _RSASIGN_DIHEAD.sha512="3051300d060960864801650304020305000440";_RSASIGN_DIHEAD.md2="3020300c06082a864886f70d020205000410";_RSASIGN_DIHEAD.md5="3020300c06082a864886f70d020505000410";_RSASIGN_DIHEAD.ripemd160="3021300906052b2403020105000414";var _RSASIGN_HASHHEXFUNC=[];_RSASIGN_HASHHEXFUNC.sha1=function(a){return hex_sha1(a)};_RSASIGN_HASHHEXFUNC.sha256=function(a){return hex_sha256(a)};_RSASIGN_HASHHEXFUNC.sha512=function(a){return hex_sha512(a)};_RSASIGN_HASHHEXFUNC.md5=function(a){return hex_md5(a)};
 _RSASIGN_HASHHEXFUNC.ripemd160=function(a){return hex_rmd160(a)};var _RSASIGN_HASHBYTEFUNC=[];_RSASIGN_HASHBYTEFUNC.sha256=function(a){return hex_sha256_from_bytes(a)};var _RE_HEXDECONLY=RegExp("");_RE_HEXDECONLY.compile("[^0-9a-f]","gi");function _rsasign_getHexPaddedDigestInfoForString(a,b,c){for(var b=b/4,a=(0,_RSASIGN_HASHHEXFUNC[c])(a),c="00"+_RSASIGN_DIHEAD[c]+a,a="",b=b-4-c.length,d=0;d<b;d+=2)a+="ff";return sPaddedMessageHex="0001"+a+c}
@@ -185,17 +185,27 @@
 function _rsasign_getAlgNameAndHashFromHexDisgestInfo(a){for(var b in _RSASIGN_DIHEAD){var c=_RSASIGN_DIHEAD[b],d=c.length;if(a.substring(0,d)==c)return[b,a.substring(d)]}return[]}function _rsasign_verifySignatureWithArgs(a,b,c,d){b=_rsasign_getHexDigestInfoFromSig(b,c,d);c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(b);if(0==c.length)return!1;b=c[1];a=(0,_RSASIGN_HASHHEXFUNC[c[0]])(a);return b==a}
 function _rsasign_verifyHexSignatureForMessage(a,b){var c=parseBigInt(a,16);return _rsasign_verifySignatureWithArgs(b,c,this.n.toString(16),this.e.toString(16))}
 function _rsasign_verifyString(a,b){b=b.replace(_RE_HEXDECONLY,"");3<LOG&&console.log("n is "+this.n);3<LOG&&console.log("e is "+this.e);if(b.length!=this.n.bitLength()/4)return 0;var b=b.replace(/[ \n]+/g,""),c=parseBigInt(b,16),c=this.doPublic(c).toString(16).replace(/^1f+00/,""),d=_rsasign_getAlgNameAndHashFromHexDisgestInfo(c);if(0==d.length)return!1;c=d[1];d=(0,_RSASIGN_HASHHEXFUNC[d[0]])(a);return c==d}
-function _rsasign_verifyByteArray(a,b){b=b.replace(_RE_HEXDECONLY,"");3<LOG&&console.log("n is "+this.n);3<LOG&&console.log("e is "+this.e);if(b.length!=this.n.bitLength()/4)return 0;var b=b.replace(/[ \n]+/g,""),c=parseBigInt(b,16),c=this.doPublic(c).toString(16).replace(/^1f+00/,""),d=_rsasign_getAlgNameAndHashFromHexDisgestInfo(c);if(0==d.length)return!1;c=d[1];d=(0,_RSASIGN_HASHBYTEFUNC[d[0]])(a);return c==d}RSAKey.prototype.signString=_rsasign_signString;RSAKey.prototype.signByteArray=_rsasign_signByteArray;
-RSAKey.prototype.signByteArrayWithSHA256=_rsasign_signByteArrayWithSHA256;RSAKey.prototype.signStringWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signStringWithSHA256=_rsasign_signStringWithSHA256;RSAKey.prototype.sign=_rsasign_signString;RSAKey.prototype.signWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signWithSHA256=_rsasign_signStringWithSHA256;RSAKey.prototype.verifyByteArray=_rsasign_verifyByteArray;RSAKey.prototype.verifyString=_rsasign_verifyString;
-RSAKey.prototype.verifyHexSignatureForMessage=_rsasign_verifyHexSignatureForMessage;RSAKey.prototype.verify=_rsasign_verifyString;RSAKey.prototype.verifyHexSignatureForByteArrayMessage=_rsasign_verifyHexSignatureForMessage;function _asnhex_getByteLengthOfL_AtObj(a,b){if("8"!=a.substring(b+2,b+3))return 1;var c=parseInt(a.substring(b+3,b+4));return 0==c?-1:0<c&&10>c?c+1:-2}function _asnhex_getHexOfL_AtObj(a,b){var c=_asnhex_getByteLengthOfL_AtObj(a,b);return 1>c?"":a.substring(b+2,b+2+2*c)}
-function _asnhex_getIntOfL_AtObj(a,b){var c=_asnhex_getHexOfL_AtObj(a,b);return""==c?-1:(8>parseInt(c.substring(0,1))?parseBigInt(c,16):parseBigInt(c.substring(2),16)).intValue()}function _asnhex_getStartPosOfV_AtObj(a,b){var c=_asnhex_getByteLengthOfL_AtObj(a,b);return 0>c?c:b+2*(c+1)}function _asnhex_getHexOfV_AtObj(a,b){var c=_asnhex_getStartPosOfV_AtObj(a,b),d=_asnhex_getIntOfL_AtObj(a,b);return a.substring(c,c+2*d)}
-function _asnhex_getHexOfTLV_AtObj(a,b){var c=a.substr(b,2),d=_asnhex_getHexOfL_AtObj(a,b),e=_asnhex_getHexOfV_AtObj(a,b);return c+d+e}function _asnhex_getPosOfNextSibling_AtObj(a,b){var c=_asnhex_getStartPosOfV_AtObj(a,b),d=_asnhex_getIntOfL_AtObj(a,b);return c+2*d}
-function _asnhex_getPosArrayOfChildren_AtObj(a,b){var c=[],d=_asnhex_getStartPosOfV_AtObj(a,b);c.push(d);for(var e=_asnhex_getIntOfL_AtObj(a,b),f=d,g=0;;){f=_asnhex_getPosOfNextSibling_AtObj(a,f);if(null==f||f-d>=2*e)break;if(200<=g)break;c.push(f);g++}return c}function _asnhex_getNthChildIndex_AtObj(a,b,c){return _asnhex_getPosArrayOfChildren_AtObj(a,b)[c]}
+function _rsasign_verifyByteArray(a,b,c){c=c.replace(_RE_HEXDECONLY,"");3<LOG&&console.log("n is "+this.n);3<LOG&&console.log("e is "+this.e);if(c.length!=this.n.bitLength()/4)return 0;c=c.replace(/[ \n]+/g,"");c=parseBigInt(c,16);c=this.doPublic(c).toString(16).replace(/^1f+00/,"");c=_rsasign_getAlgNameAndHashFromHexDisgestInfo(c);if(0==c.length)return!1;var d=c[0],c=c[1],e=null;if(null==b)e=(0,_RSASIGN_HASHBYTEFUNC[d])(a);else{a=hex_sha256_from_bytes(a);d=b.path.index;for(e=b.path.digestList.length-
+1;0<=e;e--)var f="",f=0==d%2?a+b.path.digestList[e]:b.path.digestList[e]+a,a=hex_sha256_from_bytes(DataUtils.toNumbers(f)),d=Math.floor(d/2);e=hex_sha256_from_bytes(DataUtils.toNumbers(a))}return c==e}RSAKey.prototype.signString=_rsasign_signString;RSAKey.prototype.signByteArray=_rsasign_signByteArray;RSAKey.prototype.signByteArrayWithSHA256=_rsasign_signByteArrayWithSHA256;RSAKey.prototype.signStringWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signStringWithSHA256=_rsasign_signStringWithSHA256;
+RSAKey.prototype.sign=_rsasign_signString;RSAKey.prototype.signWithSHA1=_rsasign_signStringWithSHA1;RSAKey.prototype.signWithSHA256=_rsasign_signStringWithSHA256;RSAKey.prototype.verifyByteArray=_rsasign_verifyByteArray;RSAKey.prototype.verifyString=_rsasign_verifyString;RSAKey.prototype.verifyHexSignatureForMessage=_rsasign_verifyHexSignatureForMessage;RSAKey.prototype.verify=_rsasign_verifyString;RSAKey.prototype.verifyHexSignatureForByteArrayMessage=_rsasign_verifyHexSignatureForMessage;
+function _asnhex_getByteLengthOfL_AtObj(a,b){if("8"!=a.substring(b+2,b+3))return 1;var c=parseInt(a.substring(b+3,b+4));return 0==c?-1:0<c&&10>c?c+1:-2}function _asnhex_getHexOfL_AtObj(a,b){var c=_asnhex_getByteLengthOfL_AtObj(a,b);return 1>c?"":a.substring(b+2,b+2+2*c)}function _asnhex_getIntOfL_AtObj(a,b){var c=_asnhex_getHexOfL_AtObj(a,b);return""==c?-1:(8>parseInt(c.substring(0,1))?parseBigInt(c,16):parseBigInt(c.substring(2),16)).intValue()}
+function _asnhex_getStartPosOfV_AtObj(a,b){var c=_asnhex_getByteLengthOfL_AtObj(a,b);return 0>c?c:b+2*(c+1)}function _asnhex_getHexOfV_AtObj(a,b){var c=_asnhex_getStartPosOfV_AtObj(a,b),d=_asnhex_getIntOfL_AtObj(a,b);return a.substring(c,c+2*d)}function _asnhex_getHexOfTLV_AtObj(a,b){var c=a.substr(b,2),d=_asnhex_getHexOfL_AtObj(a,b),e=_asnhex_getHexOfV_AtObj(a,b);return c+d+e}
+function _asnhex_getPosOfNextSibling_AtObj(a,b){var c=_asnhex_getStartPosOfV_AtObj(a,b),d=_asnhex_getIntOfL_AtObj(a,b);return c+2*d}function _asnhex_getPosArrayOfChildren_AtObj(a,b){var c=[],d=_asnhex_getStartPosOfV_AtObj(a,b);c.push(d);for(var e=_asnhex_getIntOfL_AtObj(a,b),f=d,g=0;;){f=_asnhex_getPosOfNextSibling_AtObj(a,f);if(null==f||f-d>=2*e)break;if(200<=g)break;c.push(f);g++}return c}function _asnhex_getNthChildIndex_AtObj(a,b,c){return _asnhex_getPosArrayOfChildren_AtObj(a,b)[c]}
 function _asnhex_getDecendantIndexByNthList(a,b,c){if(0==c.length)return b;var d=c.shift(),b=_asnhex_getPosArrayOfChildren_AtObj(a,b);return _asnhex_getDecendantIndexByNthList(a,b[d],c)}function _asnhex_getDecendantHexTLVByNthList(a,b,c){b=_asnhex_getDecendantIndexByNthList(a,b,c);return _asnhex_getHexOfTLV_AtObj(a,b)}function _asnhex_getDecendantHexVByNthList(a,b,c){b=_asnhex_getDecendantIndexByNthList(a,b,c);return _asnhex_getHexOfV_AtObj(a,b)}function ASN1HEX(){return ASN1HEX}
 ASN1HEX.getByteLengthOfL_AtObj=_asnhex_getByteLengthOfL_AtObj;ASN1HEX.getHexOfL_AtObj=_asnhex_getHexOfL_AtObj;ASN1HEX.getIntOfL_AtObj=_asnhex_getIntOfL_AtObj;ASN1HEX.getStartPosOfV_AtObj=_asnhex_getStartPosOfV_AtObj;ASN1HEX.getHexOfV_AtObj=_asnhex_getHexOfV_AtObj;ASN1HEX.getHexOfTLV_AtObj=_asnhex_getHexOfTLV_AtObj;ASN1HEX.getPosOfNextSibling_AtObj=_asnhex_getPosOfNextSibling_AtObj;ASN1HEX.getPosArrayOfChildren_AtObj=_asnhex_getPosArrayOfChildren_AtObj;ASN1HEX.getNthChildIndex_AtObj=_asnhex_getNthChildIndex_AtObj;
-ASN1HEX.getDecendantIndexByNthList=_asnhex_getDecendantIndexByNthList;ASN1HEX.getDecendantHexVByNthList=_asnhex_getDecendantHexVByNthList;ASN1HEX.getDecendantHexTLVByNthList=_asnhex_getDecendantHexTLVByNthList;var dbits,canary=0xdeadbeefcafe,j_lm=15715070==(canary&16777215);function BigInteger(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function nbi(){return new BigInteger(null)}
-function am1(a,b,c,d,e,f){for(;0<=--f;){var g=b*this[a++]+c[d]+e,e=Math.floor(g/67108864);c[d++]=g&67108863}return e}function am2(a,b,c,d,e,f){for(var g=b&32767,b=b>>15;0<=--f;){var h=this[a]&32767,j=this[a++]>>15,l=b*h+j*g,h=g*h+((l&32767)<<15)+c[d]+(e&1073741823),e=(h>>>30)+(l>>>15)+b*j+(e>>>30);c[d++]=h&1073741823}return e}
-function am3(a,b,c,d,e,f){for(var g=b&16383,b=b>>14;0<=--f;){var h=this[a]&16383,j=this[a++]>>14,l=b*h+j*g,h=g*h+((l&16383)<<14)+c[d]+e,e=(h>>28)+(l>>14)+b*j;c[d++]=h&268435455}return e}j_lm&&"Microsoft Internet Explorer"==navigator.appName?(BigInteger.prototype.am=am2,dbits=30):j_lm&&"Netscape"!=navigator.appName?(BigInteger.prototype.am=am1,dbits=26):(BigInteger.prototype.am=am3,dbits=28);BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<<dbits)-1;BigInteger.prototype.DV=1<<dbits;
+ASN1HEX.getDecendantIndexByNthList=_asnhex_getDecendantIndexByNthList;ASN1HEX.getDecendantHexVByNthList=_asnhex_getDecendantHexVByNthList;ASN1HEX.getDecendantHexTLVByNthList=_asnhex_getDecendantHexTLVByNthList;function _x509_pemToBase64(a){a=a.replace("-----BEGIN CERTIFICATE-----","");a=a.replace("-----END CERTIFICATE-----","");return a=a.replace(/[ \n]+/g,"")}function _x509_pemToHex(a){a=_x509_pemToBase64(a);return b64tohex(a)}
+function _x509_getHexTbsCertificateFromCert(a){return ASN1HEX.getStartPosOfV_AtObj(a,0)}function _x509_getSubjectPublicKeyInfoPosFromCertHex(a){var b=ASN1HEX.getStartPosOfV_AtObj(a,0),b=ASN1HEX.getPosArrayOfChildren_AtObj(a,b);return 1>b.length?-1:"a003020102"==a.substring(b[0],b[0]+10)?6>b.length?-1:b[6]:5>b.length?-1:b[5]}
+function _x509_getSubjectPublicKeyPosFromCertHex(a,b){null==b&&(b=_x509_getSubjectPublicKeyInfoPosFromCertHex(a));if(-1==b)return-1;var c=ASN1HEX.getPosArrayOfChildren_AtObj(a,b);if(2!=c.length)return-1;c=c[1];if("03"!=a.substring(c,c+2))return-1;c=ASN1HEX.getStartPosOfV_AtObj(a,c);return"00"!=a.substring(c,c+2)?-1:c+2}
+function _x509_getPublicKeyHexArrayFromCertHex(a,b){null==b&&(b=_x509_getSubjectPublicKeyPosFromCertHex(a));var c=ASN1HEX.getPosArrayOfChildren_AtObj(a,b);4<LOG&&(console.log("a is now"),console.log(c));if(2>c.length)return[];var d=ASN1HEX.getHexOfV_AtObj(a,c[0]),c=ASN1HEX.getHexOfV_AtObj(a,c[1]);return null!=d&&null!=c?[d,c]:[]}function _x509_getPublicKeyHexArrayFromCertPEM(a){a=_x509_pemToHex(a);return _x509_getPublicKeyHexArrayFromCertHex(a)}
+function _x509_getSerialNumberHex(){return ASN1HEX.getDecendantHexVByNthList(this.hex,0,[0,1])}function _x509_getIssuerHex(){return ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,3])}function _x509_getIssuerString(){return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,3]))}function _x509_getSubjectHex(){return ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,5])}function _x509_getSubjectString(){return _x509_hex2dn(ASN1HEX.getDecendantHexTLVByNthList(this.hex,0,[0,5]))}
+function _x509_getNotBefore(){var a=ASN1HEX.getDecendantHexVByNthList(this.hex,0,[0,4,0]),a=a.replace(/(..)/g,"%$1");return a=decodeURIComponent(a)}function _x509_getNotAfter(){var a=ASN1HEX.getDecendantHexVByNthList(this.hex,0,[0,4,1]),a=a.replace(/(..)/g,"%$1");return a=decodeURIComponent(a)}_x509_DN_ATTRHEX={"0603550406":"C","060355040a":"O","060355040b":"OU","0603550403":"CN","0603550405":"SN","0603550408":"ST","0603550407":"L"};
+function _x509_hex2dn(a){for(var b="",c=ASN1HEX.getPosArrayOfChildren_AtObj(a,0),d=0;d<c.length;d++)var e=ASN1HEX.getHexOfTLV_AtObj(a,c[d]),b=b+"/"+_x509_hex2rdn(e);return b}function _x509_hex2rdn(a){var b=ASN1HEX.getDecendantHexTLVByNthList(a,0,[0,0]),c=ASN1HEX.getDecendantHexVByNthList(a,0,[0,1]),a="";try{a=_x509_DN_ATTRHEX[b]}catch(d){a=b}c=c.replace(/(..)/g,"%$1");b=decodeURIComponent(c);return a+"="+b}
+function _x509_readCertPEM(a){var a=_x509_pemToHex(a),b=_x509_getPublicKeyHexArrayFromCertHex(a);4<LOG&&(console.log("HEX VALUE IS "+a),console.log("type of a"+typeof b),console.log("a VALUE IS "),console.log(b),console.log("a[0] VALUE IS "+b[0]),console.log("a[1] VALUE IS "+b[1]));var c=new RSAKey;c.setPublic(b[0],b[1]);this.subjectPublicKeyRSA=c;this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1];this.hex=a}
+function _x509_readCertHex(a){var a=a.toLowerCase(),b=_x509_getPublicKeyHexArrayFromCertHex(a),c=new RSAKey;c.setPublic(b[0],b[1]);this.subjectPublicKeyRSA=c;this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1];this.hex=a}function _x509_readCertPEMWithoutRSAInit(a){var a=_x509_pemToHex(a),b=_x509_getPublicKeyHexArrayFromCertHex(a);this.subjectPublicKeyRSA.setPublic(b[0],b[1]);this.subjectPublicKeyRSA_hN=b[0];this.subjectPublicKeyRSA_hE=b[1];this.hex=a}
+function X509(){this.hex=this.subjectPublicKeyRSA_hE=this.subjectPublicKeyRSA_hN=this.subjectPublicKeyRSA=null}X509.prototype.readCertPEM=_x509_readCertPEM;X509.prototype.readCertHex=_x509_readCertHex;X509.prototype.readCertPEMWithoutRSAInit=_x509_readCertPEMWithoutRSAInit;X509.prototype.getSerialNumberHex=_x509_getSerialNumberHex;X509.prototype.getIssuerHex=_x509_getIssuerHex;X509.prototype.getSubjectHex=_x509_getSubjectHex;X509.prototype.getIssuerString=_x509_getIssuerString;
+X509.prototype.getSubjectString=_x509_getSubjectString;X509.prototype.getNotBefore=_x509_getNotBefore;X509.prototype.getNotAfter=_x509_getNotAfter;var dbits,canary=0xdeadbeefcafe,j_lm=15715070==(canary&16777215);function BigInteger(a,b,c){null!=a&&("number"==typeof a?this.fromNumber(a,b,c):null==b&&"string"!=typeof a?this.fromString(a,256):this.fromString(a,b))}function nbi(){return new BigInteger(null)}
+function am1(a,b,c,d,e,f){for(;0<=--f;){var g=b*this[a++]+c[d]+e,e=Math.floor(g/67108864);c[d++]=g&67108863}return e}function am2(a,b,c,d,e,f){for(var g=b&32767,b=b>>15;0<=--f;){var h=this[a]&32767,i=this[a++]>>15,k=b*h+i*g,h=g*h+((k&32767)<<15)+c[d]+(e&1073741823),e=(h>>>30)+(k>>>15)+b*i+(e>>>30);c[d++]=h&1073741823}return e}
+function am3(a,b,c,d,e,f){for(var g=b&16383,b=b>>14;0<=--f;){var h=this[a]&16383,i=this[a++]>>14,k=b*h+i*g,h=g*h+((k&16383)<<14)+c[d]+e,e=(h>>28)+(k>>14)+b*i;c[d++]=h&268435455}return e}j_lm&&"Microsoft Internet Explorer"==navigator.appName?(BigInteger.prototype.am=am2,dbits=30):j_lm&&"Netscape"!=navigator.appName?(BigInteger.prototype.am=am1,dbits=26):(BigInteger.prototype.am=am3,dbits=28);BigInteger.prototype.DB=dbits;BigInteger.prototype.DM=(1<<dbits)-1;BigInteger.prototype.DV=1<<dbits;
 var BI_FP=52;BigInteger.prototype.FV=Math.pow(2,BI_FP);BigInteger.prototype.F1=BI_FP-dbits;BigInteger.prototype.F2=2*dbits-BI_FP;var BI_RM="0123456789abcdefghijklmnopqrstuvwxyz",BI_RC=[],rr,vv;rr=48;for(vv=0;9>=vv;++vv)BI_RC[rr++]=vv;rr=97;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;rr=65;for(vv=10;36>vv;++vv)BI_RC[rr++]=vv;function int2char(a){return BI_RM.charAt(a)}function intAt(a,b){var c=BI_RC[a.charCodeAt(b)];return null==c?-1:c}
 function bnpCopyTo(a){for(var b=this.t-1;0<=b;--b)a[b]=this[b];a.t=this.t;a.s=this.s}function bnpFromInt(a){this.t=1;this.s=0>a?-1:0;0<a?this[0]=a:-1>a?this[0]=a+DV:this.t=0}function nbv(a){var b=nbi();b.fromInt(a);return b}
 function bnpFromString(a,b){var c;if(16==b)c=4;else if(8==b)c=3;else if(256==b)c=8;else if(2==b)c=1;else if(32==b)c=5;else if(4==b)c=2;else{this.fromRadix(a,b);return}this.s=this.t=0;for(var d=a.length,e=!1,f=0;0<=--d;){var g=8==c?a[d]&255:intAt(a,d);0>g?"-"==a.charAt(d)&&(e=!0):(e=!1,0==f?this[this.t++]=g:f+c>this.DB?(this[this.t-1]|=(g&(1<<this.DB-f)-1)<<f,this[this.t++]=g>>this.DB-f):this[this.t-1]|=g<<f,f+=c,f>=this.DB&&(f-=this.DB))}8==c&&0!=(a[0]&128)&&(this.s=-1,0<f&&(this[this.t-1]|=(1<<this.DB-
@@ -207,8 +217,8 @@
 function bnpRShiftTo(a,b){b.s=this.s;var c=Math.floor(a/this.DB);if(c>=this.t)b.t=0;else{var d=a%this.DB,e=this.DB-d,f=(1<<d)-1;b[0]=this[c]>>d;for(var g=c+1;g<this.t;++g)b[g-c-1]|=(this[g]&f)<<e,b[g-c]=this[g]>>d;0<d&&(b[this.t-c-1]|=(this.s&f)<<e);b.t=this.t-c;b.clamp()}}
 function bnpSubTo(a,b){for(var c=0,d=0,e=Math.min(a.t,this.t);c<e;)d+=this[c]-a[c],b[c++]=d&this.DM,d>>=this.DB;if(a.t<this.t){for(d-=a.s;c<this.t;)d+=this[c],b[c++]=d&this.DM,d>>=this.DB;d+=this.s}else{for(d+=this.s;c<a.t;)d-=a[c],b[c++]=d&this.DM,d>>=this.DB;d-=a.s}b.s=0>d?-1:0;-1>d?b[c++]=this.DV+d:0<d&&(b[c++]=d);b.t=c;b.clamp()}
 function bnpMultiplyTo(a,b){var c=this.abs(),d=a.abs(),e=c.t;for(b.t=e+d.t;0<=--e;)b[e]=0;for(e=0;e<d.t;++e)b[e+c.t]=c.am(0,d[e],b,e,0,c.t);b.s=0;b.clamp();this.s!=a.s&&BigInteger.ZERO.subTo(b,b)}function bnpSquareTo(a){for(var b=this.abs(),c=a.t=2*b.t;0<=--c;)a[c]=0;for(c=0;c<b.t-1;++c){var d=b.am(c,b[c],a,2*c,0,1);if((a[c+b.t]+=b.am(c+1,2*b[c],a,2*c+1,d,b.t-c-1))>=b.DV)a[c+b.t]-=b.DV,a[c+b.t+1]=1}0<a.t&&(a[a.t-1]+=b.am(c,b[c],a,2*c,0,1));a.s=0;a.clamp()}
-function bnpDivRemTo(a,b,c){var d=a.abs();if(!(0>=d.t)){var e=this.abs();if(e.t<d.t)null!=b&&b.fromInt(0),null!=c&&this.copyTo(c);else{null==c&&(c=nbi());var f=nbi(),g=this.s,a=a.s,h=this.DB-nbits(d[d.t-1]);0<h?(d.lShiftTo(h,f),e.lShiftTo(h,c)):(d.copyTo(f),e.copyTo(c));d=f.t;e=f[d-1];if(0!=e){var j=e*(1<<this.F1)+(1<d?f[d-2]>>this.F2:0),l=this.FV/j,j=(1<<this.F1)/j,n=1<<this.F2,m=c.t,p=m-d,k=null==b?nbi():b;f.dlShiftTo(p,k);0<=c.compareTo(k)&&(c[c.t++]=1,c.subTo(k,c));BigInteger.ONE.dlShiftTo(d,
-k);for(k.subTo(f,f);f.t<d;)f[f.t++]=0;for(;0<=--p;){var q=c[--m]==e?this.DM:Math.floor(c[m]*l+(c[m-1]+n)*j);if((c[m]+=f.am(0,q,c,p,0,d))<q){f.dlShiftTo(p,k);for(c.subTo(k,c);c[m]<--q;)c.subTo(k,c)}}null!=b&&(c.drShiftTo(d,b),g!=a&&BigInteger.ZERO.subTo(b,b));c.t=d;c.clamp();0<h&&c.rShiftTo(h,c);0>g&&BigInteger.ZERO.subTo(c,c)}}}}function bnMod(a){var b=nbi();this.abs().divRemTo(a,null,b);0>this.s&&0<b.compareTo(BigInteger.ZERO)&&a.subTo(b,b);return b}function Classic(a){this.m=a}
+function bnpDivRemTo(a,b,c){var d=a.abs();if(!(0>=d.t)){var e=this.abs();if(e.t<d.t)null!=b&&b.fromInt(0),null!=c&&this.copyTo(c);else{null==c&&(c=nbi());var f=nbi(),g=this.s,a=a.s,h=this.DB-nbits(d[d.t-1]);0<h?(d.lShiftTo(h,f),e.lShiftTo(h,c)):(d.copyTo(f),e.copyTo(c));d=f.t;e=f[d-1];if(0!=e){var i=e*(1<<this.F1)+(1<d?f[d-2]>>this.F2:0),k=this.FV/i,i=(1<<this.F1)/i,m=1<<this.F2,l=c.t,n=l-d,j=null==b?nbi():b;f.dlShiftTo(n,j);0<=c.compareTo(j)&&(c[c.t++]=1,c.subTo(j,c));BigInteger.ONE.dlShiftTo(d,
+j);for(j.subTo(f,f);f.t<d;)f[f.t++]=0;for(;0<=--n;){var p=c[--l]==e?this.DM:Math.floor(c[l]*k+(c[l-1]+m)*i);if((c[l]+=f.am(0,p,c,n,0,d))<p){f.dlShiftTo(n,j);for(c.subTo(j,c);c[l]<--p;)c.subTo(j,c)}}null!=b&&(c.drShiftTo(d,b),g!=a&&BigInteger.ZERO.subTo(b,b));c.t=d;c.clamp();0<h&&c.rShiftTo(h,c);0>g&&BigInteger.ZERO.subTo(c,c)}}}}function bnMod(a){var b=nbi();this.abs().divRemTo(a,null,b);0>this.s&&0<b.compareTo(BigInteger.ZERO)&&a.subTo(b,b);return b}function Classic(a){this.m=a}
 function cConvert(a){return 0>a.s||0<=a.compareTo(this.m)?a.mod(this.m):a}function cRevert(a){return a}function cReduce(a){a.divRemTo(this.m,null,a)}function cMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}function cSqrTo(a,b){a.squareTo(b);this.reduce(b)}Classic.prototype.convert=cConvert;Classic.prototype.revert=cRevert;Classic.prototype.reduce=cReduce;Classic.prototype.mulTo=cMulTo;Classic.prototype.sqrTo=cSqrTo;
 function bnpInvDigit(){if(1>this.t)return 0;var a=this[0];if(0==(a&1))return 0;var b=a&3,b=b*(2-(a&15)*b)&15,b=b*(2-(a&255)*b)&255,b=b*(2-((a&65535)*b&65535))&65535,b=b*(2-a*b%this.DV)%this.DV;return 0<b?this.DV-b:-b}function Montgomery(a){this.m=a;this.mp=a.invDigit();this.mpl=this.mp&32767;this.mph=this.mp>>15;this.um=(1<<a.DB-15)-1;this.mt2=2*a.t}
 function montConvert(a){var b=nbi();a.abs().dlShiftTo(this.m.t,b);b.divRemTo(this.m,null,b);0>a.s&&0<b.compareTo(BigInteger.ZERO)&&this.m.subTo(b,b);return b}function montRevert(a){var b=nbi();a.copyTo(b);this.reduce(b);return b}
@@ -218,7 +228,7 @@
 BigInteger.prototype.multiplyTo=bnpMultiplyTo;BigInteger.prototype.squareTo=bnpSquareTo;BigInteger.prototype.divRemTo=bnpDivRemTo;BigInteger.prototype.invDigit=bnpInvDigit;BigInteger.prototype.isEven=bnpIsEven;BigInteger.prototype.exp=bnpExp;BigInteger.prototype.toString=bnToString;BigInteger.prototype.negate=bnNegate;BigInteger.prototype.abs=bnAbs;BigInteger.prototype.compareTo=bnCompareTo;BigInteger.prototype.bitLength=bnBitLength;BigInteger.prototype.mod=bnMod;BigInteger.prototype.modPowInt=bnModPowInt;
 BigInteger.ZERO=nbv(0);BigInteger.ONE=nbv(1);function bnClone(){var a=nbi();this.copyTo(a);return a}function bnIntValue(){if(0>this.s){if(1==this.t)return this[0]-this.DV;if(0==this.t)return-1}else{if(1==this.t)return this[0];if(0==this.t)return 0}return(this[1]&(1<<32-this.DB)-1)<<this.DB|this[0]}function bnByteValue(){return 0==this.t?this.s:this[0]<<24>>24}function bnShortValue(){return 0==this.t?this.s:this[0]<<16>>16}function bnpChunkSize(a){return Math.floor(Math.LN2*this.DB/Math.log(a))}
 function bnSigNum(){return 0>this.s?-1:0>=this.t||1==this.t&&0>=this[0]?0:1}function bnpToRadix(a){null==a&&(a=10);if(0==this.signum()||2>a||36<a)return"0";var b=this.chunkSize(a),b=Math.pow(a,b),c=nbv(b),d=nbi(),e=nbi(),f="";for(this.divRemTo(c,d,e);0<d.signum();)f=(b+e.intValue()).toString(a).substr(1)+f,d.divRemTo(c,d,e);return e.intValue().toString(a)+f}
-function bnpFromRadix(a,b){this.fromInt(0);null==b&&(b=10);for(var c=this.chunkSize(b),d=Math.pow(b,c),e=!1,f=0,g=0,h=0;h<a.length;++h){var j=intAt(a,h);0>j?"-"==a.charAt(h)&&0==this.signum()&&(e=!0):(g=b*g+j,++f>=c&&(this.dMultiply(d),this.dAddOffset(g,0),g=f=0))}0<f&&(this.dMultiply(Math.pow(b,f)),this.dAddOffset(g,0));e&&BigInteger.ZERO.subTo(this,this)}
+function bnpFromRadix(a,b){this.fromInt(0);null==b&&(b=10);for(var c=this.chunkSize(b),d=Math.pow(b,c),e=!1,f=0,g=0,h=0;h<a.length;++h){var i=intAt(a,h);0>i?"-"==a.charAt(h)&&0==this.signum()&&(e=!0):(g=b*g+i,++f>=c&&(this.dMultiply(d),this.dAddOffset(g,0),g=f=0))}0<f&&(this.dMultiply(Math.pow(b,f)),this.dAddOffset(g,0));e&&BigInteger.ZERO.subTo(this,this)}
 function bnpFromNumber(a,b,c){if("number"==typeof b)if(2>a)this.fromInt(1);else{this.fromNumber(a,c);this.testBit(a-1)||this.bitwiseTo(BigInteger.ONE.shiftLeft(a-1),op_or,this);for(this.isEven()&&this.dAddOffset(1,0);!this.isProbablePrime(b);)this.dAddOffset(2,0),this.bitLength()>a&&this.subTo(BigInteger.ONE.shiftLeft(a-1),this)}else{var c=[],d=a&7;c.length=(a>>3)+1;b.nextBytes(c);c[0]=0<d?c[0]&(1<<d)-1:0;this.fromString(c,256)}}
 function bnToByteArray(){var a=this.t,b=[];b[0]=this.s;var c=this.DB-a*this.DB%8,d,e=0;if(0<a--){if(c<this.DB&&(d=this[a]>>c)!=(this.s&this.DM)>>c)b[e++]=d|this.s<<this.DB-c;for(;0<=a;)if(8>c?(d=(this[a]&(1<<c)-1)<<8-c,d|=this[--a]>>(c+=this.DB-8)):(d=this[a]>>(c-=8)&255,0>=c&&(c+=this.DB,--a)),0!=(d&128)&&(d|=-256),0==e&&(this.s&128)!=(d&128)&&++e,0<e||d!=this.s)b[e++]=d}return b}function bnEquals(a){return 0==this.compareTo(a)}function bnMin(a){return 0>this.compareTo(a)?this:a}
 function bnMax(a){return 0<this.compareTo(a)?this:a}function bnpBitwiseTo(a,b,c){var d,e,f=Math.min(a.t,this.t);for(d=0;d<f;++d)c[d]=b(this[d],a[d]);if(a.t<this.t){e=a.s&this.DM;for(d=f;d<this.t;++d)c[d]=b(this[d],e);c.t=this.t}else{e=this.s&this.DM;for(d=f;d<a.t;++d)c[d]=b(e,a[d]);c.t=a.t}c.s=b(this.s,a.s);c.clamp()}function op_and(a,b){return a&b}function bnAnd(a){var b=nbi();this.bitwiseTo(a,op_and,b);return b}function op_or(a,b){return a|b}
@@ -232,8 +242,8 @@
 function Barrett(a){this.r2=nbi();this.q3=nbi();BigInteger.ONE.dlShiftTo(2*a.t,this.r2);this.mu=this.r2.divide(a);this.m=a}function barrettConvert(a){if(0>a.s||a.t>2*this.m.t)return a.mod(this.m);if(0>a.compareTo(this.m))return a;var b=nbi();a.copyTo(b);this.reduce(b);return b}function barrettRevert(a){return a}
 function barrettReduce(a){a.drShiftTo(this.m.t-1,this.r2);a.t>this.m.t+1&&(a.t=this.m.t+1,a.clamp());this.mu.multiplyUpperTo(this.r2,this.m.t+1,this.q3);for(this.m.multiplyLowerTo(this.q3,this.m.t+1,this.r2);0>a.compareTo(this.r2);)a.dAddOffset(1,this.m.t+1);for(a.subTo(this.r2,a);0<=a.compareTo(this.m);)a.subTo(this.m,a)}function barrettSqrTo(a,b){a.squareTo(b);this.reduce(b)}function barrettMulTo(a,b,c){a.multiplyTo(b,c);this.reduce(c)}Barrett.prototype.convert=barrettConvert;
 Barrett.prototype.revert=barrettRevert;Barrett.prototype.reduce=barrettReduce;Barrett.prototype.mulTo=barrettMulTo;Barrett.prototype.sqrTo=barrettSqrTo;
-function bnModPow(a,b){var c=a.bitLength(),d,e=nbv(1),f;if(0>=c)return e;d=18>c?1:48>c?3:144>c?4:768>c?5:6;f=8>c?new Classic(b):b.isEven()?new Barrett(b):new Montgomery(b);var g=[],h=3,j=d-1,l=(1<<d)-1;g[1]=f.convert(this);if(1<d){c=nbi();for(f.sqrTo(g[1],c);h<=l;)g[h]=nbi(),f.mulTo(c,g[h-2],g[h]),h+=2}for(var n=a.t-1,m,p=!0,k=nbi(),c=nbits(a[n])-1;0<=n;){c>=j?m=a[n]>>c-j&l:(m=(a[n]&(1<<c+1)-1)<<j-c,0<n&&(m|=a[n-1]>>this.DB+c-j));for(h=d;0==(m&1);)m>>=1,--h;if(0>(c-=h))c+=this.DB,--n;if(p)g[m].copyTo(e),
-p=!1;else{for(;1<h;)f.sqrTo(e,k),f.sqrTo(k,e),h-=2;0<h?f.sqrTo(e,k):(h=e,e=k,k=h);f.mulTo(k,g[m],e)}for(;0<=n&&0==(a[n]&1<<c);)f.sqrTo(e,k),h=e,e=k,k=h,0>--c&&(c=this.DB-1,--n)}return f.revert(e)}
+function bnModPow(a,b){var c=a.bitLength(),d,e=nbv(1),f;if(0>=c)return e;d=18>c?1:48>c?3:144>c?4:768>c?5:6;f=8>c?new Classic(b):b.isEven()?new Barrett(b):new Montgomery(b);var g=[],h=3,i=d-1,k=(1<<d)-1;g[1]=f.convert(this);if(1<d){c=nbi();for(f.sqrTo(g[1],c);h<=k;)g[h]=nbi(),f.mulTo(c,g[h-2],g[h]),h+=2}for(var m=a.t-1,l,n=!0,j=nbi(),c=nbits(a[m])-1;0<=m;){c>=i?l=a[m]>>c-i&k:(l=(a[m]&(1<<c+1)-1)<<i-c,0<m&&(l|=a[m-1]>>this.DB+c-i));for(h=d;0==(l&1);)l>>=1,--h;if(0>(c-=h))c+=this.DB,--m;if(n)g[l].copyTo(e),
+n=!1;else{for(;1<h;)f.sqrTo(e,j),f.sqrTo(j,e),h-=2;0<h?f.sqrTo(e,j):(h=e,e=j,j=h);f.mulTo(j,g[l],e)}for(;0<=m&&0==(a[m]&1<<c);)f.sqrTo(e,j),h=e,e=j,j=h,0>--c&&(c=this.DB-1,--m)}return f.revert(e)}
 function bnGCD(a){var b=0>this.s?this.negate():this.clone(),a=0>a.s?a.negate():a.clone();if(0>b.compareTo(a))var c=b,b=a,a=c;var c=b.getLowestSetBit(),d=a.getLowestSetBit();if(0>d)return b;c<d&&(d=c);0<d&&(b.rShiftTo(d,b),a.rShiftTo(d,a));for(;0<b.signum();)0<(c=b.getLowestSetBit())&&b.rShiftTo(c,b),0<(c=a.getLowestSetBit())&&a.rShiftTo(c,a),0<=b.compareTo(a)?(b.subTo(a,b),b.rShiftTo(1,b)):(a.subTo(b,a),a.rShiftTo(1,a));0<d&&a.lShiftTo(d,a);return a}
 function bnpModInt(a){if(0>=a)return 0;var b=this.DV%a,c=0>this.s?a-1:0;if(0<this.t)if(0==b)c=this[0]%a;else for(var d=this.t-1;0<=d;--d)c=(b*c+this[d])%a;return c}
 function bnModInverse(a){var b=a.isEven();if(this.isEven()&&b||0==a.signum())return BigInteger.ZERO;for(var c=a.clone(),d=this.clone(),e=nbv(1),f=nbv(0),g=nbv(0),h=nbv(1);0!=c.signum();){for(;c.isEven();){c.rShiftTo(1,c);if(b){if(!e.isEven()||!f.isEven())e.addTo(this,e),f.subTo(a,f);e.rShiftTo(1,e)}else f.isEven()||f.subTo(a,f);f.rShiftTo(1,f)}for(;d.isEven();){d.rShiftTo(1,d);if(b){if(!g.isEven()||!h.isEven())g.addTo(this,g),h.subTo(a,h);g.rShiftTo(1,g)}else h.isEven()||h.subTo(a,h);h.rShiftTo(1,
@@ -245,3 +255,29 @@
 BigInteger.prototype.millerRabin=bnpMillerRabin;BigInteger.prototype.clone=bnClone;BigInteger.prototype.intValue=bnIntValue;BigInteger.prototype.byteValue=bnByteValue;BigInteger.prototype.shortValue=bnShortValue;BigInteger.prototype.signum=bnSigNum;BigInteger.prototype.toByteArray=bnToByteArray;BigInteger.prototype.equals=bnEquals;BigInteger.prototype.min=bnMin;BigInteger.prototype.max=bnMax;BigInteger.prototype.and=bnAnd;BigInteger.prototype.or=bnOr;BigInteger.prototype.xor=bnXor;
 BigInteger.prototype.andNot=bnAndNot;BigInteger.prototype.not=bnNot;BigInteger.prototype.shiftLeft=bnShiftLeft;BigInteger.prototype.shiftRight=bnShiftRight;BigInteger.prototype.getLowestSetBit=bnGetLowestSetBit;BigInteger.prototype.bitCount=bnBitCount;BigInteger.prototype.testBit=bnTestBit;BigInteger.prototype.setBit=bnSetBit;BigInteger.prototype.clearBit=bnClearBit;BigInteger.prototype.flipBit=bnFlipBit;BigInteger.prototype.add=bnAdd;BigInteger.prototype.subtract=bnSubtract;
 BigInteger.prototype.multiply=bnMultiply;BigInteger.prototype.divide=bnDivide;BigInteger.prototype.remainder=bnRemainder;BigInteger.prototype.divideAndRemainder=bnDivideAndRemainder;BigInteger.prototype.modPow=bnModPow;BigInteger.prototype.modInverse=bnModInverse;BigInteger.prototype.pow=bnPow;BigInteger.prototype.gcd=bnGCD;BigInteger.prototype.isProbablePrime=bnIsProbablePrime;
+var LOG=0,NDN=function NDN(b){if(!NDN.supported)throw Error("The necessary JavaScript support is not available on this platform.");b=b||{};this.transport=(b.getTransport||function(){return new WebSocketTransport})();this.getHostAndPort=b.getHostAndPort||this.transport.defaultGetHostAndPort;this.host=void 0!==b.host?b.host:null;this.port=b.port||9696;this.readyStatus=NDN.UNOPEN;this.verify=void 0!==b.verify?b.verify:!0;this.onopen=b.onopen||function(){3<LOG&&console.log("NDN connection established.")};
+this.onclose=b.onclose||function(){3<LOG&&console.log("NDN connection closed.")};this.ccndid=null};NDN.UNOPEN=0;NDN.OPENED=1;NDN.CLOSED=2;NDN.getSupported=function(){try{(new Uint8Array(1)).subarray(0,1)}catch(a){return console.log("NDN not available: Uint8Array not supported. "+a),!1}return!0};NDN.supported=NDN.getSupported();NDN.ccndIdFetcher=new Name("/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY");NDN.prototype.createRoute=function(a,b){this.host=a;this.port=b};NDN.KeyStore=[];
+var KeyStoreEntry=function(a,b,c){this.keyName=a;this.rsaKey=b;this.timeStamp=c};NDN.addKeyEntry=function(a){null==NDN.getKeyByName(a.keyName)&&NDN.KeyStore.push(a)};NDN.getKeyByName=function(a){for(var b=null,c=0;c<NDN.KeyStore.length;c++)if(NDN.KeyStore[c].keyName.contentName.match(a.contentName)&&(null==b||NDN.KeyStore[c].keyName.contentName.components.length>b.keyName.contentName.components.length))b=NDN.KeyStore[c];return b};NDN.PITTable=[];
+var PITEntry=function(a,b){this.interest=a;this.closure=b;this.timerID=-1};NDN.getEntryForExpressedInterest=function(a){for(var b=null,c=0;c<NDN.PITTable.length;c++)if(NDN.PITTable[c].interest.matches_name(a)&&(null==b||NDN.PITTable[c].interest.name.components.length>b.interest.name.components.length))b=NDN.PITTable[c];return b};NDN.CSTable=[];var CSEntry=function(a,b){this.name=a;this.closure=b};
+function getEntryForRegisteredPrefix(a){for(var b=0;b<NDN.CSTable.length;b++)if(null!=NDN.CSTable[b].name.match(a))return NDN.CSTable[b];return null}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){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 h=NDN.PITTable.indexOf(e);0<=h&&NDN.PITTable.splice(h,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 "+
+this.name.to_uri()+" ."):(3<LOG&&console.log("Got ccndid from ccnd."),this.ndn.ccndid=c.signedInfo.publisher.publisherPublicKeyDigest,3<LOG&&console.log(this.ndn.ccndid),this.ndn.registerPrefixHelper(this.name,this.callerClosure,this.flag));return Closure.RESULT_OK};
+NDN.prototype.registerPrefixHelper=function(a,b){var c=new ForwardingEntry("selfreg",a,null,null,3,2147483647),c=encodeForwardingEntry(c),d=new SignedInfo;d.setFields();c=new ContentObject(new Name,d,c,new Signature);c.sign();c=encodeToBinaryContentObject(c);c=new Name(["ccnx",this.ccndid,"selfreg",c]);c=new Interest(c);c.scope=1;3<LOG&&console.log("Send Interest registration packet.");d=new CSEntry(a.getName(),b);NDN.CSTable.push(d);this.transport.send(encodeToBinaryInterest(c))};
+NDN.prototype.onReceivedElement=function(a){3<LOG&&console.log("Complete element received. Length "+a.length+". Start decoding.");var b=new BinaryXMLDecoder(a);if(b.peekStartElement(CCNProtocolDTags.Interest))3<LOG&&console.log("Interest packet received."),a=new Interest,a.from_ccnb(b),3<LOG&&console.log(a),b=escape(a.name.getName()),3<LOG&&console.log(b),b=getEntryForRegisteredPrefix(b),null!=b&&(a=new UpcallInfo(this,a,0,null),b.closure.upcall(Closure.UPCALL_INTEREST,a)==Closure.RESULT_INTEREST_CONSUMED&&
+null!=a.contentObject&&this.transport.send(encodeToBinaryContentObject(a.contentObject)));else if(b.peekStartElement(CCNProtocolDTags.ContentObject)){if(3<LOG&&console.log("ContentObject packet received."),a=new ContentObject,a.from_ccnb(b),b=NDN.getEntryForExpressedInterest(a.name),null!=b){clearTimeout(b.timerID);var c=NDN.PITTable.indexOf(b);0<=c&&NDN.PITTable.splice(c,1);b=b.closure;if(!1==this.verify)b.upcall(Closure.UPCALL_CONTENT_UNVERIFIED,new UpcallInfo(this,null,0,a));else{var d=function(a,
+b,c,d,e){this.contentObject=a;this.closure=b;this.keyName=c;this.sigHex=d;this.witness=e;Closure.call(this)},e=this;d.prototype.upcall=function(a,b){if(a==Closure.UPCALL_INTEREST_TIMED_OUT)console.log("In KeyFetchClosure.upcall: interest time out."),console.log(this.keyName.contentName.getName());else if(a==Closure.UPCALL_CONTENT){var c=decodeSubjectPublicKeyInfo(b.contentObject.content),d=!0==c.verifyByteArray(this.contentObject.rawSignatureData,this.witness,this.sigHex)?Closure.UPCALL_CONTENT:Closure.UPCALL_CONTENT_BAD;
+this.closure.upcall(d,new UpcallInfo(e,null,0,this.contentObject));c=new KeyStoreEntry(g.keyName,c,(new Date).getTime());NDN.addKeyEntry(c)}else a==Closure.UPCALL_CONTENT_BAD&&console.log("In KeyFetchClosure.upcall: signature verification failed")};if(a.signedInfo&&a.signedInfo.locator&&a.signature){3<LOG&&console.log("Key verification...");var c=DataUtils.toHex(a.signature.signature).toLowerCase(),f=null;null!=a.signature.Witness&&(f=new Witness,f.decode(a.signature.Witness));var g=a.signedInfo.locator;
+if(g.type==KeyLocatorType.KEYNAME)if(3<LOG&&console.log("KeyLocator contains KEYNAME"),g.keyName.contentName.match(a.name))3<LOG&&console.log("Content is key itself"),d=decodeSubjectPublicKeyInfo(a.content),c=d.verifyByteArray(a.rawSignatureData,f,c),c=!0==c?Closure.UPCALL_CONTENT:Closure.UPCALL_CONTENT_BAD,b.upcall(c,new UpcallInfo(this,null,0,a));else{var h=NDN.getKeyByName(g.keyName);h?(3<LOG&&console.log("Local key cache hit"),d=h.rsaKey,c=d.verifyByteArray(a.rawSignatureData,f,c),c=!0==c?Closure.UPCALL_CONTENT:
+Closure.UPCALL_CONTENT_BAD,b.upcall(c,new UpcallInfo(this,null,0,a))):(3<LOG&&console.log("Fetch key according to keylocator"),a=new d(a,b,g.keyName,c,f),this.expressInterest(g.keyName.contentName.getPrefix(4),a))}else g.type==KeyLocatorType.KEY?(3<LOG&&console.log("Keylocator contains KEY"),d=decodeSubjectPublicKeyInfo(a.signedInfo.locator.publicKey),c=d.verifyByteArray(a.rawSignatureData,f,c),c=!0==c?Closure.UPCALL_CONTENT:Closure.UPCALL_CONTENT_BAD,b.upcall(Closure.UPCALL_CONTENT,new UpcallInfo(this,
+null,0,a))):(a=g.certificate,console.log("KeyLocator contains CERT"),console.log(a))}}}}else console.log("Incoming packet is not Interest or ContentObject. Discard now.")};
+NDN.prototype.connectAndExecute=function(a){var b=this.getHostAndPort();if(null==b)console.log("ERROR: No more hosts from getHostAndPort"),this.host=null;else if(b.host==this.host&&b.port==this.port)console.log("ERROR: The host returned by getHostAndPort is not alive: "+this.host+":"+this.port);else{this.host=b.host;this.port=b.port;3<LOG&&console.log("Connect: trying host from getHostAndPort: "+this.host);b=new Interest(new Name("/"));b.interestLifetime=4E3;var c=this,d=setTimeout(function(){3<LOG&&
+console.log("Connect: timeout waiting for host "+c.host);c.connectAndExecute(a)},3E3);this.reconnectAndExpressInterest(b,new NDN.ConnectClosure(this,a,d))}};NDN.ConnectClosure=function(a,b,c){Closure.call(this);this.ndn=a;this.onConnected=b;this.timerID=c};NDN.ConnectClosure.prototype.upcall=function(a){if(!(a==Closure.UPCALL_CONTENT||a==Closure.UPCALL_CONTENT_UNVERIFIED))return Closure.RESULT_ERR;clearTimeout(this.timerID);this.ndn.readyStatus=NDN.OPENED;this.ndn.onopen();this.onConnected();return Closure.RESULT_OK};
+var BinaryXmlElementReader=function(a){this.elementListener=a;this.dataParts=[];this.structureDecoder=new BinaryXMLStructureDecoder};
+BinaryXmlElementReader.prototype.onReceivedData=function(a){for(;;)if(this.structureDecoder.seek(0),this.structureDecoder.findElementEnd(a)){this.dataParts.push(a.subarray(0,this.structureDecoder.offset));var b=DataUtils.concatArrays(this.dataParts);this.dataParts=[];try{this.elementListener.onReceivedElement(b)}catch(c){console.log("BinaryXmlElementReader: ignoring exception from onReceivedElement: "+c)}a=a.subarray(this.structureDecoder.offset,a.length);this.structureDecoder=new BinaryXMLStructureDecoder;
+if(0==a.length)break}else{this.dataParts.push(a);3<LOG&&console.log("Incomplete packet received. Length "+a.length+". Wait for more input.");break}};
diff --git a/gui/html/reset.css b/gui/html/reset.css
new file mode 100755
index 0000000..0af7c26
--- /dev/null
+++ b/gui/html/reset.css
@@ -0,0 +1,207 @@
+/* `XHTML, HTML4, HTML5 Reset
+----------------------------------------------------------------------------------------------------*/
+
+a,
+abbr,
+acronym,
+address,
+applet,
+article,
+aside,
+audio,
+b,
+big,
+blockquote,
+body,
+canvas,
+caption,
+center,
+cite,
+code,
+dd,
+del,
+details,
+dfn,
+dialog,
+div,
+dl,
+dt,
+em,
+embed,
+fieldset,
+figcaption,
+figure,
+font,
+footer,
+form,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+header,
+hgroup,
+hr,
+html,
+i,
+iframe,
+img,
+ins,
+kbd,
+label,
+legend,
+li,
+mark,
+menu,
+meter,
+nav,
+object,
+ol,
+output,
+p,
+pre,
+progress,
+q,
+rp,
+rt,
+ruby,
+s,
+samp,
+section,
+small,
+span,
+strike,
+strong,
+sub,
+summary,
+sup,
+table,
+tbody,
+td,
+tfoot,
+th,
+thead,
+time,
+tr,
+tt,
+u,
+ul,
+var,
+video,
+xmp {
+  border: 0;
+  margin: 0;
+  padding: 0;
+  font-size: 100%;
+}
+
+html,
+body {
+  height: 100%;
+}
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+/*
+  Override the default (display: inline) for
+  browsers that do not recognize HTML5 tags.
+
+  IE8 (and lower) requires a shiv:
+  http://ejohn.org/blog/html5-shiv
+*/
+  display: block;
+}
+
+b,
+strong {
+/*
+  Makes browsers agree.
+  IE + Opera = font-weight: bold.
+  Gecko + WebKit = font-weight: bolder.
+*/
+  font-weight: bold;
+}
+
+img {
+  color: transparent;
+  font-size: 0;
+  vertical-align: middle;
+/*
+  For IE.
+  http://css-tricks.com/ie-fix-bicubic-scaling-for-images
+*/
+  -ms-interpolation-mode: bicubic;
+}
+
+li {
+/*
+  For IE6 + IE7:
+
+  "display: list-item" keeps bullets from
+  disappearing if hasLayout is triggered.
+*/
+  display: list-item;
+  list-style: none;
+}
+
+table {
+  border-collapse: collapse;
+  border-spacing: 0;
+}
+
+th,
+td,
+caption {
+  font-weight: normal;
+  vertical-align: top;
+  text-align: left;
+}
+
+q {
+  quotes: none;
+}
+
+q:before,
+q:after {
+  content: '';
+  content: none;
+}
+
+sub,
+sup,
+small {
+  font-size: 75%;
+}
+
+sub,
+sup {
+  line-height: 0;
+  position: relative;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -0.25em;
+}
+
+sup {
+  top: -0.5em;
+}
+
+svg {
+/*
+  For IE9. Without, occasionally draws shapes
+  outside the boundaries of <svg> rectangle.
+*/
+  overflow: hidden;
+}
\ No newline at end of file
diff --git a/gui/html/style.css b/gui/html/style.css
index 34a05e3..198e2ef 100644
--- a/gui/html/style.css
+++ b/gui/html/style.css
@@ -1,311 +1,209 @@
+@import 'reset.css';
+@import 'text.css';
+
+@charset "utf-8";
+
 body {
-	background-color: #ffffff;
-	color: #000000;
-	font-family: 'Rambla', sans-serif;
+    background-color: #ffffff;
+    color: #000000;
+    font-family: sans-serif;
 }
 
-#all {
-	display: none;
+header, nav, article, footer, address {
+    display: block;
 }
 
-#loader {
-	display: block;
-	margin: 0 auto;
+header {
+    margin: 20px auto 0;
+    width: 90%;
 }
 
-#top, #top2, #top3, #top4 {
-	position: fixed;
-	left: 0;
-	right: 0;
-	top: 0;
-	width: 100%;
-	height: 6px;
+header h1 {
+    height: 50px;
+    padding-left: 55px;
+    padding-top: 6px;
+    background-image: url("chronoshare.png");
+    background-repeat: no-repeat;
+    background-size: 50px 50px;
 }
 
-#top { background-color: #3090C7; }
-#top2 { background-color: #2D9A65; }
-#top3 { background-color: #E41B17; }
-#top4 { background-color: #FBB917; }
-
-#contentwrapper {
-	float: left;
-	width: 100%;
-	padding-bottom: 50px;
+article {
+    margin: 20px auto 0;
+    width: 90%;
 }
 
-#header {
-	margin: 40px 20% 0 20%;
-	min-width: 587px;
+footer {
+    margin: 20px auto 0;
+    width: 90%;
+
+    padding-bottom: 2px;
+    text-align: right;
+
+    position: fixed;
+    font-height: 10px;
+    bottom: 0;
+    left: 5%;
 }
 
-/* Used for fluid layout */
-#leftcolumn {
-	float: left;
-	width: 20%;
-	margin-left: -100%;
-}
-
-/* Used for fluid layout */
-#rightcolumn {
-	float: left;
-	width: 20%;
-	margin-left: -20%;
-}
-
-h1 {	
-	font-family: 'Rambla', sans-serif;
+h1 {
+    font-family: sans-serif;
 }
 
 h3 {
-	font-family: 'Rambla', sans-serif;
-	text-align: center;
-}
-
-#speed {
-	margin-top: -70px;
-	float: right;
+    font-family: sans-serif;
 }
 
 h5 {
-	font-family: 'Rambla', sans-serif;
-	color: #727272;
+    font-family: sans-serif;
+    color: #727272;
 }
 
-.titles {
-	width: 100%;
-	margin-bottom: 30px;
-	border-bottom: 1px solid #E8E8E8;
-}
-
-.titles2 {
-	width: 100%;
-	margin-bottom: -10px;
-	border-bottom: 1px solid #E8E8E8;
-}
-
-p {
-	font-family: 'Rambla', sans-serif;
-}
-
-.titles p, .titles2 p {	
-	margin-bottom: 5px;
-	font-size: 1.1em;
-	font-weight: 700;
-	color: #000000;
-}
-
-#grey {
-	color: #727272;
-	font-weight: 200;
-}
-
-#green {	
-	color: #2D9A65;
-	font-weight: 200;
-}
-
-#navbar, #navbar_blue, #navbar_red, #navbar_yellow {
-	margin: 40px 0;
-	min-width: 587px;
-	/*max-width: 960px;*/
-	width: 100%;
-	height: 40px;
-}
-
-#navbar {
-	background-color: #EAF4EF;
-	-moz-border-radius: 6px;
-	border-radius: 6px;
-	border: 1px solid #99CCB2;
-}
-
-#navbar_blue {
-	background-color: #EAF4EF;
-	-moz-border-radius: 6px;
-	border-radius: 6px;
-	border: 1px solid #AFDCEC;
-}
-
-#navbar_red {
-	background-color: #EAF4EF;
-	-moz-border-radius: 6px;
-	border-radius: 6px;
-	border: 1px solid #F88158;
-}
-
-#navbar_yellow {
-	background-color: #EAF4EF;
-	-moz-border-radius: 6px;
-	border-radius: 6px;
-	border: 1px solid #EDDA74;
-}
-
-#navbar ul, #navbar_blue ul, #navbar_red ul, #navbar_yellow ul {
-	margin: 9px 0 0 0;
-	padding: 0px;
-}
-	 
-#navbar li, #navbar_blue li, #navbar_red li, #navbar_yellow li {
-	list-style-type: none;
-	display: inline;
-	margin: 0px 30px;
-}
-	 
-#navbar li a, #navbar_blue li a, #navbar_red li a, #navbar_yellow li a{
-	color: #727272;
-	font-size: 14px;
-	font-family: 'Istok Web', sans-serif;
-	text-decoration: none;
-}
-	 
-#navbar li a.active, #navbar a:hover { color: #2D9A65; }
-#navbar_blue li a.active, #navbar_blue a:hover { color: #38ACEC; }
-#navbar_red li a.active, #navbar_red a:hover { color: #E41B17; }
-#navbar_yellow li a.active, #navbar_yellow a:hover { color: #FBB917; }
-
-#placeholder {
-	margin: -30px 0 30px 0;
-	/*max-width: 960px;*/
-	width: 100%;
-	height: 237px;
-	/*height: auto;*/
-	background-image: url(bg.png);
-	background-repeat: no-repeat;
-	-moz-border-radius: 6px;
-	border-radius: 6px;
-	border: 2px solid #AFDCEC;
-}
-
-#link1, #link2, #link3 {
-	margin-bottom: 20px;
-	width: 100%;
-	height: 46px;
-	background-color: #EAF4EF;
-	-moz-border-radius: 6px;
-	border-radius: 6px;
-	border: 1px solid #AFDCEC;
-	text-align: center;
-}
-
-a {
-	text-decoration: none;
-	color: #38ACEC;
-	font-family: 'Rambla', sans-serif;
-}
-
-.boxtext {
-	display: inline-block;
-	margin-top: 13px;
-}
-
-#wrap {
-    margin: 100px 20% 0 20%;
+/* Navigation menu */
+nav {
+    margin: 20px 0;
     min-width: 587px;
-    /*max-width: 1000px;*/
+    width: 100%;
+    height: 40px;
 }
 
-#box-table-a
+nav {
+    background-color: #EAF4EF;
+    -moz-border-radius: 6px;
+    border-radius: 6px;
+    border: 1px solid #99CCB2;
+}
+
+nav ul {
+    margin: 13px 0 0 0;
+    padding: 0px;
+}
+
+nav li {
+    list-style-type: none;
+    display: inline;
+    margin: 0px 30px;
+}
+
+nav li a {
+    color: #727272;
+    font-size: 14px;
+    line-height: 14px;
+    font-family: sans-serif;
+    text-decoration: none;
+}
+
+nav li a.active, nav a:hover { color: #2D9A65; }
+
+/* MISC */
+grey {
+    color: #727272;
+    font-weight: 200;
+}
+
+green {
+    color: #2D9A65;
+    font-weight: 200;
+}
+
+red {
+    color: red;
+    font-weight: 200;
+    font-size: 2.4em;
+}
+
+.hidden {
+    display: none;
+}
+
+/* */
+.file-list
 {
-	margin-top: 50px;
-	margin-bottom: 50px;
-	margin-left: 1%;
-	/*float: left;*/
-	font-family: 'Istok Web', sans-serif;
-	font-size: 12px;
-	width: 55%;
-	text-align: left;
-	border-collapse: collapse;
+    border-radius: 6px;
+
+    margin-top: 10px;
+    margin-bottom: 10px;
+    /*float: left;*/
+    font-family: sans-serif;
+    font-size: 12px;
+    width: 100%;
+    text-align: left;
+    /* border-collapse: collapse; */
+}
+
+.file-list th
+{
+    /* -moz-border-radius: 10px; */
+    /* border-radius: 10px; */
+    font-size: 14px;
+    font-weight: normal;
+    padding: 8px;
+    background: #EAF4EF;
+    border-top: 1px solid #99CCB2;
+    /* border-bottom: 1px solid #fff; */
+    color: #727272;
+    text-align: left;
+}
+
+.file-list th.border-left {
+    /* -moz-border-radius-topleft:10px; */
+    /* -webkit-border-top-left-radius:10px; */
+    /* border-top-left-radius:10px; */
+}
+
+.file-list td
+{
+    padding: 8px;
+    border-bottom: 1px solid #fff;
+    color: #000;
+    border-top: 1px solid transparent;
+    /* border-right: 1px solid #99CCB2; */
+    /* border-left: 1px solid #99CCB2; */
+}
+
+.border-left {
+    border-left: 1px solid #99CCB2;
+}
+
+.border-right {
+    border-right: 1px solid #99CCB2;
 }
 
 tfoot {
-	border-bottom: 2px solid #99CCB2;
-	background: #EAF4EF;
+    border-bottom: 2px solid #99CCB2;
+    background: #EAF4EF;
+}
+.file-list tfoot td {
+    padding: 0;
 }
 
-#box-table-a th
-{
-	-moz-border-radius: 5px;
-	border-radius: 5px;
-	font-size: 14px;
-	font-weight: normal;
-	padding: 8px;
-	background: #EAF4EF;
-	border-top: 1px solid #99CCB2;
-	border-bottom: 1px solid #fff;
-	color: #727272;
-	text-align: center;
-}
-
-#box-table-a td
-{
-	padding: 8px;
-	border-bottom: 1px solid #fff;
-	color: #000;
-	border-top: 1px solid transparent;
-	border-right: 1px solid #99CCB2;
-	border-left: 1px solid #99CCB2;
-}
 
 .odd {
-	background-color: #eeeeee;
+    background-color: #eeeeee;
 }
 
-#lime, #online {
-	background-color: #4AA02C;
-	border-left: none!important;
+.filename {
+    width: 50%;
+}
+.version {
+    width: 5%;
+}
+.modified {
+    width: 20%;
+}
+.modified-by {
+    width: 25%;
 }
 
-#notintopology {
-	background-color: #BDEDFF;
-	border-left: none!important;
+pre {
+    font-size: 9px;
 }
 
-#out-of-date {
-	background-color: #FBB917;
-	border-left: none!important;
+#loader {
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    width: 128px;
+    height: 128px;
+    margin-top: -64px; /* Half the height */
+    margin-left: -64px; /* Half the width */
 }
-
-#offline {
-	background-color: #E41B17;
-	border-left: none!important;
-}
-
-.border_left {
-	border-left: 1px solid #99CCB2;
-}
-
-.border_right {
-	border-right: 1px solid #99CCB2;
-}
-
-.right_border {
-	border-right: none!important;
-}
-
-#blue {
-	color: #3090C7;
-	font-weight: 200;
-}
-
-#red {
-	color: #E41B17;
-	font-weight: 200;
-}
-
-#yellow {
-	color: #FBB917;
-	font-weight: 200;
-}
-
-#footer {
-   position: absolute;
-   bottom: 0;
-   width: 100%;
-   height: 50px;
-}
-
-.bar {
-	width: 50px;
-	border-bottom: 2px solid #ffffff;
-}
-
diff --git a/gui/html/text.css b/gui/html/text.css
new file mode 100755
index 0000000..2a2fd22
--- /dev/null
+++ b/gui/html/text.css
@@ -0,0 +1,106 @@
+/*
+  960 Grid System ~ Text CSS.
+  Learn more ~ http://960.gs/
+
+  Licensed under GPL and MIT.
+*/
+
+/* `Basic HTML
+----------------------------------------------------------------------------------------------------*/
+
+body {
+    font: 13px Arial, Helvetica, sans-serif;
+}
+
+hr {
+  border: 0 #ccc solid;
+  border-top-width: 1px;
+  clear: both;
+  height: 0;
+}
+
+/* `Headings
+----------------------------------------------------------------------------------------------------*/
+
+h1 {
+	font-size: 2.4em;
+}
+
+h2 {
+	font-size: 1.8em;
+}
+
+h3 {
+	font-size: 1.4em;
+}
+
+/* h1 { */
+/*   font-size: 25px; */
+/* } */
+
+/* h2 { */
+/*   font-size: 23px; */
+/* } */
+
+/* h3 { */
+/*   font-size: 21px; */
+/* } */
+
+h4 {
+  font-size: 19px;
+}
+
+h5 {
+  font-size: 17px;
+}
+
+h6 {
+  font-size: 15px;
+}
+
+/* `Spacing
+----------------------------------------------------------------------------------------------------*/
+
+ol {
+  list-style: decimal;
+}
+
+ul {
+  list-style: disc;
+}
+
+li {
+  margin-left: 30px;
+}
+
+p,
+dl,
+hr,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+ol,
+ul,
+pre,
+table,
+address,
+fieldset,
+figure {
+  margin-bottom: 10px;
+}
+
+pre {
+    /* padding: 0px 24px; */
+    white-space: pre-wrap;
+    background-color: #F9F9F9;
+    border: 1px dashed #2F6FAB;
+    color: black;
+    padding: 1em;
+    font-size: 13px;
+}
+code {
+    font-family: Consolas, Monaco, Andale Mono, monospace;
+}
\ No newline at end of file
