first commit
diff --git a/src/CCNProtocolDTags.js b/src/CCNProtocolDTags.js
new file mode 100644
index 0000000..cab4a4c
--- /dev/null
+++ b/src/CCNProtocolDTags.js
@@ -0,0 +1,125 @@
+
+
+
+exports.CCNProtocolDTags = {
+
+	/**
+	 * Note if you add one of these, add it to the reverse string map as well.
+	 * Emphasize getting the work done at compile time over trying to make something
+	 * flexible and developer error-proof.
+	 */
+		
+	 Any : 13,
+	 Name : 14,
+	 Component : 15,
+	 Certificate : 16,
+	 Collection : 17,
+	 CompleteName : 18,
+	 Content : 19,
+	 SignedInfo : 20,
+	 ContentDigest : 21,
+	 ContentHash : 22,
+	 Count : 24,
+	 Header : 25,
+	 Interest : 26,	/* 20090915 */
+	 Key : 27,
+	 KeyLocator : 28,
+	 KeyName : 29,
+	 Length : 30,
+	 Link : 31,
+	 LinkAuthenticator : 32,
+	 NameComponentCount : 33,	/* DeprecatedInInterest */
+	 RootDigest : 36,
+	 Signature : 37,
+	 Start : 38,
+	 Timestamp : 39,
+	 Type : 40,
+	 Nonce : 41,
+	 Scope : 42,
+	 Exclude : 43,
+	 Bloom : 44,
+	 BloomSeed : 45,
+	 AnswerOriginKind : 47,
+	 InterestLifetime : 48,
+	 Witness : 53,
+	 SignatureBits : 54,
+	 DigestAlgorithm : 55,
+	 BlockSize : 56,
+	 FreshnessSeconds : 58,
+	 FinalBlockID : 59,
+	 PublisherPublicKeyDigest : 60,
+	 PublisherCertificateDigest : 61,
+	 PublisherIssuerKeyDigest : 62,
+	 PublisherIssuerCertificateDigest : 63,
+	 ContentObject : 64,	/* 20090915 */
+	 WrappedKey : 65,
+	 WrappingKeyIdentifier : 66,
+	 WrapAlgorithm : 67,
+	 KeyAlgorithm : 68,
+	 Label : 69,
+	 EncryptedKey : 70,
+	 EncryptedNonceKey : 71,
+	 WrappingKeyName : 72,
+	 Action : 73,
+	 FaceID : 74,
+	 IPProto : 75,
+	 Host : 76,
+	 Port : 77,
+	 MulticastInterface : 78,
+	 ForwardingFlags : 79,
+	 FaceInstance : 80,
+	 ForwardingEntry : 81,
+	 MulticastTTL : 82,
+	 MinSuffixComponents : 83,
+	 MaxSuffixComponents : 84,
+	 ChildSelector : 85,
+	 RepositoryInfo : 86,
+	 Version : 87,
+	 RepositoryVersion : 88,
+	 GlobalPrefix : 89,
+	 LocalName : 90,
+	 Policy : 91,
+	 Namespace : 92,
+	 GlobalPrefixName : 93,
+	 PolicyVersion : 94,
+	 KeyValueSet : 95,
+	 KeyValuePair : 96,
+	 IntegerValue : 97,
+	 DecimalValue : 98,
+	 StringValue : 99,
+	 BinaryValue : 100,
+	 NameValue : 101,
+	 Entry : 102,
+	 ACL : 103,
+	 ParameterizedName : 104,
+	 Prefix : 105,
+	 Suffix : 106,
+	 Root : 107,
+	 ProfileName : 108,
+	 Parameters : 109,
+	 InfoString : 110,
+	// 111 unallocated
+	 StatusResponse : 112,
+	 StatusCode : 113,
+	 StatusText : 114,
+
+	// Sync protocol
+	 SyncNode : 115,
+	 SyncNodeKind : 116,
+	 SyncNodeElement : 117,
+	 SyncVersion : 118,
+	 SyncNodeElements : 119,
+	 SyncContentHash : 120,
+	 SyncLeafCount : 121,
+	 SyncTreeDepth : 122,
+	 SyncByteCount : 123,
+	 ConfigSlice : 124,
+	 ConfigSliceList : 125,
+	 ConfigSliceOp : 126,
+
+	// Remember to keep in sync with schema/tagnames.csvsdict
+	 CCNProtocolDataUnit : 17702112,
+	 CCNPROTOCOL_DATA_UNIT : "CCNProtocolDataUnit"
+};
+
+
diff --git a/src/ContentName.js b/src/ContentName.js
new file mode 100644
index 0000000..54d70f9
--- /dev/null
+++ b/src/ContentName.js
@@ -0,0 +1,46 @@
+
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+var ContentName = function ContentName(_Components){
+
+
+	this.SCHEME = "ccnx:";
+
+	this.ORIGINAL_SCHEME = "ccn:";
+
+	this.SEPARATOR = "/";
+	this.ROOT = null;
+
+	this.Components = _Components;
+};
+
+exports.ContentName = ContentName;
+
+ContentName.prototype.decode = function(/*XMLDecoder*/ decoder)  {
+		decoder.readStartElement(this.getElementLabel());
+
+		this.Components = new Array(); //new ArrayList<byte []>();
+
+		while (decoder.peekStartElement(CCNProtocolDTags.Component)) {
+			this.Components.add(decoder.readBinaryElement(CCNProtocolDTags.Component));
+		}
+
+		decoder.readEndElement();
+};
+
+ContentName.prototype.encode = function(/*XMLEncoder*/ encoder)  {
+		//if (!validate()) {
+			//throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
+		//}
+
+		encoder.writeStartElement(this.getElementLabel());
+		var count = this.Components.length;
+		for (var i=0; i < count; ++i) {
+			encoder.writeElement(CCNProtocolDTags.Component, this.Components.get(i));
+		}
+		encoder.writeEndElement();
+};
+
+ContentName.prototype.getElementLabel = function(){
+	return CCNProtocolDTags.Name;
+};
diff --git a/src/ContentObject.js b/src/ContentObject.js
new file mode 100644
index 0000000..fb1ff09
--- /dev/null
+++ b/src/ContentObject.js
@@ -0,0 +1,61 @@
+
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+var ContentObject = function ContentObject(_Name,_SignedInfo,_Content,_Signature){
+	
+	
+	this.Name = _Name;
+	this.SignedInfo = _SignedInfo;
+	this.Content=_Content;
+	this.Signature = _Signature;
+
+};
+
+exports.ContentObject = ContentObject;
+
+
+ContentObject.prototype.decode = function(/*XMLDecoder*/ decoder) {
+	
+		decoder.readStartElement(this.getElementLabel());
+
+		this.Signature = new Signature();
+		this.Signature.decode(decoder);
+
+		this.Name = new ContentName();
+		this.Name.decode(decoder);
+
+		this.SignedInfo = new SignedInfo();
+		this.SignedInfo.decode(decoder);
+
+		this.Content = decoder.readBinaryElement(CCNProtocolDTags.Content);
+
+		decoder.readEndElement();
+
+};
+
+
+ContentObject.prototype.encode = function(/*XMLEncoder*/ encoder)  {
+	
+	if((null == this.Name) && (null==this.SignedInfo) && (null ==this.Signature)){
+		
+		throw "Illegal input inside encode of Content Object";
+	}
+	/* 
+	 * if (!validate()) {
+			throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
+		}*/
+		
+	encoder.writeStartElement(this.getElementLabel());
+
+	this.Signature.encode(encoder);
+	this.Name.encode(encoder);
+	this.SignedInfo.encode(encoder);
+
+	encoder.writeElement(CCNProtocolDTags.Content, this.Content);
+
+	encoder.writeEndElement();
+
+};
+
+
+ContentObject.prototype.getElementLabel= function(){returnCCNProtocolDTags.ContentObject;};
\ No newline at end of file
diff --git a/src/Exclude.js b/src/Exclude.js
new file mode 100644
index 0000000..667c8cf
--- /dev/null
+++ b/src/Exclude.js
@@ -0,0 +1,54 @@
+
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+var Exclude = function Exclude(_Values){ 
+	
+	this.OPTIMUM_FILTER_SIZE = 100;
+	
+
+	this.Values = _Values; //array of elements
+	
+}
+exports.Exclude = Exclude;
+
+Exclude.prototype.decode = function(/*XMLDecoder*/ decoder) {
+
+
+		
+		decoder.readStartElement(this.getElementLabel());
+
+			//TODO BUGS
+			/*var component;
+			var any = false;
+			while ((component = decoder.peekStartElement(CCNProtocolDTags.Component)) || 
+					(any = decoder.peekStartElement(CCNProtocolDTags.Any)) ||
+						decoder.peekStartElement(CCNProtocolDTags.Bloom)) {
+				var ee = component?new ExcludeComponent(): any ? new ExcludeAny() : new BloomFilter();
+				ee.decode(decoder);
+				_values.add(ee);
+			}*/
+
+			decoder.readEndElement();
+
+};
+
+Exclude.prototype.encode=function(/*XMLEncoder*/ encoder)  {
+		if (!validate()) {
+			throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
+		}
+		// if everything is null, output nothing
+		if (empty())
+			return;
+		
+		encoder.writeStartElement(getElementLabel());
+
+		/*
+		for (Element element : _values)
+			element.encode(encoder);
+		*/
+
+		encoder.writeEndElement();
+	};
+
+Exclude.prototype.getElementLabel = function() { return CCNProtocolDTags.Exclude; };
+
diff --git a/src/ExcludeAny.js b/src/ExcludeAny.js
new file mode 100644
index 0000000..4fbeb14
--- /dev/null
+++ b/src/ExcludeAny.js
@@ -0,0 +1,21 @@
+
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+var ExcludeAny = function ExcludeAny() {
+
+};
+
+exports.ExcludeAny= ExcludeAny;
+
+ExcludeAny.prototype.decode = function(decoder) {
+		decoder.readStartElement(this.getElementLabel());
+		decoder.readEndElement();
+};
+
+
+ExcludeAny.prototype.encode = function( encoder) {
+		encoder.writeStartElement(this.getElementLabel());
+		encoder.writeEndElement();
+};
+
+ExcludeAny.prototype.getElementLabel=function() { return CCNProtocolDTags.Any; };
diff --git a/src/ExcludeComponent.js b/src/ExcludeComponent.js
new file mode 100644
index 0000000..91d6cae
--- /dev/null
+++ b/src/ExcludeComponent.js
@@ -0,0 +1,23 @@
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+/*
+ * _Body is an array of componenets
+ */
+var ExcludeComponent = function ExcludeComponent(_Body) {
+
+	//TODO Check BODY is an Array of componenets.
+	
+	this.Body = _Body
+};
+exports.ExcludeComponent = ExcludeComponent;
+
+ExcludeComponent.prototype.decode = function( decoder)  {
+		body = decoder.readBinaryElement(this.getElementLabel());
+};
+
+ExcludeComponent.prototype.encode = function(encoder) {
+		encoder.writeElement(this.getElementLabel(), body);
+};
+
+ExcludeComponent.prototype.getElementLabel = function() { return CCNProtocolDTags.Component; };
+
diff --git a/src/Interest.js b/src/Interest.js
new file mode 100644
index 0000000..1fd2585
--- /dev/null
+++ b/src/Interest.js
@@ -0,0 +1,128 @@
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+var Interest = function Interest(_Name,_MinSuffixComponents,_MaxSuffixComponents,_PublisherPublicKeyDigest, _Exclude, _ChildSelector,_AnswerOriginKind,_Scope,_InterestLifetime,_Nonce){
+	
+	
+	this.Name = _Name;
+	this.MaxSuffixComponents = _MaxSuffixComponents;
+	this.MinSuffixComponents = _MinSuffixComponents;
+	
+	this.PublisherKeyDigest = _PublisherPublicKeyDigest;
+	this.Exclude = _Exclude;
+	this.ChildSelector = _ChildSelector;
+	this.AnswerOriginKind = _AnswerOriginKind;
+	this.Scope = _Scope;
+	this.InterestLifetime = null;		// For now we don't have the ability to set an interest lifetime
+	this.Nonce = _Nonce;
+	
+	/*Not sure if the rest is needed*/
+	this.Publisher = _Publisher;
+
+	this.UserTime=_UserTime;
+	
+	this.RECURSIVE_POSTFIX = "*";
+	
+	this.CHILD_SELECTOR_LEFT = 0;
+	this.CHILD_SELECTOR_RIGHT = 1;
+	this.ANSWER_CONTENT_STORE = 1;
+	this.ANSWER_GENERATED = 2;
+	this.ANSWER_STALE = 4;		// Stale answer OK
+	this.MARK_STALE = 16;		// Must have Scope 0.  Michael calls this a "hack"
+	
+	this.DEFAULT_ANSWER_ORIGIN_KIND = ANSWER_CONTENT_STORE | ANSWER_GENERATED;
+	
+	
+};
+exports.Interest = Interest;
+
+Interest.prototype.decode(/*XMLDecoder*/ decoder) {
+
+		decoder.readStartElement(CCNProtocolDTags.Interest);
+
+		this.Name = new ContentName();
+		this.Name.decode(decoder);
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.MinSuffixComponents)) {
+			this.MinSuffixComponents = decoder.readIntegerElement(CCNProtocolDTags.MinSuffixComponents);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.MaxSuffixComponents)) {
+			this.MaxSuffixComponents = decoder.readIntegerElement(CCNProtocolDTags.MaxSuffixComponents);
+		}
+			
+		//TODO something about that guy
+		/*if (PublisherID.peek(decoder)) {
+			this.Publisher = new PublisherID();
+			this.Publisher.decode(decoder);
+		}*/
+
+		if (decoder.peekStartElement(CCNProtocolDTags.Exclude)) {
+			this.Exclude = new Exclude();
+			this.Exclude.decode(decoder);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.ChildSelector)) {
+			this.ChildSelector = decoder.readIntegerElement(CCNProtocolDTags.ChildSelector);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.AnswerOriginKind)) {
+			// call setter to handle defaulting
+			this.AnswerOriginKind = decoder.readIntegerElement(CCNProtocolDTags.AnswerOriginKind);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.Scope)) {
+			this.Scope = decoder.readIntegerElement(CCNProtocolDTags.Scope);
+		}
+
+		if (decoder.peekStartElement(CCNProtocolDTags.InterestLifetime)) {
+			this.InterestLifetime = decoder.readBinaryElement(CCNProtocolDTags.InterestLifetime);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.Nonce)) {
+			this.Nonce = decoder.readBinaryElement(CCNProtocolDTags.Nonce);
+		}
+		
+		decoder.readEndElement();
+};
+
+
+Interest.prototype.encode = function(/*XMLEncoder*/ encoder){
+		if (!validate()) {
+			throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
+		}
+		
+		encoder.writeStartElement(CCNProtocolDTags.Interest);
+		
+		this.Name.encode(encoder);
+	
+		if (null != this.MinSuffixComponents) 
+			encoder.writeElement(CCNProtocolDTags.MinSuffixComponents, this.MinSuffixComponents);	
+
+		if (null != this.MaxSuffixComponents) 
+			encoder.writeElement(CCNProtocolDTags.MaxSuffixComponents, this.MaxSuffixComponents);
+
+		//TODO
+		
+		/*if (null != this.PublisherID)
+			publisherID().encode(encoder);*/
+		
+		//if (null != this.Exclude)
+			//exclude().encode(encoder);
+
+		if (null != this.ChildSelector) 
+			encoder.writeElement(CCNProtocolDTags.ChildSelector, this.ChildSelector);
+
+		if (this.DEFAULT_ANSWER_ORIGIN_KIND != this.AnswerOriginKind) 
+			encoder.writeElement(CCNProtocolDTags.AnswerOriginKind, this.AnswerOriginKind);
+
+		if (null != this.Scope) 
+			encoder.writeElement(CCNProtocolDTags.Scope, this.Scope);
+		
+		if (null != this.Nonce)
+			encoder.writeElement(CCNProtocolDTags.Nonce, this.Nonce);
+		
+		encoder.writeEndElement();   		
+};
+
+
+
diff --git a/src/KeyLocator.js b/src/KeyLocator.js
new file mode 100644
index 0000000..7d230da
--- /dev/null
+++ b/src/KeyLocator.js
@@ -0,0 +1,119 @@
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+var KeyLocatorType = function(){
+	
+};
+
+
+exports.KeyLocatorType = {
+	  NAME:1,
+	  KEY:2,
+	  CERTIFICATE:3
+};
+
+exports.KeyLocatorType =  KeyLocatorType;
+
+var KeyLocator = function KeyLocator(_Input,_Type){ 
+
+    //this.KeyName = _KeyName;
+    //this.PublicKey = _PublicKey;
+    //this.Certificate =  _Certificate;
+    
+    this.Type=_Type;
+    
+    if (_Type==KeyLocatorType.NAME){
+    	this.KeyName = _Input;
+    }
+    else if(_Type==KeyLocatorType.KEY){
+    	this.PublicKey = _Input;
+    }
+    else if(_Type==KeyLocatorType.CERTIFICATE){
+    	this.Certificate = _Input;
+    }
+    
+};
+
+exports.KeyLocator = KeyLocator;
+
+KeyLocator.prototype.decode = function(decoder) {
+
+		decoder.readStartElement(this.getElementLabel());
+
+		if (decoder.peekStartElement(CCNProtocolDTags.Key)) {
+			try {
+				encodedKey = decoder.readBinaryElement(CCNProtocolDTags.Key);
+				// This is a DER-encoded SubjectPublicKeyInfo.
+				
+				//TODO FIX THIS, SHOULDN'T be like that
+				//this.Key =   CryptoUtil.getPublicKey(encodedKey);
+				
+				this.PublicKey = encodedKey;
+				
+				
+			} catch (e) {
+				console.log("Cannot parse stored key: error: " + e);
+				throw new ContentDecodingException("Cannot parse key: ", e);
+			} 
+
+			if (null == Key) {
+				throw new Exception("Cannot parse key: ");
+			}
+			
+		} else if ( decoder.peekStartElement(CCNProtocolDTags.Certificate)) {
+			try {
+				encodedCert = decoder.readBinaryElement(CCNProtocolDTags.Certificate);
+				/*
+				 * Certificates not yet working
+				 */
+				
+				//CertificateFactory factory = CertificateFactory.getInstance("X.509");
+				//this.Certificate = (X509Certificate) factory.generateCertificate(new ByteArrayInputStream(encodedCert));
+				
+			} catch ( e) {
+				throw new Exception("Cannot decode certificate: " +  e);
+			}
+			if (null == this.Certificate) {
+				throw new Exception("Cannot parse certificate! ");
+			}
+		} else {
+			this.KeyName = new KeyName();
+			this.KeyName.decode(decoder);
+		}
+		decoder.readEndElement();
+		}
+	
+
+		KeyLocator.prototype.encode = function( encoder) {
+		/*if (!validate()) {
+			throw new ContentEncodingException("Cannot encode " + this.getClass().getName() + ": field values missing.");
+		}*/
+
+		
+		//TODO FIX THIS TOO
+		encoder.writeStartElement(this.getElementLabel());
+		if (this._Type == KeyLocatorType.KEY) {
+			encoder.writeElement(CCNProtocolDTags.Key, this.PublicKey.getEncoded() );
+			
+		} else if (this.Type == KeyLocatorType.CERTIFICATE) {
+			try {
+				encoder.writeElement(CCNProtocolDTags.Certificate, this.Certificate.getEncoded());
+			} catch ( e) {
+				
+				throw new Exception("CertificateEncodingException attempting to write key locator: " + e);
+			}
+			
+		} else if (this.Type == KeyLocatorType.NAME) {
+			this.KeyName.encode(encoder);
+		}
+		encoder.writeEndElement();
+		
+};
+	
+KeyLocator.prototype.getElementLabel = function() {
+	return CCNProtocolDTags.KeyLocator; 
+};
+
+KeyLocator.prototype.validate = function() {
+	return (  (null != this.keyName) || (null != this.PublicKey) || (null != this.Certificate)   );
+};
+	
\ No newline at end of file
diff --git a/src/KeyName.js b/src/KeyName.js
new file mode 100644
index 0000000..d534944
--- /dev/null
+++ b/src/KeyName.js
@@ -0,0 +1,50 @@
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+
+var KeyName = function KeyName() {
+	
+
+	this.ContentName = this.ContentName;//ContentName
+	this.PublisherID =this.PublisherID;//PublisherID
+
+};
+
+exports.KeyName = KeyName;
+
+KeyName.prototype.decode=function( decoder){
+	
+
+	decoder.readStartElement(this.getElementLabel());
+
+	this.ContentName = new ContentName();
+	this.ContentName.decode(decoder);
+	
+	if (PublisherID.peek(decoder)) {
+		this.PublisherID = new PublisherID();
+		this.PublisherID.decode(decoder);
+	}
+	
+	decoder.readEndElement();
+};
+
+KeyName.prototype.encode = function( encoder) {
+	if (!this.validate()) {
+		throw new Exception("Cannot encode : field values missing.");
+	}
+	
+	encoder.writeStartElement(this.getElementLabel());
+	
+	this.ContentName.encode(encoder);
+	if (null != this.PublisherID)
+		this.PublisherID.encode(encoder);
+
+	encoder.writeEndElement();   		
+};
+	
+KeyName.prototype.getElementLabel = function() { return CCNProtocolDTags.KeyName; };
+
+KeyName.prototype.validate = function() {
+		// DKS -- do we do recursive validation?
+		// null signedInfo ok
+		return (null != this.ContentName);
+};
diff --git a/src/PublisherID.js b/src/PublisherID.js
new file mode 100644
index 0000000..26009da
--- /dev/null
+++ b/src/PublisherID.js
@@ -0,0 +1,76 @@
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+
+var PublisherType = function PublisherType(_tag){
+    	this.KEY =(CCNProtocolDTags.PublisherPublicKeyDigest);
+    	this.CERTIFICATE= (CCNProtocolDTags.PublisherCertificateDigest);
+    	this.ISSUER_KEY=	(CCNProtocolDTags.PublisherIssuerKeyDigest);
+    	this.ISSUER_CERTIFICATE	=(CCNProtocolDTags.PublisherIssuerCertificateDigest);
+
+    	this.Tag = _tag;
+}; exports.PublisherType = PublisherType;
+
+PublisherType.prototype.isTypeTagVal = function(tagVal) {
+		if ((tagVal == CCNProtocolDTags.PublisherPublicKeyDigest) ||
+			(tagVal == CCNProtocolDTags.PublisherCertificateDigest) ||
+			(tagVal == CCNProtocolDTags.PublisherIssuerKeyDigest) ||
+			(tagVal == CCNProtocolDTags.PublisherIssuerCertificateDigest)) {
+			return true;
+		}
+		return false;
+};
+
+
+var PublisherID = function PublisherID() {
+
+	this.PUBLISHER_ID_DIGEST_ALGORITHM = "SHA-256";
+	this.PUBLISHER_ID_LEN = 256/8;
+    
+    
+    this.PublisherID = generatePublicKeyDigest(key);//ByteArray
+    //CryptoUtil.generateKeyID(PUBLISHER_ID_DIGEST_ALGORITHM, key);
+    this.PublisherType = isIssuer ? PublisherType.ISSUER_KEY : PublisherType.KEY;//publisher Type
+    
+};
+
+exports.PublisherID = PublisherID;
+
+PublisherID.prototype.decode = function(decoder) {
+		
+		// We have a choice here of one of 4 binary element types.
+		var nextTag = decoder.peekStartElementAsLong();
+		
+		if (null == nextTag) {
+			throw new Exception("Cannot parse publisher ID.");
+		} 
+		
+		this.PublisherType = new PublisherType(nextTag); 
+		
+		if (!this.PublisherType.isTypeTagVal(nextTag)) {
+			throw new Exception("Invalid publisher ID, got unexpected type: " + nextTag);
+		}
+		this.PublisherID = decoder.readBinaryElement(nextTag);
+		if (null == _publisherID) {
+			throw new ContentDecodingException("Cannot parse publisher ID of type : " + nextTag + ".");
+		}
+};
+
+PublisherID.prototype.encode = function(encoder) {
+	if (!this.validate()) {
+		throw new Exception("Cannot encode " + this.getClass().getName() + ": field values missing.");
+	}
+
+	encoder.writeElement(this.getElementLabel(), this.PublisherID);
+};
+	
+PublisherID.prototype.getElementLabel = function() { 
+	return this.PublisherType.Tag;
+};
+
+	
+PublisherID.prototype.validate = function(){
+	return ((null != id() && (null != type())));
+};
+
+
+
diff --git a/src/PublisherPublicKeyDigest.js b/src/PublisherPublicKeyDigest.js
new file mode 100644
index 0000000..3d3987a
--- /dev/null
+++ b/src/PublisherPublicKeyDigest.js
@@ -0,0 +1,38 @@
+
+var PublisherID = require('./PublisherID').PublisherID;
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+var PublisherPublicKeyDigest = function PublisherPublicKeyDigest(_pkd){ 
+	
+ 	 if( typeof _pkd == "ByteArray") this.PublisherPublicKeyDigest = _pkd; // Byte Array
+ 	 else if( typeof _pkd == "PublicKey") ;//TODO...
+    
+};
+
+exports.PublisherPublicKeyDigest = PublisherPublicKeyDigest;
+
+
+PublisherPublicKeyDigest.prototype.decode = function( decoder) {		
+
+		this.PublisherPublicKeyDigest = decoder.readBinaryElement(this.getElementLabel());
+		if (null == this.PublisherPublicKeyDigest) {
+			throw new Exception("Cannot parse publisher key digest.");
+		}
+		if (this.PublisherPublicKeyDigest.length != PublisherID.PUBLISHER_ID_LEN) {
+			
+			this.PublisherPublicKeyDigest = new PublisherPublicKeyDigest(this.PublisherPublicKeyDigest).PublisherKeyDigest;
+		}
+	};
+
+PublisherPublicKeyDigest.prototype.encode= function( encoder) {
+		if (!this.validate()) {
+			throw new Exception("Cannot encode : field values missing.");
+		}
+		this.encoder.writeElement(this.getElementLabel(), this.PublisherKeyDigest);
+};
+	
+PublisherPublicKeyDigest.prototype.getElementLabel = function() { return CCNProtocolDTags.PublisherPublicKeyDigest; };
+
+PublisherPublicKeyDigest.prototype.validate =function() {
+		return (null != this.PublisherKeyDigest);
+};
diff --git a/src/Signature.js b/src/Signature.js
new file mode 100644
index 0000000..d4c3fa4
--- /dev/null
+++ b/src/Signature.js
@@ -0,0 +1,58 @@
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+
+var Signature = function Signature(_Witness,_Signature,_DigestAlgorithm) {
+	
+    this.Witness = _Witness;//byte [] _witness;
+	this.Signature = _Signature;//byte [] _signature;
+	this.DigestAlgorithm = _DigestAlgorithm//String _digestAlgorithm;
+};
+
+exports.Signature = Signature;
+
+
+Signature.prototype.decode =function( decoder) {
+		decoder.readStartElement(this.getElementLabel());
+		if (decoder.peekStartElement(CCNProtocolDTags.DigestAlgorithm)) {
+			this.DigestAlgorithm = decoder.readUTF8Element(CCNProtocolDTags.DigestAlgorithm); 
+		}
+		if (decoder.peekStartElement(CCNProtocolDTags.Witness)) {
+			this.Witness = decoder.readBinaryElement(CCNProtocolDTags.Witness); 
+		}
+		this.Signature = decoder.readBinaryElement(CCNProtocolDTags.SignatureBits);	
+		decoder.readEndElement();
+	
+};
+
+
+exports.Signature = Signature;
+
+Signature.prototype.encode= function( encoder){
+    	
+	if (!this.validate()) {
+		throw new Exception("Cannot encode: field values missing.");
+	}
+	
+	encoder.writeStartElement(this.getElementLabel());
+	
+	if ((null != this.DigestAlgorithm) && (!this.DigestAlgorithm.equals(CCNDigestHelper.DEFAULT_DIGEST_ALGORITHM))) {
+		encoder.writeElement(CCNProtocolDTags.DigestAlgorithm, OIDLookup.getDigestOID(this.DigestAlgorithm));
+	}
+	
+	if (null != this.Witness) {
+		// needs to handle null witness
+		encoder.writeElement(CCNProtocolDTags.Witness, this.Witness);
+	}
+
+	encoder.writeElement(CCNProtocolDTags.SignatureBits, this.Signature);
+
+	encoder.writeEndElement();   		
+};
+
+Signature.prototype.getElementLabel = function() { return CCNProtocolDTags.Signature; };
+
+
+Signature.prototype.validate = function() {
+		return null != this.Signature;
+};
+
diff --git a/src/SignedInfo.js b/src/SignedInfo.js
new file mode 100644
index 0000000..14b72ef
--- /dev/null
+++ b/src/SignedInfo.js
@@ -0,0 +1,106 @@
+var CCNProtocolDTags = require('./CCNProtocolDTags').CCNProtocolDTags;
+
+var SignedInfo = function SignedInfo(_publisher,_timestamp,_type,_locator,_freshnessSeconds,_finalBlockID){
+
+	//TODO, Check types
+    
+    this.Publisher = _publisher; //PublisherPublicKeyDigest
+    this.Timestamp=_timestamp; // CCN Time
+    this.Type=_type; // ContentType
+    this.Locator =_locator;//KeyLocator
+    this.FreshnessSeconds =_freshnessSeconds; // Integer
+    this.FinalBlockID=_finalBlockID; //byte array
+
+};
+
+//exports.SignedInfo.Working;
+
+
+SignedInfo.prototype.decode = function( decoder){
+
+		decoder.readStartElement( this.getElementLabel() );
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.PublisherPublicKeyDigest)) {
+			this.Publisher = new PublisherPublicKeyDigest();
+			this.Publisher.decode(decoder);
+		}
+
+		if (decoder.peekStartElement(CCNProtocolDTags.Timestamp)) {
+			this.Timestamp = decoder.readDateTime(CCNProtocolDTags.Timestamp);
+		}
+
+		if (decoder.peekStartElement(CCNProtocolDTags.Type)) {
+			binType = decoder.readBinaryElement(CCNProtocolDTags.Type);//byte [] 
+			//TODO Implement valueToType
+			
+			this.Type = valueToType(binType);
+			if (null == this.Type) {
+				throw new Exception("Cannot parse signedInfo type: bytes.");
+			}
+			
+		} else {
+			this.Type = ContentType.DATA; // default
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.FreshnessSeconds)) {
+			this.FreshnessSeconds = decoder.readIntegerElement(CCNProtocolDTags.FreshnessSeconds);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.FinalBlockID)) {
+			this.FinalBlockID = decoder.readBinaryElement(CCNProtocolDTags.FinalBlockID);
+		}
+		
+		if (decoder.peekStartElement(CCNProtocolDTags.KeyLocator)) {
+			this.Locator = new KeyLocator();
+			this.Locator.decode(decoder);
+		}
+				
+		decoder.readEndElement();
+};
+
+SignedInfo.prototype.encode = function( encoder)  {
+		if (!this.validate()) {
+			throw new Exception("Cannot encode : field values missing.");
+		}
+		encoder.writeStartElement(this.getElementLabel());
+		
+		if (null!=this.Publisher) {
+			this.Publisher.encode(encoder);
+		}
+
+		if (null!=this.Timestamp) {
+			encoder.writeDateTime(CCNProtocolDTags.Timestamp, this.Timestamp);
+		}
+		
+		if (null!=this.Type) {
+			
+			encoder.writeElement(CCNProtocolDTags.Type, this.Type);
+		}
+		
+		if (null!=this.FreshnessSeconds) {
+			encoder.writeElement(CCNProtocolDTags.FreshnessSeconds, this.FreshnessSeconds);
+		}
+
+		if (null!=this.FinalBlockID) {
+			encoder.writeElement(CCNProtocolDTags.FinalBlockID, this.FinalBlockID);
+		}
+
+		if (null!=this.Locator) {
+			this.Locator.encode(encoder);
+		}
+
+		encoder.writeEndElement();   		
+};
+	
+SignedInfo.prototype.getElementLabel = function() { 
+	return CCNProtocolDTags.SignedInfo;
+};
+
+SignedInfo.prototype.validate = function() {
+		// We don't do partial matches any more, even though encoder/decoder
+		// is still pretty generous.
+		if (null ==this.Publisher || null==this.Timestamp ||null== this.Locator)
+			return false;
+		return true;
+	};
+
diff --git a/src/encoding/BinaryXMLCodec.js b/src/encoding/BinaryXMLCodec.js
new file mode 100644
index 0000000..077c7e2
--- /dev/null
+++ b/src/encoding/BinaryXMLCodec.js
@@ -0,0 +1,135 @@
+
+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 = 0x0000007FFL;
+var bits_18 = 0x00003FFFFL;
+var bits_32 = 0x0FFFFFFFFL;
+
+
+var TypeAndVal = function TypeAndVal(_type,_val) {
+	this.type = _type;
+	this.val = _val;
+	
+};
+exports.TypeAndVal = TypeAndVal;
+
+var BinaryXMLCodec = function BinaryXMLCodec(){
+	
+	this.CODEC_NAME = "Binary";
+			
+
+
+};
+
+exports.BinaryXMLCodec = BinaryXMLCodec;
+
+
+    
+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 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;;
+
+	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.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);
+};
+
+//TODO
\ No newline at end of file
diff --git a/src/encoding/BinaryXMLDecoder.js b/src/encoding/BinaryXMLDecoder.js
new file mode 100644
index 0000000..4a8b1c4
--- /dev/null
+++ b/src/encoding/BinaryXMLDecoder.js
@@ -0,0 +1,89 @@
+var MARK_LEN=512;
+var DEBUG_MAX_LEN =  32768;
+
+var BinaryXMLDecoder = new BinaryXMLDecoder(_Istream){
+	this.Istream = _Istream;
+	
+};
+
+
+BinaryXMLDecoder.prototype.readStartElement =function(
+	//String
+	startTag,				    
+	//TreeMap<String, String>
+	attributes) {
+
+	try {
+		BinaryXMLCodec.TypeAndVal tv = BinaryXMLCodec.decodeTypeAndVal(this.Istream);
+		
+		if (null == tv) {
+			throw new Exception("Expected start element: " + startTag + " got something not a tag.");
+		}
+		
+		String decodedTag = null;
+		
+		if (tv.type() == BinaryXMLCodec.XML_TAG) {
+			
+			decodedTag = BinaryXMLCodec.decodeUString(this.Istream, tv.val()+1);
+			
+		} else if (tv.type() == BinaryXMLCodec.XML_DTAG) {
+			decodedTag = tagToString(tv.val());	
+		}
+		
+		if ((null ==  decodedTag) || (!decodedTag.equals(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 {
+
+		BinaryXMLCodec.TypeAndVal nextTV = BinaryXMLCodec.peekTypeAndVal(_istream);
+
+		while ((null != nextTV) && ((BinaryXMLCodec.XML_ATTR == nextTV.type()) ||
+				(BinaryXMLCodec.XML_DATTR == nextTV.type()))) {
+
+			BinaryXMLCodec.TypeAndVal thisTV = BinaryXMLCodec.decodeTypeAndVal(this.Istream);
+
+			var attributeName = null;
+			if (BinaryXMLCodec.XML_ATTR == thisTV.type()) {
+				
+				attributeName = BinaryXMLCodec.decodeUString(_istream, thisTV.val()+1);
+
+			} else if (BinaryXMLCodec.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 = BinaryXMLCodec.decodeUString(_istream);
+
+			attributes.put(attributeName, attributeValue);
+
+			nextTV = BinaryXMLCodec.peekTypeAndVal(_istream);
+		}
+
+	} catch ( e) {
+
+		throw new ContentDecodingException("readStartElement", e);
+	}
+};
+
+//TODO
\ No newline at end of file
diff --git a/src/encoding/BinaryXMLEncoder.js b/src/encoding/BinaryXMLEncoder.js
new file mode 100644
index 0000000..7ccf3b4
--- /dev/null
+++ b/src/encoding/BinaryXMLEncoder.js
@@ -0,0 +1,31 @@
+
+var BinaryXMLEncoder = function BinaryXMLEncoder(){
+	
+BinaryXMLEncoder.prototype.writeStartElement = function(
+		//String 
+		tag, 
+		//TreeMap<String,String> 
+		attributes){
+	
+}
+	try {
+		var dictionaryVal = stringToTag(tag);
+		
+		if (null == dictionaryVal) {
+			BinaryXMLCodec.encodeUString(_ostream, tag, BinaryXMLCodec.XML_TAG);
+			
+		} else {
+			BinaryXMLCodec.encodeTypeAndVal(BinaryXMLCodec.XML_DTAG, dictionaryVal, _ostream);
+		}
+		
+		if (null != attributes) {
+			writeAttributes(attributes); 
+		}
+		
+	} catch (e) {
+		throw new Exception(e);
+	}
+};
+
+
+//TODO
\ No newline at end of file
diff --git a/src/encoding/TextXMLCodec.js b/src/encoding/TextXMLCodec.js
new file mode 100644
index 0000000..ea64188
--- /dev/null
+++ b/src/encoding/TextXMLCodec.js
@@ -0,0 +1 @@
+//TODO
\ No newline at end of file
diff --git a/src/encoding/TextXMLDecoder.js b/src/encoding/TextXMLDecoder.js
new file mode 100644
index 0000000..ea64188
--- /dev/null
+++ b/src/encoding/TextXMLDecoder.js
@@ -0,0 +1 @@
+//TODO
\ No newline at end of file
diff --git a/src/encoding/TextXMLEncoder.js b/src/encoding/TextXMLEncoder.js
new file mode 100644
index 0000000..ea64188
--- /dev/null
+++ b/src/encoding/TextXMLEncoder.js
@@ -0,0 +1 @@
+//TODO
\ No newline at end of file