diff --git a/js/encoding/BinaryXMLCodec.js b/js/encoding/BinaryXMLCodec.js
new file mode 100644
index 0000000..b1befdd
--- /dev/null
+++ b/js/encoding/BinaryXMLCodec.js
@@ -0,0 +1,271 @@
+/*
+ * This class is used to encode and decode binary elements ( blog, type/value pairs)
+ * 
+ * @author: ucla-cs
+ */
+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 TypeAndVal = function TypeAndVal(_type,_val) {
+	this.type = _type;
+	this.val = _val;
+	
+};
+
+var BinaryXMLCodec = function BinaryXMLCodec(){
+	this.CODEC_NAME = "Binary";
+};
+    
+
+
+BinaryXMLCodec.prototype.encodeTypeAndValOffset = function(
+	//int
+	type,
+	//long
+	val,
+	//byte []
+	buf,
+	//int
+	offset) {
+	
+	if ((type > XML_UDATA) || (type < 0) || (val < 0)) {
+		throw new Exception("Tag and value must be positive, and tag valid.");
+	}
+	
+	// Encode backwards. Calculate how many bytes we need:
+	var/*int*/ numEncodingBytes = numEncodingBytes(val);
+	
+	if ((offset + numEncodingBytes) > buf.length) {
+		throw new Exception("Buffer space of " + (buf.length-offset) + 
+											" bytes insufficient to hold " + 
+											numEncodingBytes + " of encoded type and value.");
+	}
+	
+
+	buf[offset + numEncodingBytes - 1] = 
+		(BYTE_MASK &
+					(((XML_TT_MASK & type) | 
+					 ((XML_TT_VAL_MASK & val) << XML_TT_BITS))) |
+					 XML_TT_NO_MORE); 
+	val = val >>> XML_TT_VAL_BITS;;
+
+	var /*int*/ i = offset + numEncodingBytes - 2;
+	while ((0 != val) && (i >= offset)) {
+		buf[i] = (BYTE_MASK &
+						    (val & XML_REG_VAL_MASK)); 
+		val = val >>> XML_REG_VAL_BITS;
+		--i;
+	}
+	
+	return numEncodingBytes;
+};
+
+
+BinaryXMLCodec.prototype.encodeTypeAndVal = function(
+		//int
+		type, 
+		//long 
+		val, 
+		//byte [] 
+		buf, 
+		//int 
+		offset) {
+	
+	if ((type > XML_UDATA) || (type < 0) || (val < 0)) {
+		throw new Exception("Tag and value must be positive, and tag valid.");
+	}
+	
+	// Encode backwards. Calculate how many bytes we need:
+	//int
+	var numEncodingBytes = numEncodingBytes(val);
+	
+	if ((offset + numEncodingBytes) > buf.length) {
+		throw new Exception("Buffer space of " + (buf.length-offset) + 
+											" bytes insufficient to hold " + 
+											numEncodingBytes + " of encoded type and value.");
+	}
+	
+	// Bottom 4 bits of val go in last byte with tag.
+	buf[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 = offset + numEncodingBytes - 2;
+	while ((0 != val) && (i >= offset)) {
+		buf[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 Exception( "This should not happen: miscalculated encoding");
+		//Log.warning(Log.FAC_ENCODING, "This should not happen: miscalculated encoding length, have " + val + " left.");
+	}
+	
+	return numEncodingBytes;
+}
+
+
+	
+BinaryXMLCodec.prototype.decodeTypeAndVal = function(
+		/*InputStream*/
+		istream) {
+	
+	/*int*/next;
+	/*int*/type = -1;
+	/*long*/val = 0;
+	/*boolean*/more = true;
+
+	do {
+		next = istream.read();
+		
+		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);
+		}
+		
+	} while (more);
+	
+	return new TypeAndVal(type, val);
+};
+
+BinaryXMLCodec.prototype.encodeUString = function(
+		//OutputStream 
+		ostream, 
+		//String 
+		ustring, 
+		//byte 
+		type,
+		offset) {
+	
+	// We elide the encoding of a 0-length UString
+	if ((null == ustring) || (ustring.length == 0)) {
+		//if (Log.isLoggable(Log.FAC_ENCODING, Level.FINER))
+			//Log.finer(Log.FAC_ENCODING, "Eliding 0-length UString.");
+		return;
+	}
+	
+	//byte [] data utils
+	/*custom*/
+	//byte[]
+	strBytes = new Array(ustring.Length);
+	var i = 0;
+	for( ;i<ustring.lengh;i++) //in InStr.ToCharArray())
+	{
+		strBytes[i] = ustring[i];
+	}
+	//strBytes = DataUtils.getBytesFromUTF8String(ustring);
+	
+	this.encodeTypeAndVal(type, 
+						(((type == XML_TAG) || (type == XML_ATTR)) ?
+								(strBytes.length-1) :
+								strBytes.length), ostream);
+	//
+	//console.log(strBytes.toString());
+	
+	ostream.write(strBytes.toString(),offset);
+	
+	// 
+};
+
+BinaryXMLCodec.prototype.encodeBlob = function(
+		//OutputStream 
+		ostream, 
+		//byte [] 
+		blob, 
+		//int 
+		offset, 
+		//int 
+		length) {
+	// We elide the encoding of a 0-length blob
+	if ((null == blob) || (length == 0)) {
+
+		return;
+	}
+	
+	encodeTypeAndVal(XML_BLOB, length, ostream,offset);
+	if (null != blob) {
+		ostream.write(blob, this.offset, length);
+		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);
+
+var 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);
+}
+
+//TODO
\ No newline at end of file
diff --git a/js/encoding/BinaryXMLDecoder.js b/js/encoding/BinaryXMLDecoder.js
new file mode 100644
index 0000000..f70cca4
--- /dev/null
+++ b/js/encoding/BinaryXMLDecoder.js
@@ -0,0 +1,654 @@
+/*
+ * This class is used to encode and decode binary elements ( blog, type/value pairs)
+ * 
+ * @author: ucla-cs
+ */
+
+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;
+	//console.log('istream is '+ this.istream);
+	this.offset = 0;
+};
+
+
+BinaryXMLDecoder.prototype.readStartElement =function(
+	//String
+	startTag,				    
+	//TreeMap<String, String>
+	attributes) {
+
+	try {
+		//this.TypeAndVal 
+		tv = this.decodeTypeAndVal(this.istream);
+
+		if (null == tv) {
+			throw new Exception("Expected start element: " + startTag + " got something not a tag.");
+		}
+		
+		//String 
+		decodedTag = null;
+		
+		if (tv.type() == XML_TAG) {
+			
+			decodedTag = this.decodeUString(this.Istream, tv.val()+1);
+			
+		} else if (tv.type() == XML_DTAG) {
+			decodedTag = tagToString(tv.val());	
+		}
+		
+		if ((null ==  decodedTag) || decodedTag != startTag) {
+			throw new Exception("Expected start element: " + startTag + " got: " + decodedTag + "(" + tv.val() + ")");
+		}
+		
+		if (null != attributes) {
+			readAttributes(attributes); 
+		}
+		
+	} catch (e) {
+		throw new Exception("readStartElement", e);
+	}
+};
+
+BinaryXMLDecoder.prototype.readAttributes = function(
+	//TreeMap<String,String> 
+	attributes){
+	
+	if (null == attributes) {
+		return;
+	}
+
+	try {
+
+		//this.TypeAndVal 
+		nextTV = this.peekTypeAndVal(this.istream);
+
+		while ((null != nextTV) && ((XML_ATTR == nextTV.type()) ||
+				(XML_DATTR == nextTV.type()))) {
+
+			//this.TypeAndVal 
+			thisTV = this.decodeTypeAndVal(this.Istream);
+
+			var attributeName = null;
+			if (XML_ATTR == thisTV.type()) {
+				
+				attributeName = this.decodeUString(this.istream, thisTV.val()+1);
+
+			} else if (XML_DATTR == thisTV.type()) {
+				// DKS TODO are attributes same or different dictionary?
+				attributeName = tagToString(thisTV.val());
+				if (null == attributeName) {
+					throw new ContentDecodingException("Unknown DATTR value" + thisTV.val());
+				}
+			}
+			
+			var attributeValue = this.decodeUString(this.istream);
+
+			attributes.put(attributeName, attributeValue);
+
+			nextTV = this.peekTypeAndVal(this.istream);
+		}
+
+	} catch ( e) {
+
+		throw new ContentDecodingException("readStartElement", e);
+	}
+};
+
+
+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);
+		
+		//try {
+			//TypeAndVal 
+			tv = this.decodeTypeAndVal(this.istream);
+			
+			if (null == tv) {
+				throw new Exception("Expected start element: " + startTag + " got something not a tag.");
+			}
+			
+			//String 
+			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(this.istream,  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 '+ startag + ' but got '+ decodedTag);
+				throw new Exception("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); 
+			}
+			
+		//} catch ( e) {
+			//console.log(e);
+			//throw new Exception("readStartElement", e);
+		//}
+	}
+	
+
+BinaryXMLDecoder.prototype.readAttributes = function(
+	//TreeMap<String,String> 
+	attributes) {
+	
+	if (null == attributes) {
+		return;
+	}
+
+	try {
+		// Now need to get attributes.
+		//TypeAndVal 
+		nextTV = this.peekTypeAndVal(this.istream);
+
+		while ((null != nextTV) && ((XML_ATTR == nextTV.type()) ||
+				(XML_DATTR == nextTV.type()))) {
+
+			// Decode this attribute. First, really read the type and value.
+			//this.TypeAndVal 
+			thisTV = this.decodeTypeAndVal(this.istream);
+
+			//String 
+			attributeName = null;
+			if (XML_ATTR == thisTV.type()) {
+				// Tag value represents length-1 as attribute names cannot be empty.
+				var valval ;
+				if(typeof tv.val() == 'string'){
+					valval = (parseInt(tv.val())) + 1;
+				}
+				else
+					valval = (tv.val())+ 1;
+				
+				attributeName = this.decodeUString(this.istream,valval);
+
+			} else if (XML_DATTR == thisTV.type()) {
+				// DKS TODO are attributes same or different dictionary?
+				attributeName = tagToString(thisTV.val());
+				if (null == attributeName) {
+					throw new Exception("Unknown DATTR value" + thisTV.val());
+				}
+			}
+			// Attribute values are always UDATA
+			//String
+			attributeValue = this.decodeUString(this.istream);
+
+			//
+			attributes.push([attributeName, attributeValue]);
+
+			nextTV = this.peekTypeAndVal(this.istream);
+		}
+
+	} catch ( e) {
+		Log.logStackTrace(Log.FAC_ENCODING, Level.WARNING, e);
+		throw new Exception("readStartElement", e);
+	}
+};
+
+//returns a string
+BinaryXMLDecoder.prototype.peekStartElementAsString = function() {
+	//this.istream.mark(MARK_LEN);
+
+	//String 
+	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 
+		tv = this.decodeTypeAndVal(this.istream);
+
+		if (null != tv) {
+
+			if (tv.type() == XML_TAG) {
+				/*if (tv.val()+1 > DEBUG_MAX_LEN) {
+					throw new ContentDecodingException("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(this.istream, 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("Cannot reset stream! " + e.getMessage(), e);
+		}
+	}
+	return decodedTag;
+};
+
+BinaryXMLDecoder.prototype.peekStartElement = function(
+		//String 
+		startTag) {
+	//String 
+	if(typeof startTag == 'string'){
+		decodedTag = this.peekStartElementAsString();
+		
+		if ((null !=  decodedTag) && decodedTag == startTag) {
+			return true;
+		}
+		return false;
+	}
+	else if(typeof startTag == 'number'){
+		decodedTag = this.peekStartElementAsLong();
+		if ((null !=  decodedTag) && decodedTag == startTag) {
+			return true;
+		}
+		return false;
+	}
+	else{
+		throw new Exception("SHOULD BE STRING OR NUMBER");
+	}
+}
+//returns Long
+BinaryXMLDecoder.prototype.peekStartElementAsLong = function() {
+		//this.istream.mark(MARK_LEN);
+
+		//Long
+		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
+			tv = this.decodeTypeAndVal(this.istream);
+
+			if (null != tv) {
+
+				if (tv.type() == XML_TAG) {
+					if (tv.val()+1 > DEBUG_MAX_LEN) {
+						throw new ContentDecodingException("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 
+					strTag = this.decodeUString(this.istream, 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 Exception("Cannot reset stream! " + e.getMessage(), e);
+			}
+		}
+		return decodedTag;
+	};
+
+
+// returns a byte[]
+BinaryXMLDecoder.prototype.readBinaryElement = function(
+		//long 
+		startTag,
+		//TreeMap<String, String> 
+		attributes){
+	//byte [] 
+	blob = null;
+	
+		this.readStartElement(startTag, attributes);
+		blob = this.readBlob();
+	
+
+	return blob;
+
+};
+	
+	
+BinaryXMLDecoder.prototype.readEndElement = function(){
+		try {
+			var next = this.istream[this.offset]; 
+			this.offset++;
+			//read();
+			if (next != XML_CLOSE) {
+				throw new ContentDecodingException("Expected end element, got: " + next);
+			}
+		} catch ( e) {
+			throw new ContentDecodingException(e);
+		}
+	};
+
+
+//String	
+BinaryXMLDecoder.prototype.readUString = function(){
+			//String 
+			ustring = this.decodeUString(this.istream);	
+			this.readEndElement();
+			return ustring;
+
+	};
+	
+
+//returns a byte[]
+BinaryXMLDecoder.prototype.readBlob = function() {
+			//byte []
+			
+			blob = this.decodeBlob(this.istream);	
+			this.readEndElement();
+			return blob;
+
+	};
+
+
+//CCNTime
+BinaryXMLDecoder.prototype.readDateTime = function(
+	//long 
+	startTag)  {
+	//byte [] 
+	
+	byteTimestamp = this.readBinaryElement(startTag);
+	//CCNTime 
+	timestamp = new CCNTime();
+	timestamp.setDateBinary(byteTimestamp);
+	
+	if (null == timestamp) {
+		throw new ContentDecodingException("Cannot parse timestamp: " + DataUtils.printHexBytes(byteTimestamp));
+	}		
+	return timestamp;
+};
+
+BinaryXMLDecoder.prototype.decodeTypeAndVal = function(
+		/*InputStream*/
+		istream) {
+	
+	/*int*/next;
+	/*int*/type = -1;
+	/*long*/val = 0;
+	/*boolean*/more = true;
+
+	
+	//var savedOffset = this.offset;
+	var count = 0;
+	
+	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);
+	
+	return new TypeAndVal(type, val);
+};
+
+
+
+//TypeAndVal
+BinaryXMLDecoder.peekTypeAndVal = function(
+		//InputStream 
+		istream) {
+	//TypeAndVal 
+	tv = null;
+	
+	//istream.mark(LONG_BYTES*2);		
+	
+	var previousOffset = this.offset;
+	
+	try {
+		tv = this.decodeTypeAndVal(this.istream);
+	} finally {
+		//istream.reset();
+		this.offset = previousOffset;
+	}
+	
+	return tv;
+};
+
+
+//byte[]
+BinaryXMLDecoder.prototype.decodeBlob = function(
+		//InputStream 
+		istream, 
+		//int 
+		blobLength) {
+	
+	
+	if(null == blobLength){
+		//TypeAndVal
+		tv = this.decodeTypeAndVal(this.istream);
+
+		var valval ;
+		if(typeof tv.val() == 'string'){
+			valval = (parseInt(tv.val()));
+		}
+		else
+			valval = (tv.val());
+		
+		//console.log('valval here is ' + valval);
+		return  this.decodeBlob(this.istream, valval);
+	}
+	
+	//
+	//byte [] 
+
+	bytes = this.istream.slice(this.offset, this.offset+ blobLength);
+	this.offset += blobLength;
+	
+	//int 
+	return bytes;
+	
+	count = 0;
+
+};
+
+
+
+//String
+BinaryXMLDecoder.prototype.decodeUString = function(
+		//InputStream 
+		istream, 
+		//int 
+		byteLength) {
+	
+	if(null == byteLength){
+		tv = this.decodeTypeAndVal(this.istream);
+		var valval ;
+		if(typeof tv.val() == 'string'){
+			valval = (parseInt(tv.val()));
+		}
+		else
+			valval = (tv.val());
+		
+		byteLength= this.decodeUString(this.istream, valval);
+	}
+
+	stringBytes = this.decodeBlob(this.istream, byteLength);
+	
+	tempBuffer = this.istream.slice(this.offset, this.offset+byteLength);
+	this.offset+= byteLength;
+	console.log('read the String' + tempBuffer.toString('ascii'));
+	return tempBuffer.toString('ascii');//DataUtils.getUTF8StringFromBytes(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;
+};
+//TODO
\ No newline at end of file
diff --git a/js/encoding/BinaryXMLEncoder.js b/js/encoding/BinaryXMLEncoder.js
new file mode 100644
index 0000000..f05a869
--- /dev/null
+++ b/js/encoding/BinaryXMLEncoder.js
@@ -0,0 +1,340 @@
+/*
+ * This class is used to encode and decode binary elements ( blog, type/value pairs)
+ * 
+ * @author: ucla-cs
+ */
+
+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 Array(10000);
+	
+	
+	this.offset =0;
+	
+	this.CODEC_NAME = "Binary";
+	
+};
+
+BinaryXMLEncoder.prototype.writeUString = function(/*String*/ utf8Content){
+	this.encodeUString(this.ostream, utf8Content);
+};
+
+BinaryXMLEncoder.prototype.writeBlob = function(/*byte []*/ binaryContent
+		//, /*int*/ offset, /*int*/ length
+		)  {
+	console.log(binaryContent);
+	this.encodeBlob(this.ostream, binaryContent, this.offset, binaryContent.length);
+};
+
+BinaryXMLEncoder.prototype.writeStartElement = function(/*String*/ tag, /*TreeMap<String,String>*/ attributes){
+
+	/*Long*/ dictionaryVal = tag;//stringToTag(tag);
+	
+	if (null == dictionaryVal) {
+
+		this.encodeUString(this.ostream, tag, XML_TAG);
+		
+	} else {
+		this.encodeTypeAndVal(XML_DTAG, dictionaryVal, this.ostream);
+	}
+	
+	if (null != attributes) {
+		this.writeAttributes(attributes); 
+	}
+};
+
+
+BinaryXMLEncoder.prototype.writeEndElement = function(){
+
+	this.ostream[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(this.ostream, strAttr, XML_ATTR);
+		} else {
+			this.encodeTypeAndVal(XML_DATTR, dictionaryAttr, this.ostream);
+		}
+		// Write value
+		this.encodeUString(this.ostream, 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;
+};
+
+
+BinaryXMLEncoder.prototype.writeElement = function(
+		//long 
+		tag, 
+		//byte[] 
+		binaryContent,
+		//TreeMap<String, String> 
+		attributes) {
+	this.writeStartElement(tag, attributes);
+	// Will omit if 0-length
+	
+	this.writeBlob(binaryContent);
+	this.writeEndElement();
+}
+
+//TODO
+
+var TypeAndVal = function TypeAndVal(_type,_val) {
+	this.type = _type;
+	this.val = _val;
+	
+};
+
+BinaryXMLEncoder.prototype.encodeTypeAndVal = function(
+		//int
+		type, 
+		//long 
+		val, 
+		//byte [] 
+		buf) {
+	
+	console.log('Encoding type '+ type+ ' and value '+ val);
+	
+	if ((type > XML_UDATA) || (type < 0) || (val < 0)) {
+		throw new Exception("Tag and value must be positive, and tag valid.");
+	}
+	
+	// Encode backwards. Calculate how many bytes we need:
+	var numEncodingBytes = this.numEncodingBytes(val);
+	
+	if ((this.offset + numEncodingBytes) > buf.length) {
+		throw new Exception("Buffer space of " + (buf.length-this.offset) + 
+											" bytes insufficient to hold " + 
+											numEncodingBytes + " of encoded type and value.");
+	}
+
+	// Bottom 4 bits of val go in last byte with tag.
+	buf[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)) {
+		buf[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 Exception( "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;
+};
+
+BinaryXMLEncoder.prototype.encodeUString = function(
+		//OutputStream 
+		ostream, 
+		//String 
+		ustring, 
+		//byte 
+		type) {
+	
+	if ((null == ustring) || (ustring.length == 0)) {
+		return;
+	}
+	
+	
+	//byte [] data utils
+	/*custom*/
+	//byte[]
+	strBytes = new Array(ustring.Length);
+	var i = 0;
+	for( ;i<ustring.lengh;i++) //in InStr.ToCharArray())
+	{
+		strBytes[i] = ustring[i];
+	}
+	//strBytes = DataUtils.getBytesFromUTF8String(ustring);
+	
+	this.encodeTypeAndVal(type, 
+						(((type == XML_TAG) || (type == XML_ATTR)) ?
+								(strBytes.length-1) :
+								strBytes.length), ostream);
+	
+
+	this.writeString(strBytes,this.offset);
+	
+	this.offset+= strBytes.length;
+
+};
+
+
+
+BinaryXMLEncoder.prototype.encodeBlob = function(
+		//OutputStream 
+		ostream, 
+		//byte [] 
+		blob, 
+		//int 
+		offset, 
+		//int 
+		length) {
+
+
+	if ((null == blob) || (length == 0)) {
+
+		return;
+	}
+	
+	
+	this.encodeTypeAndVal(XML_BLOB, length, ostream,offset);
+	
+	if (null != blob) {
+
+		this.writeString(blob,this.offset);
+		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) {
+	this.writeElement(tag, dateTime.toBinaryTime());
+};
+
+BinaryXMLEncoder.prototype.writeString = function(
+		//String 
+		input,
+		//CCNTime 
+		offset) {
+	
+	
+	for (var i = 0; i < input.length; i++) {
+	    this.ostream[this.offset+i] = (input.charCodeAt(i));
+	}
+	
+};
+
+BinaryXMLEncoder.prototype.writeBlobArray = function(
+		//String 
+		Blob,
+		//CCNTime 
+		offset) {
+	
+	for (var i = 0; i < Blob.length; i++) {
+	    this.ostream[this.offset+i] = Blob[i];
+	}
+	
+};
+BinaryXMLEncoder.prototype.getReducedOstream = function() {
+	
+	return this.ostream.slice(0,this.offset);
+	
+};
+
diff --git a/js/encoding/DataUtils.js b/js/encoding/DataUtils.js
new file mode 100644
index 0000000..92a4257
--- /dev/null
+++ b/js/encoding/DataUtils.js
@@ -0,0 +1,137 @@
+
+/*
+ * This class contains utilities to help parse the data
+ * author: ucla-cs
+ */
+ 
+var DataUtils = function DataUtils(){
+	
+	
+};
+
+
+/*
+ * NOTE THIS IS CURRENTLY NOT BEHING USED
+ * 
+ */
+
+  var keyStr = "ABCDEFGHIJKLMNOP" +
+               "QRSTUVWXYZabcdef" +
+               "ghijklmnopqrstuv" +
+               "wxyz0123456789+/" +
+               "=";
+
+DataUtils.encode64=function encode64(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 +
+           keyStr.charAt(enc1) +
+           keyStr.charAt(enc2) +
+           keyStr.charAt(enc3) +
+           keyStr.charAt(enc4);
+        chr1 = chr2 = chr3 = "";
+        enc1 = enc2 = enc3 = enc4 = "";
+     } while (i < input.length);
+
+     return output;
+  }
+
+DataUtils.decode64 = function decode64(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;
+     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 = keyStr.indexOf(input.charAt(i++));
+        enc2 = keyStr.indexOf(input.charAt(i++));
+        enc3 = keyStr.indexOf(input.charAt(i++));
+        enc4 = 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 [] 
+DataUtils.prototype.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
+	var offset = -1;
+	for(var i = 7; i >=0; --i) {
+		//byte
+		b = ((value >> (i * 8)) & 0xFF);
+		if( out == null && b != 0 ) {
+			out = new byte[i+1];
+			offset = i;
+		}
+		if( out != null )
+			out[ offset - i ] = b;
+	}
+	return out;
+}
+
+
+
+
diff --git a/js/encoding/TextXMLCodec.js b/js/encoding/TextXMLCodec.js
new file mode 100644
index 0000000..716aa6d
--- /dev/null
+++ b/js/encoding/TextXMLCodec.js
@@ -0,0 +1,59 @@
+//TODO INCOMPLETE
+/*
+ * @author: ucla-cs
+ * 
+ * Encodes CCN object into xml tags
+ */
+var DataUtils = require('./DataUtils').DataUtils;
+	
+ 	var /*DateFormat*/ canonicalWriteDateFormat = null;
+	var /* DateFormat*/ canonicalReadDateFormat = null;
+    var /*String*/ PAD_STRING = "000000000";
+	var /*int*/ NANO_LENGTH = 9;
+
+var TextXMLCodec =  function TextXMLCodec(){
+
+	this.CCN_NAMESPACE = "http://www.parc.com/ccn"; // String
+	this.CCN_PREFIX = "ccn";	// String
+	this.CODEC_NAME = "Text";// String
+	this.BINARY_ATTRIBUTE = "ccnbencoding";// String
+	this.BINARY_ATTRIBUTE_VALUE = "base64Binary";// String
+
+
+};
+
+//returns a string
+
+TextXMLCodec.protpotype.codecName = function() { return this.CODEC_NAME; }	;
+
+//returns a string
+TextXMLCodec.protottype.encodeBinaryElement = function(/*byte []*/ element) {
+		if ((null == element) || (0 == element.length)) 
+			return new String("");
+		return new String(DataUtils.base64Encode(element));
+	};
+	
+/* returns a string */
+TextXMLCodec.prototype.encodeBinaryElement = function(/*byte []*/ element, /*int*/ offset, /*int*/ length) {
+		if ((null == element) || (0 == element.length)) 
+			return new String("");
+		ByteBuffer bbuf = ByteBuffer.wrap(element, offset, length);
+		return new String(DataUtils.base64Encode(bbuf.array()));
+	};
+
+/*returns a byte array*/
+TextXMLCodec.prototype.decodeBinaryElement = function(/*String*/ element) {
+		if ((null == element) || (0 == element.length()))
+			return new byte[0];
+		return DataUtils.base64Decode(element.getBytes());
+	}; 
+
+	
+/*
+	Decode Data
+*/
+	
+
+/*
+	Encode Date
+*/ 
\ No newline at end of file
diff --git a/js/encoding/TextXMLDecoder.js b/js/encoding/TextXMLDecoder.js
new file mode 100644
index 0000000..6af8be3
--- /dev/null
+++ b/js/encoding/TextXMLDecoder.js
@@ -0,0 +1,232 @@
+//TODO INCOMPLETE
+
+/*
+ * @author: ucla-cs
+ * 
+ * Decodes CCN object into xml
+ */
+
+var TextXMLDecoder = function TextXMLDecoder(){
+
+	this.reader = null;
+	
+};
+
+
+exports.TextXMLDecoder = TextXMLDecoder;
+
+
+exports.prototype.initializeDecoding = function(){
+	try {
+		XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+        factory.setNamespaceAware(true);
+		_reader = factory.newPullParser();
+		_reader.setInput(_istream, null);
+	} catch (XmlPullParserException e) {
+		throw new ContentDecodingException(e.getMessage(), e);
+	}		
+};
+
+exports.prototype.readStartDocument = function(){
+	try {
+		int event = _reader.getEventType();
+		_reader.next();
+		if (event != XmlPullParser.START_DOCUMENT) {
+			throw new ContentDecodingException("Expected start document, got: " + XmlPullParser.TYPES[event]);
+		}
+	} catch (XmlPullParserException e) {
+		throw new ContentDecodingException(e.getMessage(), e);
+	} catch (IOException e) {
+		throw new ContentDecodingException(e.getMessage(), e);
+	}
+};
+
+public void readEndDocument() throws ContentDecodingException {
+	int event;
+	try {
+		event = _reader.getEventType();
+	} catch (XmlPullParserException e) {
+		throw new ContentDecodingException(e.getMessage(), e);
+	}
+	if (event != XmlPullParser.END_DOCUMENT) {
+		throw new ContentDecodingException("Expected end document, got: " + XmlPullParser.TYPES[event]);
+	}
+};
+
+exports.prototype.readStartElement = function(/*String*/ startTag,
+							TreeMap<String, String> attributes) throws ContentDecodingException {
+
+	int event = readToNextTag(XmlPullParser.START_TAG);
+	if (event != XmlPullParser.START_TAG) {
+		throw new ContentDecodingException("Expected start element, got: " + XmlPullParser.TYPES[event]);
+	}
+	// Use getLocalPart to strip namespaces.
+	// Assumes we are working with a global default namespace of CCN.
+	if (!startTag.equals(_reader.getName())) {
+		// Coming back with namespace decoration doesn't match
+		throw new ContentDecodingException("Expected start element: " + startTag + " got: " + _reader.getName());
+	}	
+	if (null != attributes) {
+		// we might be expecting attributes
+		for (int i=0; i < _reader.getAttributeCount(); ++i) {
+			// may need fancier namespace handling.
+			attributes.put(_reader.getAttributeName(i), _reader.getAttributeValue(i));
+		}
+	}
+	try {
+		_reader.next();
+	} catch (XmlPullParserException e) {
+		throw new ContentDecodingException(e.getMessage());
+	} catch (IOException e) {
+		throw new ContentDecodingException(e.getMessage());
+	}
+}
+
+	public void readStartElement(long startTagLong,
+			TreeMap<String, String> attributes) throws ContentDecodingException {
+		
+		String startTag = tagToString(startTagLong);
+
+		int event = readToNextTag(XmlPullParser.START_TAG);
+		if (event != XmlPullParser.START_TAG) {
+			throw new ContentDecodingException("Expected start element, got: " + XmlPullParser.TYPES[event]);
+		}
+		// Use getLocalPart to strip namespaces.
+		// Assumes we are working with a global default namespace of CCN.
+		if (!startTag.equals(_reader.getName())) {
+			// Coming back with namespace decoration doesn't match
+			throw new ContentDecodingException("Expected start element: " + startTag + " got: " + _reader.getName());
+		}	
+		if (null != attributes) {
+			// we might be expecting attributes
+			for (int i=0; i < _reader.getAttributeCount(); ++i) {
+				// may need fancier namespace handling.
+				attributes.put(_reader.getAttributeName(i), _reader.getAttributeValue(i));
+			}
+		}
+		try {
+			_reader.next();
+		} catch (XmlPullParserException e) {
+			throw new ContentDecodingException(e.getMessage());
+		} catch (IOException e) {
+			throw new ContentDecodingException(e.getMessage());
+		}
+	}
+	public String peekStartElementAsString() throws ContentDecodingException {
+		int event = readToNextTag(XmlPullParser.START_TAG);
+		if (event != XmlPullParser.START_TAG) {
+			return null;
+		}
+		return _reader.getName();
+	}
+	
+	public Long peekStartElementAsLong() throws ContentDecodingException {
+		String strTag = peekStartElementAsString();
+		if (null == strTag) {
+			return null; // e.g. hit an end tag...
+		}
+		return stringToTag(strTag);
+	}
+	
+	/**
+	 * Helper method to decode text (UTF-8) and binary elements. Consumes the end element,
+	 * behavior which other decoders are forced to match.
+	 * @return the read data, as a String
+	 * @throws ContentDecodingException if there is a problem decoding the data
+	 */
+	public String readUString() throws ContentDecodingException {
+		StringBuffer buf = new StringBuffer();
+		try {
+			int event = _reader.getEventType();;
+			// Handles empty text element.
+			while (event == XmlPullParser.TEXT) {
+				buf.append(_reader.getText());
+				event = _reader.next();
+			}
+			if (event == XmlPullParser.START_TAG) {
+				throw new ContentDecodingException("readElementText expects start element to have been previously consumed, got: " + XmlPullParser.TYPES[event]);
+			} else if (event != XmlPullParser.END_TAG) {
+				throw new ContentDecodingException("Expected end of text element, got: " + XmlPullParser.TYPES[event]);
+			}
+			readEndElement();
+			return buf.toString();
+		} catch (XmlPullParserException e) {
+			throw new ContentDecodingException(e.getMessage(), e);
+		} catch (IOException e) {
+			throw new ContentDecodingException(e.getMessage(), e);
+		}
+	}
+
+	public void readEndElement() throws ContentDecodingException {
+		int event = readToNextTag(XmlPullParser.END_TAG);
+		if (event != XmlPullParser.END_TAG) {
+			throw new ContentDecodingException("Expected end element, got: " + XmlPullParser.TYPES[event]);
+		}
+		try {
+			_reader.next();
+		} catch (XmlPullParserException e) {
+			throw new ContentDecodingException(e.getMessage());
+		} catch (IOException e) {
+			throw new ContentDecodingException(e.getMessage());
+		}
+	}
+
+	/**
+	 * Read a BLOB. Consumes the end element, so force other versions
+	 * to match.
+	 */
+	public byte [] readBlob() throws ContentDecodingException {
+		try {
+			String strElementText = readUString();
+			// readEndElement(); // readElementText consumes end element
+			return TextXMLCodec.decodeBinaryElement(strElementText);
+		} catch (IOException e) {
+			throw new ContentDecodingException(e.getMessage(),e);
+		}
+	}
+	
+	public CCNTime readDateTime(String startTag) throws ContentDecodingException {
+		String strTimestamp = readUTF8Element(startTag);
+		CCNTime timestamp;
+		try {
+			timestamp = TextXMLCodec.parseDateTime(strTimestamp);
+		} catch (ParseException e) {
+			timestamp = null;
+		}
+		if (null == timestamp) {
+			throw new ContentDecodingException("Cannot parse timestamp: " + strTimestamp);
+		}		
+		return timestamp;
+	}
+
+	public CCNTime readDateTime(long startTag) throws ContentDecodingException {
+		String strTimestamp = readUTF8Element(startTag);
+		CCNTime timestamp;
+		try {
+			timestamp = TextXMLCodec.parseDateTime(strTimestamp);
+		} catch (ParseException e) {
+			timestamp = null;
+		}
+		if (null == timestamp) {
+			throw new ContentDecodingException("Cannot parse timestamp: " + strTimestamp);
+		}		
+		return timestamp;
+	}
+
+	private int readToNextTag(int type) throws ContentDecodingException {
+		int event;
+		try {
+			event = _reader.getEventType();
+			if (event == type)
+				return event;
+			if (event == XmlPullParser.TEXT || event == XmlPullParser.COMMENT)
+				event = _reader.next();
+		} catch (IOException e) {
+			throw new ContentDecodingException(e.getMessage(), e);
+		} catch (XmlPullParserException e) {
+			throw new ContentDecodingException(e.getMessage(), e);
+		}
+		return event;
+	}
+
+};
diff --git a/js/encoding/TextXMLEncoder.js b/js/encoding/TextXMLEncoder.js
new file mode 100644
index 0000000..495984b
--- /dev/null
+++ b/js/encoding/TextXMLEncoder.js
@@ -0,0 +1,109 @@
+//TODO INCOMPLETE
+/*
+ * @author: ucla-cs
+ * 
+ * Encodes CCN object into xml
+ */
+
+var Stream = require('stream').Stream;
+var TextXMLCodec = require('TextXMLCodec').TextXMLCodec;
+
+
+
+
+var TextXMLEncoder  = function TextXMLEncoder(){
+
+
+	this.ostream = new String();
+};
+
+exports.TextXMLEncoder = TextXMLEncoder;
+
+TextXMLEncoder.prototype.beginEncoding = function(/*OutputStream*/ ostream){
+		if (null == ostream)
+			throw new IllegalArgumentException("TextXMLEncoder: output stream cannot be null!");
+		
+		
+		/*Start by encoing the begining*/
+		//this.IStream = ostream;
+		this.ostream.write('<?xml version="1.0" encoding="UTF-8"?>');
+};
+
+TextXMLEncoder.prototype.endEncoding =function() {
+	this.IStream.end();
+}
+
+
+TextXMLEncoder.prorotype.writeStartElement(/*String*/ tag, /*TreeMap<String, String>*/ attributes) {
+		
+	
+		this.ostream.write('<'+tab);
+
+		if (null != attributes) {
+			
+			for(var i=0; i<attributes.length;i++){
+				this.ostream.write(' '+attributes[i].key +'='+attributes[i].value);
+			}
+		
+			// keySet of a TreeMap is ordered
+		}
+		this.ostream.write('>');
+};
+
+TextXMLEncoder.prototype.writeUString = function(/*String*/ utf8Content) {
+
+		this.ostream.write(utf8Content);
+
+};
+
+
+TextXMLEncoder.prototype.writeBlob =  function(/*byte []*/ binaryContent, /*int*/ offset, /*int*/ length) {
+
+		this.ostream.write(TextXMLCodec.encodeBinaryElement(binaryContent, offset, length));
+
+};
+
+TextXMLEncoder.prototype.writeElement = function(/*String*/ tag, /*byte[]*/ binaryContent,
+			/*TreeMap<String, String>*/ attributes)  {
+		
+		/*if (null == attributes) {
+		
+			attributes = new TreeMap<String,String>();
+		}*/
+		if (!attributes.containsKey(TextXMLCodec.BINARY_ATTRIBUTE)) {
+			attributes.put(TextXMLCodec.BINARY_ATTRIBUTE, TextXMLCodec.BINARY_ATTRIBUTE_VALUE);
+		}
+		super.writeElement(tag, binaryContent, attributes);
+}
+
+
+TextXMLEncoder.prototype.writeEndElement(tag) {
+
+		this.ostream.write('<'+tab+'>');
+
+	};
+
+	
+//returns number long
+stringToTag = function(/*String*/ tagName) {
+
+	if (null == tagName) {
+		return null;
+	}
+	Long tagVal = null;
+	if (null != _dictionaryStack) {
+		for (/*XMLDictionary*/ dictionary in _dictionaryStack) {
+			tagVal = dictionary.stringToTag(tagName);
+			if (null != tagVal) {
+				return tagVal;
+			}
+		}
+	}
+
+
+	if (XMLDictionaryStack.isUnknownTag(tagName)) {
+		return XMLDictionaryStack.decodeUnknownTag(tagName);
+	}
+	return null;
+};
+	
diff --git a/js/encoding/xml2object.js b/js/encoding/xml2object.js
new file mode 100644
index 0000000..c6711b6
--- /dev/null
+++ b/js/encoding/xml2object.js
@@ -0,0 +1,170 @@
+/**
+ * Simple xml 2 javascript object parser based on sax.js
+ * 
+ * https://github.com/emberfeather/node-xml2object
+ */
+var emitter = require('events').EventEmitter;
+var fs = require('fs');
+var sax = require('./sax');
+var util = require('util');
+
+var xml2object  = function(xmlFile, elements) {
+	elements = elements || [];
+	
+	this._hasStarted = false;
+
+	var self = this;
+	var currentObject;
+	var inObject = false;
+	var inObjectName;
+	var ancestors = [];
+
+	this.fileStream = fs.createReadStream(xmlFile);
+	this.saxStream = sax.createStream(true);
+
+	this.saxStream.on("opentag", function (args) {
+		if(!inObject) {
+			// If we are not in an object and not tracking the element
+			// then we don't need to do anything
+			if (elements.indexOf(args.name) < 0) {
+				return;
+			}
+
+			// Start tracking a new object
+			inObject = true;
+			inObjectName = args.name;
+
+			currentObject = {};
+		}
+
+		if (!(args.name in currentObject)) {
+			currentObject[args.name] = args.attributes;
+		} else if (!util.isArray(currentObject[args.name])) {
+			// Put the existing object in an array.
+			var newArray = [currentObject[args.name]];
+			
+			// Add the new object to the array.
+			newArray.push(args.attributes);
+			
+			// Point to the new array.
+			currentObject[args.name] = newArray;
+		} else {
+			// An array already exists, push the attributes on to it.
+			currentObject[args.name].push(args.attributes);
+		}
+
+		// Store the current (old) parent.
+		ancestors.push(currentObject);
+
+		// We are now working with this object, so it becomes the current parent.
+		if (currentObject[args.name] instanceof Array) {
+			// If it is an array, get the last element of the array.
+			currentObject = currentObject[args.name][currentObject[args.name].length - 1];
+		} else {
+			// Otherwise, use the object itself.
+			currentObject = currentObject[args.name];
+		}
+	});
+
+	this.saxStream.on("text", function (data) {
+		if(!inObject) {
+			return;
+		}
+
+		data = data.trim();
+
+		if (!data.length) {
+			return;
+		}
+
+		currentObject['$t'] = (currentObject['$t'] || "") + data;
+	});
+
+	this.saxStream.on("closetag", function (name) {
+		if(!inObject) {
+			return;
+		}
+
+		if(inObject && inObjectName === name) {
+			// Finished building the object
+			self.emit('object', name, currentObject);
+
+			inObject = false;
+			ancestors = [];
+
+			return;
+		}
+
+		if(ancestors.length) {
+			var ancestor = ancestors.pop();
+			var keys = Object.keys(currentObject);
+
+			if (keys.length == 1 && '$t' in currentObject) {
+				// Convert the text only objects into just the text
+				if (ancestor[name] instanceof Array) {
+					ancestor[name].push(ancestor[name].pop()['$t']);
+				} else {
+					ancestor[name] = currentObject['$t'];
+				}
+			} else if (!keys.length) {
+				// Remove empty keys
+				delete ancestor[name];
+			}
+
+			currentObject = ancestor;
+		} else {
+			currentObject = {};
+		}
+	});
+
+	// Rebroadcast the error and keep going
+	this.saxStream.on("error", function (e) {
+		this.emit('error', e);
+
+		// clear the error and resume
+		this._parser.error = null;
+		this._parser.resume();
+	});
+
+	// Rebroadcast the end of the file read
+	this.fileStream.on("end", function() {
+		self.emit("end");
+	});
+};
+
+util.inherits(xml2object, emitter);
+
+xml2object.prototype.start = function() {
+	// Can only start once
+	if(this._hasStarted) {
+		return;
+	}
+
+	this._hasStarted = true;
+
+	this.emit('start');
+
+	// Start the streaming!
+	this.fileStream.pipe(this.saxStream);
+};
+
+
+//TEST///////////////////////////////////////////////////////////////////////////////
+//var xml2object = require('xml2object');
+
+// Create a new xml parser with an array of xml elements to look for
+/*var parser = new xml2object('./src/encoding/ContentObject1.xml', [ 'ContentObject' ]);
+
+// Bind to the object event to work with the objects found in the XML file
+parser.on('object', function(name, obj) {
+    console.log('Found an object: %s', name);
+    console.log(obj);
+});
+
+// Bind to the file end event to tell when the file is done being streamed
+parser.on('end', function(name, obj) {
+    console.log('Finished parsing xml!');
+});
+
+// Start parsing the XML
+parser.start();*/
\ No newline at end of file
