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;
+	}
+
+};
