Make add check for string, byte array, etc.  If a component is a string, encode as UTF8.  Implement getPrefix and getComponent.  Added test-name.html to test these functions.
diff --git a/js/Name.js b/js/Name.js
index 7c4e05a..c177f61 100644
--- a/js/Name.js
+++ b/js/Name.js
@@ -1,53 +1,40 @@
 /*
- * @author: Meki Cheraoui
+ * @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( typeof _components == 'string') {		
 		if(LOG>3)console.log('Content Name String '+_components);
-		this.components = Name.makeBlob(Name.createNameArray(_components));
+		this.components = Name.createNameArray(_components);
 	}
-	else if(typeof _components === 'object' && _components instanceof Array ){
-		
+	else if(typeof _components === 'object'){		
 		if(LOG>4)console.log('Content Name Array '+_components);
-		this.components = Name.makeBlob(_components);
-
+		this.components = [];
+        for (var i = 0; i < _components.length; ++i)
+            this.add(_components[i]);
 	}
-	else if(_components==null){
+	else if(_components==null)
 		this.components =[];
-	}
-	else{
-
+	else
 		if(LOG>1)console.log("NO CONTENT NAME GIVEN");
-
-	}
 };
 
 Name.prototype.getName = function() {
     return this.to_uri();
 };
 
-Name.makeBlob=function(name){
-	
-	var blobArrays = new Array(name.length);
-
-	for(var i=0;i<name.length;i++){
-		if(typeof name[i] == 'string')
-			blobArrays[i]= DataUtils.toNumbersFromString(name[i]);
-		else if(typeof name[i] == 'object')
-			blobArrays[i]= name[i] ;
-		else 
-			if(LOG>4)console.log('NAME COMPONENT INVALID');
-	}
-	
-	return blobArrays;
-};
-
+/* Parse name as a URI and return an array of Uint8Array components.
+ *
+ */
 Name.createNameArray = function(name) {
     name = name.trim();
     if (name.length <= 0)
@@ -97,6 +84,9 @@
         }
         else
             array[i] = component;
+        
+        // Change the component to Uint8Array now.
+        array[i] = DataUtils.toNumbersFromString(array[i]);
     }
 
 	return array;
@@ -133,8 +123,27 @@
 	return CCNProtocolDTags.Name;
 };
 
-Name.prototype.add = function(param){
-	return this.components.push(param);
+/*
+ * 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 = null;
+    if(typeof component == 'string')
+        result = DataUtils.stringToUtf8Array(component);
+	else if(typeof component == 'object' && component instanceof Array)
+        result = new Uint8Array(component);
+	else if(typeof component == 'object' && component instanceof Uint8Array)
+        result = new Uint8Array(component);
+	else if(typeof component == 'object' && component instanceof ArrayBuffer)
+        // Make a copy.
+        result = new Uint8Array(component.slice(0, component.byteLength));
+	else 
+		if(LOG>4)console.log('NAME COMPONENT INVALID');
+    
+	return this.components.push(result);
 };
 
 // Return the escaped name string according to "CCNx URI Scheme".  Does not include "ccnx:".
@@ -147,6 +156,22 @@
 	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;
+}
+
 /**
  * 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.
diff --git a/js/testing/test-encode-decode-ContentObject-bis.html b/js/testing/test-encode-decode-ContentObject-bis.html
deleted file mode 100644
index df3e700..0000000
--- a/js/testing/test-encode-decode-ContentObject-bis.html
+++ /dev/null
@@ -1,210 +0,0 @@
-<?xml version = "1.0" encoding="utf-8" ?>

-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

-"DTD/xhtml1-strict.dtd">

-<html xmlns = "http://www.w3.org/1999/xhtml">

-

-<head>

-	<title>NDN Request Example</title>

-	

-	<script type="text/javascript" src="../Helper.js"></script>

-

-	<script type="text/javascript">

-	

-		function encode(){

-			var contentname = new Name( Name.createNameArray(document.getElementById('contentname').value) );

-			

-			var content = document.getElementById('content').value;

-			

-			var signedInfo = new SignedInfo();

-			signedInfo.setFields();

-			//var signatureBits = generateSignatureBits(contentname,content,signedInfo);

-			

-			//witness is null

-			var signature = new Signature();

-			

-			

-			var co = new ContentObject(contentname,signedInfo,content,signature); 

-			

-			co.sign();

-			

-			

-			var output = encodeToHexContentObject(co);

-			

-			document.getElementById('result').innerHTML = output;

-

-		}

-		

-		function decode(){

-			

-			

-			

-			var input = document.getElementById('result').innerHTML;

-

-			

-			var co = decodeHexContentObject(input);

-			

-			if(LOG>3)console.log('CONTENT OBJECT DECODED');

-			if(LOG>3)console.log(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: ";

-					

-					for(var i=0;i<co.name.components.length;i++){

-						output+= "/"+ toString(co.name.components[i]);

-					}

-					output+= "<br />";

-					output+= "<br />";

-				}

-	

-				if(co.content !=null){

-					output += "CONTENT(ASCII): "+ 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){

-					

-					output += "TimeStamp(hex): "+ co.signedInfo.timestamp.date;

-					

-					output+= "<br />";

-					output+= "<br />";

-				}

-				if(co.signedInfo!=null && co.signedInfo.locator!=null && co.signedInfo.locator.publicKey!=null){

-					

-					var publickey = rstr2b64(toString(co.signedInfo.locator.publicKey));

-					var publickeyHex = DataUtils.toHex(co.signedInfo.locator.publicKey).toLowerCase();

-					var publickeyString = toString(co.signedInfo.locator.publicKey);

-					

-					var signature = DataUtils.toHex(co.signature.signature).toLowerCase();

-					

-					

-					var input = toString(co.rawSignatureData);

-					 

-					

-					output += "DER Certificate: "+publickey ;

-					

-					output+= "<br />";

-					output+= "<br />";

-					

-					

-					

-					if(LOG>2) console.log(" ContentName + SignedInfo + Content = "+input);

-					if(LOG>2) console.log(" PublicKey = "+publickey );

-					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(" Signature NOW IS" );

-					if(LOG>2) console.log(co.signature.signature);

-					

-					

-					var x509 = new X509();

-					

-					x509.readCertPEM(publickey);

-					

-					

-					//x509.readCertPEMWithoutRSAInit(publickey);

-

-					var result = x509.subjectPublicKeyRSA.verifyString(input, signature);

-					console.log('result is '+result);

-					/*var rsakey = new RSAKey();

-					

-					var kp = publickeyHex.slice(56,314);

-					

-					output += "PUBLISHER KEY(hex): "+kp ;

-					

-					output+= "<br />";

-					output+= "<br />";

-					

-					console.log('kp is '+kp);

-					

-					var exp = publickeyHex.slice(318,324);

-					

-					console.log('kp size is '+kp.length );

-					output += "exponent: "+exp ;

-					

-					output+= "<br />";

-					output+= "<br />";

-					

-					console.log('exp is '+exp);

-					

-					

-					rsakey.setPublic(kp,exp);

-

-				    var result = rsakey.verifyString(input, signature);*/

-					

-					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]);

-				}

-			}

-			

-			document.getElementById('result').innerHTML = output;

-			

-		}

-

-	</script>

-

-</head>

-<body >

-	<form>

-		

-		Please Enter a Content Name:<br />

-		

-		<input id="contentname" type="text" name="CONTENTNAME" value="/PARC/abc" /> 

-		

-		Please Enter the Content:<br />

-		

-		<textarea id="content" cols="40" rows="5" name="CONTENT" value="SUCCESS"  >SUCCESS!</textarea> 

-		

-	</form>

-	<button onclick="encode()">Encode</button>

-	<button onclick="decode()">Decode</button>

-	

-	

-

-		<p id="result"></p>

-

-</body>

-</html>
\ No newline at end of file
diff --git a/js/testing/test-name.html b/js/testing/test-name.html
new file mode 100644
index 0000000..713423b
--- /dev/null
+++ b/js/testing/test-name.html
@@ -0,0 +1,110 @@
+<?xml version = "1.0" encoding="utf-8" ?>

+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

+"DTD/xhtml1-strict.dtd">

+<html xmlns = "http://www.w3.org/1999/xhtml">

+

+<head>

+	<title>NDN Name</title>

+	

+	<script type="text/javascript" src="../Helper.js"></script>

+

+	<script type="text/javascript">

+	

+function testName() {

+    var result = document.getElementById('result');

+    result.innerHTML = "";

+    

+    var comp1 = new Uint8Array(1); 

+    comp1.set(['.'.charCodeAt(0)]);

+    

+    var ab2 = new ArrayBuffer(4); 

+    var comp2 = new Uint8Array(ab2); 

+    comp2.set([0x00, 0x01, 0x02, 0x03]);

+

+    // \u00E9 is e with accent.

+    var entree = "entr\u00E9e";

+

+    // When Name constructor is passed an array, each item is a name component represented with ArrayBuffer, 

+    //   typed array, or string (parsed as UTF-8)

+    var name1 = new Name([entree, comp1, ab2]);

+    var name1Uri = name1.to_uri();

+    var name1UriExpected = "/entr%C3%A9e/..../%00%01%02%03";

+    result.innerHTML += "Name from '" + entree + "', Uint8Array of '.' and ArrayBuffer of 0,1,2,3:<br>";

+    if (name1Uri == name1UriExpected)

+        result.innerHTML += "SUCCESS: " + name1Uri + ".<br>";

+    else

+        result.innerHTML += "ERROR: got " + name1Uri + ", expected " + name1UriExpected + " .<br>";

+

+    result.innerHTML += "Compare with same Name from '" + entree + "', '.' and ArrayBuffer:<br>";

+    // Equivalent with name1

+    var name2 = new Name([entree, ".", comp2]);

+    if (name2.components.length != name1.components.length)

+        result.innerHTML += "ERROR: Got name with " + name2.components.length + 

+            " components, expected " + name1.components.length + ".<br>";

+    else {

+        var allEqual = true;

+        for (var i = 0; i < name1.components.length; ++i) {

+            if (!DataUtils.arraysEqual(name1.components[i], name2.components[i])) {

+                allEqual = false;

+                result.innerHTML += "ERROR: Names differ at component at index " + i + ".<br>";

+            }

+        }

+        if (allEqual)

+            result.innerHTML += "SUCCESS: Names are equal.<br>";

+    }

+    

+    result.innerHTML += "Compare with same Name from URI:<br>";

+    // Equivalent with name1; when Name constructor is passed a string, it is treated as a URI

+    var name3 = new Name("/entr%C3%A9e/..../%00%01%02%03");

+    if (name3.components.length != name1.components.length)

+        result.innerHTML += "ERROR: Got name with " + name3.components.length + 

+            " components, expected " + name1.components.length + ".<br>";

+    else {

+        var allEqual = true;

+        for (var i = 0; i < name1.components.length; ++i) {

+            if (!DataUtils.arraysEqual(name1.components[i], name3.components[i])) {

+                allEqual = false;

+                result.innerHTML += "ERROR: Names differ at component at index " + i + ".<br>";

+            }

+        }

+        if (allEqual)

+            result.innerHTML += "SUCCESS: Names are equal.<br>";

+    }    

+    

+    result.innerHTML += "Compare with Name prefix of first 2 components:<br>";

+    // Returns new Name([entree, "."])

+    var name4 = name2.getPrefix(2);

+    if (name4.components.length != 2)

+        result.innerHTML += "ERROR: Got name with " + name4.components.length + 

+            " components, expected 2.<br>";

+    else {

+        var allEqual = true;

+        for (var i = 0; i < name4.components.length; ++i) {

+            if (!DataUtils.arraysEqual(name1.components[i], name4.components[i])) {

+                allEqual = false;

+                result.innerHTML += "ERROR: Names differ at component at index " + i + ".<br>";

+            }

+        }

+        if (allEqual)

+            result.innerHTML += "SUCCESS: First 2 components are equal: " + name4.to_uri() + " .<br>";

+    }    

+    

+    result.innerHTML += "Check with Name component at index 2:<br>";

+    // Returns ArrayBuffer of "%00%01%02%03"

+    var component2Out = new Uint8Array(name1.getComponent(2));

+    if (DataUtils.arraysEqual(component2Out, comp2))

+        result.innerHTML += "SUCCESS: Components at index 2 are equal.<br>";

+    else

+        result.innerHTML += "ERROR: Components at index 2 are different.<br>";

+}

+

+	</script>

+

+</head>

+<body >

+	<button onclick="testName()">Test</button>

+	

+	<p id="result"></p>

+

+</body>

+</html>