Move the functionality of sending content response into WebSocketTransport so that user's closure is simpler.
diff --git a/js/ContentObject.js b/js/ContentObject.js
index 9567e44..8450a00 100644
--- a/js/ContentObject.js
+++ b/js/ContentObject.js
@@ -6,7 +6,7 @@
 var ContentObject = function ContentObject(_name,_signedInfo,_content,_signature){
 	
 	
-	if (typeof _name === 'string'){
+	if (typeof _name == 'string') {
 		this.name = new Name(_name);
 	}
 	else{
@@ -14,7 +14,13 @@
 		this.name = _name;
 	}
 	this.signedInfo = _signedInfo;
-	this.content=_content;
+	
+	if (typeof _content == 'string') {
+		this.content = DataUtils.toNumbersFromString(_content);
+	} else {
+		this.content = _content;
+	}
+	
 	this.signature = _signature;
 
 	
@@ -270,6 +276,9 @@
     this.locator =_locator;//KeyLocator
     this.freshnessSeconds =_freshnessSeconds; // Integer
     this.finalBlockID=_finalBlockID; //byte array
+    
+    // SWT: merge setFields() method into constructor
+    this.setFields();
 
 };
 
diff --git a/js/WebSocketTransport.js b/js/WebSocketTransport.js
index 99cb224..ae69e49 100644
--- a/js/WebSocketTransport.js
+++ b/js/WebSocketTransport.js
@@ -84,7 +84,22 @@
 				var entry = getEntryForRegisteredPrefix(nameStr);
 				if (entry != null) {
 					//console.log(entry);
-					entry.closure.upcall(Closure.UPCALL_INTEREST, new UpcallInfo(ndn, interest, 0, null));
+					var info = new UpcallInfo(ndn, interest, 0, null);
+					var ret = entry.closure.upcall(Closure.UPCALL_INTEREST, info);
+					if (ret == Closure.RESULT_INTEREST_CONSUMED && info.contentObject != null) { 
+						var coBinary = encodeToBinaryContentObject(info.contentObject);
+						// If we directly use coBinary.buffer to feed ws.send(), WebSocket 
+						// will end up sending a packet with 10000 bytes of data. That 
+						// is, WebSocket will flush the entire buffer in BinaryXMLEncoder
+						// 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 coBinary to the new buffer.
+						//    ---Wentao
+						var bytearray = new Uint8Array(coBinary.length);
+						bytearray.set(coBinary);
+						
+						self.ws.send(bytearray.buffer);
+					}
 				}
 				
 			} else if (decoder.peekStartElement(CCNProtocolDTags.ContentObject)) {  // Content packet
diff --git a/js/encoding/DataUtils.js b/js/encoding/DataUtils.js
index b9728d0..b80ce36 100644
--- a/js/encoding/DataUtils.js
+++ b/js/encoding/DataUtils.js
@@ -276,7 +276,7 @@
 /**
  * Raw String to Uint8Array.
  */
-DataUtils.toNumbersFromString = function( str ){
+DataUtils.toNumbersFromString = function(str) {
 	var bytes = new Uint8Array(str.length);
 	for(var i=0;i<str.length;i++)
 		bytes[i] = str.charCodeAt(i);
diff --git a/js/testing/test-publish-async.html b/js/testing/test-publish-async.html
index fb3d644..cb8a7c1 100644
--- a/js/testing/test-publish-async.html
+++ b/js/testing/test-publish-async.html
@@ -32,26 +32,11 @@
 				var nameStr = escape(interest.name.getName());

 				

 				var si = new SignedInfo();

-				si.setFields();

 				

-				var answer = DataUtils.toNumbersFromString(content);

-				

-				var co = new ContentObject(new Name(nameStr), si, answer, new Signature()); 

+				var co = new ContentObject(new Name(nameStr), si, content, new Signature()); 

 				co.sign();

-				var coBinary = encodeToBinaryContentObject(co);

-				// If we directly use coBinary.buffer to feed ws.send(), WebSocket 

-				// will end up sending a packet with 10000 bytes of data. That 

-				// is, WebSocket will flush the entire buffer in BinaryXMLEncoder

-				// 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 coBinary to the new buffer.

-				//    ---Wentao

-				var bytearray = new Uint8Array(coBinary.length);

-				bytearray.set(coBinary);

 				

-				upcallInfo.ndn.transport.ws.send(bytearray.buffer);

-				console.log('ws.send() finised.');

-				

+				upcallInfo.contentObject = co;

 				return Closure.RESULT_INTEREST_CONSUMED;

 			}

 			return Closure.RESULT_OK;

diff --git a/js/tools/build/ndn-js.js b/js/tools/build/ndn-js.js
index a0dffdc..aa51fd6 100644
--- a/js/tools/build/ndn-js.js
+++ b/js/tools/build/ndn-js.js
@@ -1,7 +1,7 @@
 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 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.transport=(b.getTransport||function(){return new WebSocketTransport})();this.getHostAndPort=b.getHostAndPort||this.transport.defaultGetHostAndPort;this.host=void 0!==b.host?b.host:"localhost";dump("this.host "+this.host+"\n");this.port=b.port||9696;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.ccndIdFetcher="/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY";NDN.prototype.createRoute=function(a,b){this.host=a;this.port=b};NDN.PITTable=[];var PITEntry=function(a,b){this.interest=a;this.closure=b};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};
+var LOG=0,NDN=function NDN(b){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:"localhost";this.port=b.port||9696;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.ccndIdFetcher="/%C1.M.S.localhost/%C1.M.SRV/ccnd/KEY";NDN.prototype.createRoute=function(a,b){this.host=a;this.port=b};NDN.PITTable=[];var PITEntry=function(a,b){this.interest=a;this.closure=b};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.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){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;null==this.host||null==this.port?null==this.getHostAndPort?console.log("ERROR: host OR port NOT SET"):this.connectAndExpressInterest(a,
 b):this.transport.expressInterest(this,a,b)};NDN.prototype.registerPrefix=function(a,b,c){return this.transport.registerPrefix(this,a,b,c)};
@@ -9,13 +9,13 @@
 d.host);d.connectAndExpressInterest(a,b)},3E3);this.transport.expressInterest(this,c,new NDN.ConnectClosure(this,a,b,e))}};NDN.ConnectClosure=function(a,b,c,d){Closure.call(this);this.ndn=a;this.callerInterest=b;this.callerClosure=c;this.timerID=d};
 NDN.ConnectClosure.prototype.upcall=function(a){if(!(a==Closure.UPCALL_CONTENT||a==Closure.UPCALL_CONTENT_UNVERIFIED||a==Closure.UPCALL_INTEREST))return Closure.RESULT_ERR;clearTimeout(this.timerID);console.log(this.ndn.host+": Host is alive. Fetching callerInterest.");this.ndn.transport.expressInterest(this.ndn,this.callerInterest,this.callerClosure);return Closure.RESULT_OK};
 var WebSocketTransport=function(){this.ccndid=this.ws=null;this.maxBufferSize=1E4;this.buffer=new Uint8Array(this.maxBufferSize);this.bufferOffset=0;this.structureDecoder=new BinaryXMLStructureDecoder;this.defaultGetHostAndPort=NDN.makeShuffledGetHostAndPort(["A.ws.ndn.ucla.edu","B.ws.ndn.ucla.edu","C.ws.ndn.ucla.edu","D.ws.ndn.ucla.edu","E.ws.ndn.ucla.edu"],9696)};
-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(NDN.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=
-NDN.getEntryForExpressedInterest(e.name),null!=f){clearTimeout(f.closure.timerID);var g=NDN.PITTable.indexOf(f);0<=g&&NDN.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(NDN.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()}};
+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){var d=new Uint8Array(c);3<LOG&&console.log("BINARY RESPONSE IS "+DataUtils.toHex(d));try{if(d.length+b.bufferOffset>=b.buffer.byteLength){3<LOG&&
+console.log("NDN.ws.onmessage: buffer overflow. Accumulate received length: "+b.bufferOffset+". Current packet length: "+d.length+".");delete b.structureDecoder;delete b.buffer;b.structureDecoder=new BinaryXMLStructureDecoder;b.buffer=new Uint8Array(b.maxBufferSize);b.bufferOffset=0;return}b.buffer.set(d,b.bufferOffset);b.bufferOffset+=d.length;if(!b.structureDecoder.findElementEnd(b.buffer.subarray(0,b.bufferOffset))){3<LOG&&console.log("Incomplete packet received. Length "+d.length+". Wait for more input.");
+return}3<LOG&&console.log("Complete packet received. Length "+d.length+". Start decoding.")}catch(e){console.log("NDN.ws.onmessage exception: "+e);return}c=new BinaryXMLDecoder(b.buffer);if(c.peekStartElement(CCNProtocolDTags.Interest)){3<LOG&&console.log("Interest packet received.");d=new Interest;d.from_ccnb(c);3<LOG&&console.log(d);var f=escape(d.name.getName());3<LOG&&console.log(f);f=getEntryForRegisteredPrefix(f);null!=f&&(d=new UpcallInfo(a,d,0,null),f.closure.upcall(Closure.UPCALL_INTEREST,
+d)==Closure.RESULT_INTEREST_CONSUMED&&null!=d.contentObject&&(f=encodeToBinaryContentObject(d.contentObject),d=new Uint8Array(f.length),d.set(f),b.ws.send(d.buffer)))}else if(c.peekStartElement(CCNProtocolDTags.ContentObject))if(3<LOG&&console.log("ContentObject packet received."),d=new ContentObject,d.from_ccnb(c),3<LOG&&console.log(d),f=d.name.getName(),3<LOG&&console.log(f),null==b.ccndid&&null!=f.match(NDN.ccndIdFetcher))!d.signedInfo||!d.signedInfo.publisher||!d.signedInfo.publisher.publisherPublicKeyDigest?
+(console.log("Cannot contact router, close NDN now."),a.readyStatus=NDN.CLOSED,a.onclose()):(b.ccndid=d.signedInfo.publisher.publisherPublicKeyDigest,3<LOG&&console.log(b.ccndid),a.readyStatus=NDN.OPENED,a.onopen());else{if(f=NDN.getEntryForExpressedInterest(d.name),null!=f){clearTimeout(f.closure.timerID);var g=NDN.PITTable.indexOf(f);0<=g&&NDN.PITTable.splice(g,1);f.closure.upcall(Closure.UPCALL_CONTENT,new UpcallInfo(a,null,0,d))}}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(NDN.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()}};
 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,c);NDN.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=NDN.PITTable.indexOf(f);0<=d&&NDN.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);
@@ -34,9 +34,10 @@
 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.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=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.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};
+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.startSignedInfo=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)};
@@ -47,7 +48,7 @@
 4<LOG&&console.log("READ SIGNATURE ");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),