ie.klatt.proxy.BinaryXml.java Source code

Java tutorial

Introduction

Here is the source code for ie.klatt.proxy.BinaryXml.java

Source

package ie.klatt.proxy;

import org.bouncycastle.util.encoders.Base64;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Vector;

public class BinaryXml {
    protected final HashMap<Long, String> dictionary = new HashMap<Long, String>();
    protected String xml;
    protected boolean tagOpened;
    protected boolean listMode;

    public BinaryXml() {
        xml = "";
        dictionary.put(0x00L, "mustUnderstand");
        dictionary.put(0x02L, "Envelope");
        dictionary.put(0x04L, "http://www.w3.org/2003/05/soap-envelope");
        dictionary.put(0x06L, "http://www.w3.org/2005/08/addressing");
        dictionary.put(0x08L, "Header");
        dictionary.put(0x0AL, "Action");
        dictionary.put(0x0CL, "To");
        dictionary.put(0x0EL, "Body");
        dictionary.put(0x10L, "Algorithm");
        dictionary.put(0x12L, "RelatesTo");
        dictionary.put(0x14L, "http://www.w3.org/2005/08/addressing/anonymous");
        dictionary.put(0x16L, "URI");
        dictionary.put(0x18L, "Reference");
        dictionary.put(0x1AL, "MessageID");
        dictionary.put(0x1CL, "Id");
        dictionary.put(0x1EL, "Identifier");
        dictionary.put(0x20L, "http://schemas.xmlsoap.org/ws/2005/02/rm");
        dictionary.put(0x22L, "Transforms");
        dictionary.put(0x24L, "Transform");
        dictionary.put(0x26L, "DigestMethod");
        dictionary.put(0x28L, "DigestValue");
        dictionary.put(0x2AL, "Address");
        dictionary.put(0x2CL, "ReplyTo");
        dictionary.put(0x2EL, "SequenceAcknowledgement");
        dictionary.put(0x30L, "AcknowledgementRange");
        dictionary.put(0x32L, "Upper");
        dictionary.put(0x34L, "Lower");
        dictionary.put(0x36L, "BufferRemaining");
        dictionary.put(0x38L, "http://schemas.microsoft.com/ws/2006/05/rm");
        dictionary.put(0x3AL, "http://schemas.xmlsoap.org/ws/2005/02/rm/SequenceAcknowledgement");
        dictionary.put(0x3CL, "SecurityTokenReference");
        dictionary.put(0x3EL, "Sequence");
        dictionary.put(0x40L, "MessageNumber");
        dictionary.put(0x42L, "http://www.w3.org/2000/09/xmldsig#");
        dictionary.put(0x44L, "http://www.w3.org/2000/09/xmldsig#enveloped-signature");
        dictionary.put(0x46L, "KeyInfo");
        dictionary.put(0x48L, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
        dictionary.put(0x4AL, "http://www.w3.org/2001/04/xmlenc#");
        dictionary.put(0x4CL, "http://schemas.xmlsoap.org/ws/2005/02/sc");
        dictionary.put(0x4EL, "DerivedKeyToken");
        dictionary.put(0x50L, "Nonce");
        dictionary.put(0x52L, "Signature");
        dictionary.put(0x54L, "SignedInfo");
        dictionary.put(0x56L, "CanonicalizationMethod");
        dictionary.put(0x58L, "SignatureMethod");
        dictionary.put(0x5AL, "SignatureValue");
        dictionary.put(0x5CL, "DataReference");
        dictionary.put(0x5EL, "EncryptedData");
        dictionary.put(0x60L, "EncryptionMethod");
        dictionary.put(0x62L, "CipherData");
        dictionary.put(0x64L, "CipherValue");
        dictionary.put(0x66L, "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
        dictionary.put(0x68L, "Security");
        dictionary.put(0x6AL, "Timestamp");
        dictionary.put(0x6CL, "Created");
        dictionary.put(0x6EL, "Expires");
        dictionary.put(0x70L, "Length");
        dictionary.put(0x72L, "ReferenceList");
        dictionary.put(0x74L, "ValueType");
        dictionary.put(0x76L, "Type");
        dictionary.put(0x78L, "EncryptedHeader");
        dictionary.put(0x7AL, "http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd");
        dictionary.put(0x7CL, "RequestSecurityTokenResponseCollection");
        dictionary.put(0x7EL, "http://schemas.xmlsoap.org/ws/2005/02/trust");
        dictionary.put(0x80L, "http://schemas.xmlsoap.org/ws/2005/02/trust#BinarySecret");
        dictionary.put(0x82L, "http://schemas.microsoft.com/ws/2006/02/transactions");
        dictionary.put(0x84L, "s");
        dictionary.put(0x86L, "Fault");
        dictionary.put(0x88L, "MustUnderstand");
        dictionary.put(0x8AL, "role");
        dictionary.put(0x8CL, "relay");
        dictionary.put(0x8EL, "Code");
        dictionary.put(0x90L, "Reason");
        dictionary.put(0x92L, "Text");
        dictionary.put(0x94L, "Node");
        dictionary.put(0x96L, "Role");
        dictionary.put(0x98L, "Detail");
        dictionary.put(0x9AL, "Value");
        dictionary.put(0x9CL, "Subcode");
        dictionary.put(0x9EL, "NotUnderstood");
        dictionary.put(0xA0L, "qname");
        dictionary.put(0xA2L, "");
        dictionary.put(0xA4L, "From");
        dictionary.put(0xA6L, "FaultTo");
        dictionary.put(0xA8L, "EndpointReference");
        dictionary.put(0xAAL, "PortType");
        dictionary.put(0xACL, "ServiceName");
        dictionary.put(0xAEL, "PortName");
        dictionary.put(0xB0L, "ReferenceProperties");
        dictionary.put(0xB2L, "RelationshipType");
        dictionary.put(0xB4L, "Reply");
        dictionary.put(0xB6L, "a");
        dictionary.put(0xB8L, "http://schemas.xmlsoap.org/ws/2006/02/addressingidentity");
        dictionary.put(0xBAL, "Identity");
        dictionary.put(0xBCL, "Spn");
        dictionary.put(0xBEL, "Upn");
        dictionary.put(0xC0L, "Rsa");
        dictionary.put(0xC2L, "Dns");
        dictionary.put(0xC4L, "X509v3Certificate");
        dictionary.put(0xC6L, "http://www.w3.org/2005/08/addressing/fault");
        dictionary.put(0xC8L, "ReferenceParameters");
        dictionary.put(0xCAL, "IsReferenceParameter");
        dictionary.put(0xCCL, "http://www.w3.org/2005/08/addressing/reply");
        dictionary.put(0xCEL, "http://www.w3.org/2005/08/addressing/none");
        dictionary.put(0xD0L, "Metadata");
        dictionary.put(0xD2L, "http://schemas.xmlsoap.org/ws/2004/08/addressing");
        dictionary.put(0xD4L, "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous");
        dictionary.put(0xD6L, "http://schemas.xmlsoap.org/ws/2004/08/addressing/fault");
        dictionary.put(0xD8L, "http://schemas.xmlsoap.org/ws/2004/06/addressingex");
        dictionary.put(0xDAL, "RedirectTo");
        dictionary.put(0xDCL, "Via");
        dictionary.put(0xDEL, "http://www.w3.org/2001/10/xml-exc-c14n#");
        dictionary.put(0xE0L, "PrefixList");
        dictionary.put(0xE2L, "InclusiveNamespaces");
        dictionary.put(0xE4L, "ec");
        dictionary.put(0xE6L, "SecurityContextToken");
        dictionary.put(0xE8L, "Generation");
        dictionary.put(0xEAL, "Label");
        dictionary.put(0xECL, "Offset");
        dictionary.put(0xEEL, "Properties");
        dictionary.put(0xF0L, "Cookie");
        dictionary.put(0xF2L, "wsc");
        dictionary.put(0xF4L, "http://schemas.xmlsoap.org/ws/2004/04/sc");
        dictionary.put(0xF6L, "http://schemas.xmlsoap.org/ws/2004/04/security/sc/dk");
        dictionary.put(0xF8L, "http://schemas.xmlsoap.org/ws/2004/04/security/sc/sct");
        dictionary.put(0xFAL, "http://schemas.xmlsoap.org/ws/2004/04/security/trust/RST/SCT");
        dictionary.put(0xFCL, "http://schemas.xmlsoap.org/ws/2004/04/security/trust/RSTR/SCT");
        dictionary.put(0xFEL, "RenewNeeded");
        dictionary.put(0x100L, "BadContextToken");
        dictionary.put(0x102L, "c");
        dictionary.put(0x104L, "http://schemas.xmlsoap.org/ws/2005/02/sc/dk");
        dictionary.put(0x106L, "http://schemas.xmlsoap.org/ws/2005/02/sc/sct");
        dictionary.put(0x108L, "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT");
        dictionary.put(0x10AL, "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/SCT");
        dictionary.put(0x10CL, "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT/Renew");
        dictionary.put(0x10EL, "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/SCT/Renew");
        dictionary.put(0x110L, "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/SCT/Cancel");
        dictionary.put(0x112L, "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/SCT/Cancel");
        dictionary.put(0x114L, "http://www.w3.org/2001/04/xmlenc#aes128-cbc");
        dictionary.put(0x116L, "http://www.w3.org/2001/04/xmlenc#kw-aes128");
        dictionary.put(0x118L, "http://www.w3.org/2001/04/xmlenc#aes192-cbc");
        dictionary.put(0x11AL, "http://www.w3.org/2001/04/xmlenc#kw-aes192");
        dictionary.put(0x11CL, "http://www.w3.org/2001/04/xmlenc#aes256-cbc");
        dictionary.put(0x11EL, "http://www.w3.org/2001/04/xmlenc#kw-aes256");
        dictionary.put(0x120L, "http://www.w3.org/2001/04/xmlenc#des-cbc");
        dictionary.put(0x122L, "http://www.w3.org/2000/09/xmldsig#dsa-sha1");
        dictionary.put(0x124L, "http://www.w3.org/2001/10/xml-exc-c14n#WithComments");
        dictionary.put(0x126L, "http://www.w3.org/2000/09/xmldsig#hmac-sha1");
        dictionary.put(0x128L, "http://www.w3.org/2001/04/xmldsig-more#hmac-sha256");
        dictionary.put(0x12AL, "http://schemas.xmlsoap.org/ws/2005/02/sc/dk/p_sha1");
        dictionary.put(0x12CL, "http://www.w3.org/2001/04/xmlenc#ripemd160");
        dictionary.put(0x12EL, "http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p");
        dictionary.put(0x130L, "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
        dictionary.put(0x132L, "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
        dictionary.put(0x134L, "http://www.w3.org/2001/04/xmlenc#rsa-1_5");
        dictionary.put(0x136L, "http://www.w3.org/2000/09/xmldsig#sha1");
        dictionary.put(0x138L, "http://www.w3.org/2001/04/xmlenc#sha256");
        dictionary.put(0x13AL, "http://www.w3.org/2001/04/xmlenc#sha512");
        dictionary.put(0x13CL, "http://www.w3.org/2001/04/xmlenc#tripledes-cbc");
        dictionary.put(0x13EL, "http://www.w3.org/2001/04/xmlenc#kw-tripledes");
        dictionary.put(0x140L, "http://schemas.xmlsoap.org/2005/02/trust/tlsnego#TLS_Wrap");
        dictionary.put(0x142L, "http://schemas.xmlsoap.org/2005/02/trust/spnego#GSS_Wrap");
        dictionary.put(0x144L, "http://schemas.microsoft.com/ws/2006/05/security");
        dictionary.put(0x146L, "dnse");
        dictionary.put(0x148L, "o");
        dictionary.put(0x14AL, "Password");
        dictionary.put(0x14CL, "PasswordText");
        dictionary.put(0x14EL, "Username");
        dictionary.put(0x150L, "UsernameToken");
        dictionary.put(0x152L, "BinarySecurityToken");
        dictionary.put(0x154L, "EncodingType");
        dictionary.put(0x156L, "KeyIdentifier");
        dictionary.put(0x158L,
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
        dictionary.put(0x15AL,
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#HexBinary");
        dictionary.put(0x15CL,
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Text");
        dictionary.put(0x15EL,
                "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier");
        dictionary.put(0x160L,
                "http://docs.oasis-open.org/wss/oasis-wss-kerberos-token-profile-1.1#GSS_Kerberosv5_AP_REQ");
        dictionary.put(0x162L,
                "http://docs.oasis-open.org/wss/oasis-wss-kerberos-token-profile-1.1#GSS_Kerberosv5_AP_REQ1510");
        dictionary.put(0x164L, "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID");
        dictionary.put(0x166L, "Assertion");
        dictionary.put(0x168L, "urn:oasis:names:tc:SAML:1.0:assertion");
        dictionary.put(0x16AL, "http://docs.oasis-open.org/wss/oasis-wss-rel-token-profile-1.0.pdf#license");
        dictionary.put(0x16CL, "FailedAuthentication");
        dictionary.put(0x16EL, "InvalidSecurityToken");
        dictionary.put(0x170L, "InvalidSecurity");
        dictionary.put(0x172L, "k");
        dictionary.put(0x174L, "SignatureConfirmation");
        dictionary.put(0x176L, "TokenType");
        dictionary.put(0x178L, "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1");
        dictionary.put(0x17AL, "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey");
        dictionary.put(0x17CL,
                "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKeySHA1");
        dictionary.put(0x17EL, "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1");
        dictionary.put(0x180L, "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0");
        dictionary.put(0x182L, "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID");
        dictionary.put(0x184L, "AUTH-HASH");
        dictionary.put(0x186L, "RequestSecurityTokenResponse");
        dictionary.put(0x188L, "KeySize");
        dictionary.put(0x18AL, "RequestedTokenReference");
        dictionary.put(0x18CL, "AppliesTo");
        dictionary.put(0x18EL, "Authenticator");
        dictionary.put(0x190L, "CombinedHash");
        dictionary.put(0x192L, "BinaryExchange");
        dictionary.put(0x194L, "Lifetime");
        dictionary.put(0x196L, "RequestedSecurityToken");
        dictionary.put(0x198L, "Entropy");
        dictionary.put(0x19AL, "RequestedProofToken");
        dictionary.put(0x19CL, "ComputedKey");
        dictionary.put(0x19EL, "RequestSecurityToken");
        dictionary.put(0x1A0L, "RequestType");
        dictionary.put(0x1A2L, "Context");
        dictionary.put(0x1A4L, "BinarySecret");
        dictionary.put(0x1A6L, "http://schemas.xmlsoap.org/ws/2005/02/trust/spnego");
        dictionary.put(0x1A8L, "http://schemas.xmlsoap.org/ws/2005/02/trust/tlsnego");
        dictionary.put(0x1AAL, "wst");
        dictionary.put(0x1ACL, "http://schemas.xmlsoap.org/ws/2004/04/trust");
        dictionary.put(0x1AEL, "http://schemas.xmlsoap.org/ws/2004/04/security/trust/RST/Issue");
        dictionary.put(0x1B0L, "http://schemas.xmlsoap.org/ws/2004/04/security/trust/RSTR/Issue");
        dictionary.put(0x1B2L, "http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue");
        dictionary.put(0x1B4L, "http://schemas.xmlsoap.org/ws/2004/04/security/trust/CK/PSHA1");
        dictionary.put(0x1B6L, "http://schemas.xmlsoap.org/ws/2004/04/security/trust/SymmetricKey");
        dictionary.put(0x1B8L, "http://schemas.xmlsoap.org/ws/2004/04/security/trust/Nonce");
        dictionary.put(0x1BAL, "KeyType");
        dictionary.put(0x1BCL, "http://schemas.xmlsoap.org/ws/2004/04/trust/SymmetricKey");
        dictionary.put(0x1BEL, "http://schemas.xmlsoap.org/ws/2004/04/trust/PublicKey");
        dictionary.put(0x1C0L, "Claims");
        dictionary.put(0x1C2L, "InvalidRequest");
        dictionary.put(0x1C4L, "RequestFailed");
        dictionary.put(0x1C6L, "SignWith");
        dictionary.put(0x1C8L, "EncryptWith");
        dictionary.put(0x1CAL, "EncryptionAlgorithm");
        dictionary.put(0x1CCL, "CanonicalizationAlgorithm");
        dictionary.put(0x1CEL, "ComputedKeyAlgorithm");
        dictionary.put(0x1D0L, "UseKey");
        dictionary.put(0x1D2L, "http://schemas.microsoft.com/net/2004/07/secext/WS-SPNego");
        dictionary.put(0x1D4L, "http://schemas.microsoft.com/net/2004/07/secext/TLSNego");
        dictionary.put(0x1D6L, "t");
        dictionary.put(0x1D8L, "http://schemas.xmlsoap.org/ws/2005/02/trust/RST/Issue");
        dictionary.put(0x1DAL, "http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue");
        dictionary.put(0x1DCL, "http://schemas.xmlsoap.org/ws/2005/02/trust/Issue");
        dictionary.put(0x1DEL, "http://schemas.xmlsoap.org/ws/2005/02/trust/SymmetricKey");
        dictionary.put(0x1E0L, "http://schemas.xmlsoap.org/ws/2005/02/trust/CK/PSHA1");
        dictionary.put(0x1E2L, "http://schemas.xmlsoap.org/ws/2005/02/trust/Nonce");
        dictionary.put(0x1E4L, "RenewTarget");
        dictionary.put(0x1E6L, "CancelTarget");
        dictionary.put(0x1E8L, "RequestedTokenCancelled");
        dictionary.put(0x1EAL, "RequestedAttachedReference");
        dictionary.put(0x1ECL, "RequestedUnattachedReference");
        dictionary.put(0x1EEL, "IssuedTokens");
        dictionary.put(0x1F0L, "http://schemas.xmlsoap.org/ws/2005/02/trust/Renew");
        dictionary.put(0x1F2L, "http://schemas.xmlsoap.org/ws/2005/02/trust/Cancel");
        dictionary.put(0x1F4L, "http://schemas.xmlsoap.org/ws/2005/02/trust/PublicKey");
        dictionary.put(0x1F6L, "Access");
        dictionary.put(0x1F8L, "AccessDecision");
        dictionary.put(0x1FAL, "Advice");
        dictionary.put(0x1FCL, "AssertionID");
        dictionary.put(0x1FEL, "AssertionIDReference");
        dictionary.put(0x200L, "Attribute");
        dictionary.put(0x202L, "AttributeName");
        dictionary.put(0x204L, "AttributeNamespace");
        dictionary.put(0x206L, "AttributeStatement");
        dictionary.put(0x208L, "AttributeValue");
        dictionary.put(0x20AL, "Audience");
        dictionary.put(0x20CL, "AudienceRestrictionCondition");
        dictionary.put(0x20EL, "AuthenticationInstant");
        dictionary.put(0x210L, "AuthenticationMethod");
        dictionary.put(0x212L, "AuthenticationStatement");
        dictionary.put(0x214L, "AuthorityBinding");
        dictionary.put(0x216L, "AuthorityKind");
        dictionary.put(0x218L, "AuthorizationDecisionStatement");
        dictionary.put(0x21AL, "Binding");
        dictionary.put(0x21CL, "Condition");
        dictionary.put(0x21EL, "Conditions");
        dictionary.put(0x220L, "Decision");
        dictionary.put(0x222L, "DoNotCacheCondition");
        dictionary.put(0x224L, "Evidence");
        dictionary.put(0x226L, "IssueInstant");
        dictionary.put(0x228L, "Issuer");
        dictionary.put(0x22AL, "Location");
        dictionary.put(0x22CL, "MajorVersion");
        dictionary.put(0x22EL, "MinorVersion");
        dictionary.put(0x230L, "NameIdentifier");
        dictionary.put(0x232L, "Format");
        dictionary.put(0x234L, "NameQualifier");
        dictionary.put(0x236L, "Namespace");
        dictionary.put(0x238L, "NotBefore");
        dictionary.put(0x23AL, "NotOnOrAfter");
        dictionary.put(0x23CL, "saml");
        dictionary.put(0x23EL, "Statement");
        dictionary.put(0x240L, "Subject");
        dictionary.put(0x242L, "SubjectConfirmation");
        dictionary.put(0x244L, "SubjectConfirmationData");
        dictionary.put(0x246L, "ConfirmationMethod");
        dictionary.put(0x248L, "urn:oasis:names:tc:SAML:1.0:cm:holder-of-key");
        dictionary.put(0x24AL, "urn:oasis:names:tc:SAML:1.0:cm:sender-vouches");
        dictionary.put(0x24CL, "SubjectLocality");
        dictionary.put(0x24EL, "DNSAddress");
        dictionary.put(0x250L, "IPAddress");
        dictionary.put(0x252L, "SubjectStatement");
        dictionary.put(0x254L, "urn:oasis:names:tc:SAML:1.0:am:unspecified");
        dictionary.put(0x256L, "xmlns");
        dictionary.put(0x258L, "Resource");
        dictionary.put(0x25AL, "UserName");
        dictionary.put(0x25CL, "urn:oasis:names:tc:SAML:1.1:nameid-format:WindowsDomainQualifiedName");
        dictionary.put(0x25EL, "EmailName");
        dictionary.put(0x260L, "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress");
        dictionary.put(0x262L, "u");
        dictionary.put(0x264L, "ChannelInstance");
        dictionary.put(0x266L, "http://schemas.microsoft.com/ws/2005/02/duplex");
        dictionary.put(0x268L, "Encoding");
        dictionary.put(0x26AL, "MimeType");
        dictionary.put(0x26CL, "CarriedKeyName");
        dictionary.put(0x26EL, "Recipient");
        dictionary.put(0x270L, "EncryptedKey");
        dictionary.put(0x272L, "KeyReference");
        dictionary.put(0x274L, "e");
        dictionary.put(0x276L, "http://www.w3.org/2001/04/xmlenc#Element");
        dictionary.put(0x278L, "http://www.w3.org/2001/04/xmlenc#Content");
        dictionary.put(0x27AL, "KeyName");
        dictionary.put(0x27CL, "MgmtData");
        dictionary.put(0x27EL, "KeyValue");
        dictionary.put(0x280L, "RSAKeyValue");
        dictionary.put(0x282L, "Modulus");
        dictionary.put(0x284L, "Exponent");
        dictionary.put(0x286L, "X509Data");
        dictionary.put(0x288L, "X509IssuerSerial");
        dictionary.put(0x28AL, "X509IssuerName");
        dictionary.put(0x28CL, "X509SerialNumber");
        dictionary.put(0x28EL, "X509Certificate");
        dictionary.put(0x290L, "AckRequested");
        dictionary.put(0x292L, "http://schemas.xmlsoap.org/ws/2005/02/rm/AckRequested");
        dictionary.put(0x294L, "AcksTo");
        dictionary.put(0x296L, "Accept");
        dictionary.put(0x298L, "CreateSequence");
        dictionary.put(0x29AL, "http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence");
        dictionary.put(0x29CL, "CreateSequenceRefused");
        dictionary.put(0x29EL, "CreateSequenceResponse");
        dictionary.put(0x2A0L, "http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse");
        dictionary.put(0x2A2L, "FaultCode");
        dictionary.put(0x2A4L, "InvalidAcknowledgement");
        dictionary.put(0x2A6L, "LastMessage");
        dictionary.put(0x2A8L, "http://schemas.xmlsoap.org/ws/2005/02/rm/LastMessage");
        dictionary.put(0x2AAL, "LastMessageNumberExceeded");
        dictionary.put(0x2ACL, "MessageNumberRollover");
        dictionary.put(0x2AEL, "Nack");
        dictionary.put(0x2B0L, "netrm");
        dictionary.put(0x2B2L, "Offer");
        dictionary.put(0x2B4L, "r");
        dictionary.put(0x2B6L, "SequenceFault");
        dictionary.put(0x2B8L, "SequenceTerminated");
        dictionary.put(0x2BAL, "TerminateSequence");
        dictionary.put(0x2BCL, "http://schemas.xmlsoap.org/ws/2005/02/rm/TerminateSequence");
        dictionary.put(0x2BEL, "UnknownSequence");
        dictionary.put(0x2C0L, "http://schemas.microsoft.com/ws/2006/02/tx/oletx");
        dictionary.put(0x2C2L, "oletx");
        dictionary.put(0x2C4L, "OleTxTransaction");
        dictionary.put(0x2C6L, "PropagationToken");
        dictionary.put(0x2C8L, "http://schemas.xmlsoap.org/ws/2004/10/wscoor");
        dictionary.put(0x2CAL, "wscoor");
        dictionary.put(0x2CCL, "CreateCoordinationContext");
        dictionary.put(0x2CEL, "CreateCoordinationContextResponse");
        dictionary.put(0x2D0L, "CoordinationContext");
        dictionary.put(0x2D2L, "CurrentContext");
        dictionary.put(0x2D4L, "CoordinationType");
        dictionary.put(0x2D6L, "RegistrationService");
        dictionary.put(0x2D8L, "Register");
        dictionary.put(0x2DAL, "RegisterResponse");
        dictionary.put(0x2DCL, "ProtocolIdentifier");
        dictionary.put(0x2DEL, "CoordinatorProtocolService");
        dictionary.put(0x2E0L, "ParticipantProtocolService");
        dictionary.put(0x2E2L, "http://schemas.xmlsoap.org/ws/2004/10/wscoor/CreateCoordinationContext");
        dictionary.put(0x2E4L, "http://schemas.xmlsoap.org/ws/2004/10/wscoor/CreateCoordinationContextResponse");
        dictionary.put(0x2E6L, "http://schemas.xmlsoap.org/ws/2004/10/wscoor/Register");
        dictionary.put(0x2E8L, "http://schemas.xmlsoap.org/ws/2004/10/wscoor/RegisterResponse");
        dictionary.put(0x2EAL, "http://schemas.xmlsoap.org/ws/2004/10/wscoor/fault");
        dictionary.put(0x2ECL, "ActivationCoordinatorPortType");
        dictionary.put(0x2EEL, "RegistrationCoordinatorPortType");
        dictionary.put(0x2F0L, "InvalidState");
        dictionary.put(0x2F2L, "InvalidProtocol");
        dictionary.put(0x2F4L, "InvalidParameters");
        dictionary.put(0x2F6L, "NoActivity");
        dictionary.put(0x2F8L, "ContextRefused");
        dictionary.put(0x2FAL, "AlreadyRegistered");
        dictionary.put(0x2FCL, "http://schemas.xmlsoap.org/ws/2004/10/wsat");
        dictionary.put(0x2FEL, "wsat");
        dictionary.put(0x300L, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Completion");
        dictionary.put(0x302L, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Durable2PC");
        dictionary.put(0x304L, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Volatile2PC");
        dictionary.put(0x306L, "Prepare");
        dictionary.put(0x308L, "Prepared");
        dictionary.put(0x30AL, "ReadOnly");
        dictionary.put(0x30CL, "Commit");
        dictionary.put(0x30EL, "Rollback");
        dictionary.put(0x310L, "Committed");
        dictionary.put(0x312L, "Aborted");
        dictionary.put(0x314L, "Replay");
        dictionary.put(0x316L, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Commit");
        dictionary.put(0x318L, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Rollback");
        dictionary.put(0x31AL, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Committed");
        dictionary.put(0x31CL, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Aborted");
        dictionary.put(0x31EL, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Prepare");
        dictionary.put(0x320L, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Prepared");
        dictionary.put(0x322L, "http://schemas.xmlsoap.org/ws/2004/10/wsat/ReadOnly");
        dictionary.put(0x324L, "http://schemas.xmlsoap.org/ws/2004/10/wsat/Replay");
        dictionary.put(0x326L, "http://schemas.xmlsoap.org/ws/2004/10/wsat/fault");
        dictionary.put(0x328L, "CompletionCoordinatorPortType");
        dictionary.put(0x32AL, "CompletionParticipantPortType");
        dictionary.put(0x32CL, "CoordinatorPortType");
        dictionary.put(0x32EL, "ParticipantPortType");
        dictionary.put(0x330L, "InconsistentInternalState");
        dictionary.put(0x332L, "mstx");
        dictionary.put(0x334L, "Enlistment");
        dictionary.put(0x336L, "protocol");
        dictionary.put(0x338L, "LocalTransactionId");
        dictionary.put(0x33AL, "IsolationLevel");
        dictionary.put(0x33CL, "IsolationFlags");
        dictionary.put(0x33EL, "Description");
        dictionary.put(0x340L, "Loopback");
        dictionary.put(0x342L, "RegisterInfo");
        dictionary.put(0x344L, "ContextId");
        dictionary.put(0x346L, "TokenId");
        dictionary.put(0x348L, "AccessDenied");
        dictionary.put(0x34AL, "InvalidPolicy");
        dictionary.put(0x34CL, "CoordinatorRegistrationFailed");
        dictionary.put(0x34EL, "TooManyEnlistments");
        dictionary.put(0x350L, "Disabled");
        dictionary.put(0x352L, "ActivityId");
        dictionary.put(0x354L, "http://schemas.microsoft.com/2004/09/ServiceModel/Diagnostics");
        dictionary.put(0x356L,
                "http://docs.oasis-open.org/wss/oasis-wss-kerberos-token-profile-1.1#Kerberosv5APREQSHA1");
        dictionary.put(0x358L, "http://schemas.xmlsoap.org/ws/2002/12/policy");
        dictionary.put(0x35AL, "FloodMessage");
        dictionary.put(0x35CL, "LinkUtility");
        dictionary.put(0x35EL, "Hops");
        dictionary.put(0x360L, "http://schemas.microsoft.com/net/2006/05/peer/HopCount");
        dictionary.put(0x362L, "PeerVia");
        dictionary.put(0x364L, "http://schemas.microsoft.com/net/2006/05/peer");
        dictionary.put(0x366L, "PeerFlooder");
        dictionary.put(0x368L, "PeerTo");
        dictionary.put(0x36AL, "http://schemas.microsoft.com/ws/2005/05/routing");
        dictionary.put(0x36CL, "PacketRoutable");
        dictionary.put(0x36EL, "http://schemas.microsoft.com/ws/2005/05/addressing/none");
        dictionary.put(0x370L, "http://schemas.microsoft.com/ws/2005/05/envelope/none");
        dictionary.put(0x372L, "http://www.w3.org/2001/XMLSchema-instance");
        dictionary.put(0x374L, "http://www.w3.org/2001/XMLSchema");
        dictionary.put(0x376L, "nil");
        dictionary.put(0x378L, "type");
        dictionary.put(0x37AL, "char");
        dictionary.put(0x37CL, "boolean");
        dictionary.put(0x37EL, "byte");
        dictionary.put(0x380L, "unsignedByte");
        dictionary.put(0x382L, "short");
        dictionary.put(0x384L, "unsignedShort");
        dictionary.put(0x386L, "int");
        dictionary.put(0x388L, "unsignedInt");
        dictionary.put(0x38AL, "long");
        dictionary.put(0x38CL, "unsignedLong");
        dictionary.put(0x38EL, "float");
        dictionary.put(0x390L, "double");
        dictionary.put(0x392L, "decimal");
        dictionary.put(0x394L, "dateTime");
        dictionary.put(0x396L, "string");
        dictionary.put(0x398L, "base64Binary");
        dictionary.put(0x39AL, "anyType");
        dictionary.put(0x39CL, "duration");
        dictionary.put(0x39EL, "guid");
        dictionary.put(0x3A0L, "anyURI");
        dictionary.put(0x3A2L, "QName");
        dictionary.put(0x3A4L, "time");
        dictionary.put(0x3A6L, "date");
        dictionary.put(0x3A8L, "hexBinary");
        dictionary.put(0x3AAL, "gYearMonth");
        dictionary.put(0x3ACL, "gYear");
        dictionary.put(0x3AEL, "gMonthDay");
        dictionary.put(0x3B0L, "gDay");
        dictionary.put(0x3B2L, "gMonth");
        dictionary.put(0x3B4L, "integer");
        dictionary.put(0x3B6L, "positiveInteger");
        dictionary.put(0x3B8L, "negativeInteger");
        dictionary.put(0x3BAL, "nonPositiveInteger");
        dictionary.put(0x3BCL, "nonNegativeInteger");
        dictionary.put(0x3BEL, "normalizedString");
        dictionary.put(0x3C0L, "ConnectionLimitReached");
        dictionary.put(0x3C2L, "http://schemas.xmlsoap.org/soap/envelope/");
        dictionary.put(0x3C4L, "actor");
        dictionary.put(0x3C6L, "faultcode");
        dictionary.put(0x3C8L, "faultstring");
        dictionary.put(0x3CAL, "faultactor");
        dictionary.put(0x3CCL, "detail");
    }

    public BinaryXml(String xml) {
        this();
        this.xml = xml;
        if (xml.length() > 0) {
            this.tagOpened = true;
        } else {
            this.listMode = true;
        }
    }

    private long readInt(ByteBuffer content) {
        int result = 0;
        int value;
        int i = 0;
        do {
            value = content.get() & 0xff;
            int seven = value & 0x7f;
            seven <<= 7 * i;
            i++;
            result |= seven;
        } while (value > 0x7f);
        return result & 0xffffffffL;
    }

    private String readString(ByteBuffer content) throws UnsupportedEncodingException {
        int len = (int) readInt(content);
        byte[] bytes = new byte[len];
        content.get(bytes);
        return new String(bytes, "UTF-8");
    }

    private String readText(ByteBuffer content) throws Exception {
        int type = content.get() & 0xff;
        return readText(content, type);
    }

    private String readText(ByteBuffer content, int type) throws Exception {
        byte[] bytes;
        int dataSize;
        long word;
        String text;
        ByteBuffer byteBuffer;
        char letter;
        switch (type) {
        case 0x80: // ZeroText
            return "0";
        case 0x82: // OneText
            return "1";
        case 0x84: // FalseText
            return "false";
        case 0x86: // TrueText
            return "true";
        case 0x88: // Int8Text
            return String.valueOf((byte) (content.get() & 0xff));
        case 0x8A: // Int16Text
            dataSize = 2;
            bytes = new byte[dataSize];
            content.get(bytes);
            return String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort());
        case 0x8C: // Int32Text
            dataSize = 4;
            bytes = new byte[dataSize];
            content.get(bytes);
            return String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt());
        case 0x8E: // Int64Text
            dataSize = 8;
            bytes = new byte[dataSize];
            content.get(bytes);
            return String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong());
        case 0x90: // FloatText
            dataSize = 4;
            bytes = new byte[dataSize];
            content.get(bytes);
            return String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getFloat());
        case 0x92: // DoubleText
            dataSize = 8;
            bytes = new byte[dataSize];
            content.get(bytes);
            return String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getDouble());
        case 0x94: // DecimalText
            dataSize = 16;
            bytes = new byte[dataSize];
            content.get(bytes);
            return makeDecimal(bytes);
        case 0x96: // DateTimeText
            dataSize = 8;
            bytes = new byte[dataSize];
            content.get(bytes);
            return makeDate(bytes);
        case 0x98: // Chars8Text
            dataSize = (content.get() & 0xff);
            bytes = new byte[dataSize];
            content.get(bytes);
            return new String(bytes, "UTF-8");
        case 0x9A: // Chars16Text
            dataSize = 2;
            bytes = new byte[dataSize];
            content.get(bytes);
            word = (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff);
            bytes = new byte[(int) word];
            content.get(bytes);
            return new String(bytes, "UTF-8");
        case 0x9C: // Chars32Text
            dataSize = 4;
            bytes = new byte[dataSize];
            content.get(bytes);
            word = (bytes[3] & 0xff) << 24 | (bytes[2] & 0xff) << 16 | (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff);
            bytes = new byte[(int) word];
            content.get(bytes);
            return new String(bytes, "UTF-8");
        case 0x9E: // Bytes8Text
            dataSize = (content.get() & 0xff);
            bytes = new byte[dataSize];
            content.get(bytes);
            return new String(Base64.encode(bytes), "UTF-8");
        case 0xA0: // Bytes16Text
            dataSize = 2;
            bytes = new byte[dataSize];
            content.get(bytes);
            word = (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff);
            bytes = new byte[(int) word];
            content.get(bytes);
            return new String(Base64.encode(bytes), "UTF-8");
        case 0xA2: // Bytes32Text
            dataSize = 4;
            bytes = new byte[dataSize];
            content.get(bytes);
            word = (bytes[3] & 0xff) << 24 | (bytes[2] & 0xff) << 16 | (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff);
            bytes = new byte[(int) word];
            content.get(bytes);
            return new String(Base64.encode(bytes), "UTF-8");
        case 0xA8: // EmptyText
            return "";
        case 0xAA: // DictionaryText
            word = readInt(content);
            return dictionary.get(word);
        case 0xAC: // UniqueIdText
            dataSize = 16;
            bytes = new byte[dataSize];
            content.get(bytes);
            return makeUrn(bytes);
        case 0xAE: // TimeSpanText
            dataSize = 8;
            bytes = new byte[dataSize];
            content.get(bytes);
            return makeTimeSpan(bytes);
        case 0xB0: // UuidText
            dataSize = 16;
            bytes = new byte[dataSize];
            content.get(bytes);
            return makeUuid(bytes);
        case 0xB2: // UInt64Text
            dataSize = 8;
            bytes = new byte[dataSize];
            content.get(bytes);
            return makeUint64(bytes);
        case 0xB4: // BoolText
            return String.valueOf(content.get() != 0);
        case 0xB6: // UnicodeChars8Text
            dataSize = (content.get() & 0xff);
            bytes = new byte[dataSize];
            content.get(bytes);
            text = "";
            byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
            while (byteBuffer.hasRemaining()) {
                text += byteBuffer.getChar();
            }
            return text;
        case 0xB8:// UnicodeChars16Text
            dataSize = 2;
            bytes = new byte[dataSize];
            content.get(bytes);
            word = (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff);
            bytes = new byte[(int) word];
            content.get(bytes);
            text = "";
            byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
            while (byteBuffer.hasRemaining()) {
                text += byteBuffer.getChar();
            }
            return text;
        case 0xBA:// UnicodeChars32Text
            dataSize = 4;
            bytes = new byte[dataSize];
            content.get(bytes);
            word = (bytes[3] & 0xff) << 24 | (bytes[2] & 0xff) << 16 | (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff);
            bytes = new byte[(int) word];
            content.get(bytes);
            text = "";
            byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
            while (byteBuffer.hasRemaining()) {
                text += byteBuffer.getChar();
            }
            return text;
        case 0xBC: // QNameDictionaryText
            letter = (char) ('a' + (content.get()));
            text = letter + ":";
            word = readInt(content);
            text += dictionary.get(word);
            return text;
        case 0xA4: // StartListText
            return new BinaryXml("").decode(content);
        }
        throw new Exception(Integer.toHexString(type));
    }

    private String makeTimeSpan(byte[] bytes) {
        // -3440000000 -PT5M44S
        // 120000000000 PT3H20M
        ByteBuffer bb = ByteBuffer.allocate(8);
        int i;
        for (i = bytes.length - 1; i >= 0; i--) {
            byte octet = (byte) (bytes[i] & 0xff);
            bb.put(octet);
        }
        bb.rewind();
        long span = bb.getLong();
        boolean negative = span < 0;
        if (negative) {
            span *= -1;
        }
        String ret = (negative ? "-" : "");

        long fraction = span % 10000000;
        span /= 10000000;
        long seconds = span % 60;
        span /= 60;
        long minutes = span % 60;
        span /= 60;
        long hours = span % 24;
        span /= 24;
        long days = span;
        ret += "PT";
        ret += days > 0 ? days + "" : "";
        ret += hours > 0 ? hours + "H" : "";
        ret += minutes > 0 ? minutes + "M" : "";
        ret += seconds > 0 ? seconds + "S" : "";
        return String.valueOf(ret);
    }

    private String makeDate(byte[] bytes) {
        ByteBuffer bb = ByteBuffer.allocate(8);
        int i;
        for (i = bytes.length - 1; i >= 0; i--) {
            byte octet = (byte) (bytes[i] & 0xff);
            bb.put(octet);
        }
        bb.rewind();
        long ticks = bb.getLong();
        long epoch = (ticks - 621355968000000000L) / 100;
        int fraction = (int) (epoch % 10000000);
        epoch /= 100;
        Date date = new Date(epoch);
        Format formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
        String ret = formatter.format(date);
        if (fraction > 0) {
            ret += "." + fraction;
        }
        return ret;
    }

    private String makeUrn(byte[] bytes) {
        return "urn:uuid:" + makeUuid(bytes);
    }

    private String makeUuid(byte[] bytes) {
        String text = "";
        int i;
        for (i = 3; i >= 0; i--) {
            String s = Integer.toHexString(bytes[i] & 0xff);
            if (s.length() == 1) {
                s = "0" + s;
            }
            text += s;
        }
        text += "-";
        for (i = 5; i >= 4; i--) {
            String s = Integer.toHexString(bytes[i] & 0xff);
            if (s.length() == 1) {
                s = "0" + s;
            }
            text += s;
        }
        text += "-";
        for (i = 7; i >= 6; i--) {
            String s = Integer.toHexString(bytes[i] & 0xff);
            if (s.length() == 1) {
                s = "0" + s;
            }
            text += s;
        }
        text += "-";
        for (i = 8; i < 10; i++) {
            String s = Integer.toHexString(bytes[i] & 0xff);
            if (s.length() == 1) {
                s = "0" + s;
            }
            text += s;
        }
        text += "-";
        for (i = 10; i < bytes.length; i++) {
            String s = Integer.toHexString(bytes[i] & 0xff);
            if (s.length() == 1) {
                s = "0" + s;
            }
            text += s;
        }
        return text;
    }

    private String makeUint64(byte[] bytes) {
        byte[] bigBytes = new byte[bytes.length];
        int i;
        for (i = 0; i < bytes.length; i++) {
            bigBytes[i] = (byte) (bytes[bytes.length - i - 1] & 0xff);
        }
        BigInteger big = new BigInteger(1, bigBytes);
        return big.toString();
    }

    private String makeDecimal(byte[] bytes) {
        int scale = bytes[2];
        int sign = bytes[3];
        int len = 12;
        int no;
        for (no = 4; no < bytes.length; no++) {
            if ((bytes[no] & 0xff) != 0) {
                break;
            }
            len--;
        }
        byte[] bigBytes = new byte[len];
        int i;
        for (i = 0; i < len; i++) {
            bigBytes[i] = (byte) (bytes[16 - i - 1] & 0xff);
        }
        BigInteger big = new BigInteger((sign == 0 ? 1 : 0), bigBytes);
        BigDecimal dec = new BigDecimal(big, scale);
        return dec.toString();
    }

    public String decode(ByteBuffer content) throws Exception {
        return decode(content, null);
    }

    private String decode(ByteBuffer content, String[] tag) throws Exception {
        content.order(ByteOrder.LITTLE_ENDIAN);
        Vector<String> stack = new Vector<String>();
        if (tag != null) {
            stack.add(tag[0]);
        }
        while (content.remaining() > 0) {
            int RecordType = content.get() & 0xff, n;
            String text;
            long word;
            char letter;
            long length;
            byte[] bytes;
            ByteBuffer byteBuffer;
            switch (RecordType) {
            case 0x01: // EndElement
                if (tag != null) {
                    tag[0] = stack.lastElement();
                    return xml;
                }
                checkBracket(true);
                xml += "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x02: // Comment
                checkBracket(true);
                text = readString(content);
                xml += "<!-- " + text + " -->\n";
                break;
            case 0x03: // Array
                String tagPointer[] = new String[1];
                text = new BinaryXml().decode(content, tagPointer);
                RecordType = content.get() & 0xff;
                int dataSize = 0;
                switch (RecordType) {
                case 0xB5: // BoolTextWithEndElement
                    dataSize = 1;
                    break;
                case 0x8B: // Int16TextWithEndElement
                    dataSize = 2;
                    break;
                case 0x8D: // Int32TextWithEndElement
                    dataSize = 4;
                    break;
                case 0x8F: // Int64TextWithEndElement
                    dataSize = 8;
                    break;
                case 0x91: // FloatTextWithEndElement
                    dataSize = 4;
                    break;
                case 0x93: // DoubleTextWithEndElement
                    dataSize = 8;
                    break;
                case 0x95: // DecimalTextWithEndElement
                    dataSize = 16;
                    break;
                case 0x97: // DateTimeTextWithEndElement
                    dataSize = 8;
                    break;
                case 0xAF: // TimeSpanTextWithEndElement
                    dataSize = 8;
                    break;
                case 0XB1: // UuidTextWithEndElement
                    dataSize = 16;
                    break;
                }
                length = readInt(content);
                for (n = 0; n < length; n++) {
                    bytes = new byte[dataSize + 1];
                    bytes[0] = (byte) (RecordType & 0xff);
                    content.get(bytes, 1, bytes.length - 1);
                    xml += new BinaryXml(text).decode(ByteBuffer.wrap(bytes), tagPointer);
                }
                break;
            case 0x04: // ShortAttribute
                text = readString(content);
                xml += " " + text + "=\"" + readText(content) + "\"";
                break;
            case 0x05: // Attribute
                xml += " " + readString(content) + ":" + readString(content) + "=\"" + readText(content) + "\"";
                break;
            case 0x06: // ShortDictionaryAttribute
                word = readInt(content);
                text = readText(content);
                xml += " " + dictionary.get(word) + "=\"" + text + "\"";
                break;
            case 0x07: // DictionaryAttribute
                xml += " " + readString(content) + ":" + readString(content) + "=\"" + readText(content) + "\"";
                break;
            case 0x08: // ShortXmlnsAttribute
                xml += " xmlns=\"" + readString(content) + "\"";
                break;
            case 0x09: // XmlnsAttribute
                text = readString(content);
                xml += " xmlns:" + text + "=\"" + readString(content) + "\"";
                break;
            case 0x0A: // ShortDictionaryXmlnsAttribute
                word = readInt(content);
                xml += " xmlns=\"" + dictionary.get(word) + "\"";
                break;
            case 0x0B: // DictionaryXmlnsAttribute
                text = readString(content);
                word = readInt(content);
                xml += " xmlns:" + text + "=\"" + dictionary.get(word) + "\"";
                break;
            case 0x0C: // PrefixDictionaryAttribute[A-Z]
            case 0x0D:
            case 0x0E:
            case 0x0F:
            case 0x10:
            case 0x11:
            case 0x12:
            case 0x13:
            case 0x14:
            case 0x15:
            case 0x16:
            case 0x17:
            case 0x18:
            case 0x19:
            case 0x1A:
            case 0x1B:
            case 0x1C:
            case 0x1D:
            case 0x1E:
            case 0x1F:
            case 0x20:
            case 0x21:
            case 0x22:
            case 0x23:
            case 0x24:
            case 0x25:
                letter = (char) ('a' + (RecordType - 0x0C));
                word = readInt(content);
                text = readText(content);
                xml += " " + letter + ":" + dictionary.get(word) + "=\"" + text + "\"";
                break;
            case 0x26: // PrefixDictionaryAttribute[A-Z]
            case 0x27:
            case 0x28:
            case 0x29:
            case 0x2A:
            case 0x2B:
            case 0x2C:
            case 0x2D:
            case 0x2E:
            case 0x2F:
            case 0x30:
            case 0x31:
            case 0x32:
            case 0x33:
            case 0x34:
            case 0x35:
            case 0x36:
            case 0x37:
            case 0x38:
            case 0x39:
            case 0x3A:
            case 0x3B:
            case 0x3C:
            case 0x3D:
            case 0x3E:
            case 0x3F:
                letter = (char) ('a' + (RecordType - 0x26));
                xml += " " + letter + ":" + readString(content) + "=\"" + readText(content) + "\"";
                break;
            case 0x40: // ShortElement
                text = readString(content);
                checkBracket(true);
                stack.add(text);
                xml += "<" + text;
                break;
            case 0x41: // Element
                text = readString(content) + ":" + readString(content);
                checkBracket(true);
                stack.add(text);
                xml += "<" + text;
                break;
            case 0x42: // ShortDictionaryElement
                word = readInt(content);
                text = dictionary.get(word);
                checkBracket(true);
                stack.add(text);
                xml += "<" + text;
                break;
            case 0x43: // DictionaryElement
                text = readString(content);
                word = readInt(content);
                text += ":" + dictionary.get(word);
                checkBracket(true);
                stack.add(text);
                xml += "<" + text;
                break;
            case 0x44: // PrefixDictionaryElement[A-Z]
            case 0x45:
            case 0x46:
            case 0x47:
            case 0x48:
            case 0x49:
            case 0x4A:
            case 0x4B:
            case 0x4C:
            case 0x4D:
            case 0x4E:
            case 0x4F:
            case 0x50:
            case 0x51:
            case 0x52:
            case 0x53:
            case 0x54:
            case 0x55:
            case 0x56:
            case 0x57:
            case 0x58:
            case 0x59:
            case 0x5A:
            case 0x5B:
            case 0x5C:
            case 0x5D:
                letter = (char) ('a' + (RecordType - 0x44));
                text = String.valueOf(letter);
                word = readInt(content);
                text += ":" + dictionary.get(word);
                checkBracket(true);
                stack.add(text);
                xml += "<" + text;
                break;
            case 0x5E: // PrefixElement[A-Z]
            case 0x5F:
            case 0x60:
            case 0x61:
            case 0x62:
            case 0x63:
            case 0x64:
            case 0x65:
            case 0x66:
            case 0x67:
            case 0x68:
            case 0x69:
            case 0x6a:
            case 0x6b:
            case 0x6c:
            case 0x6d:
            case 0x6e:
            case 0x6f:
            case 0x70:
            case 0x71:
            case 0x72:
            case 0x73:
            case 0x74:
            case 0x75:
            case 0x76:
            case 0x77:
                letter = (char) ('a' + (RecordType - 0x5E));
                text = letter + ":" + readString(content);
                checkBracket(true);
                stack.add(text);
                xml += "<" + text;
                break;
            case 0x81: // ZeroTextWithEndElement
                text = "0";
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x83: // OneTextWithEndElement
                text = "1";
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x85: // FalseTextWithEndElement
                text = "false";
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x87: // TrueTextWithEndElement
                text = "true";
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x89: // Int8TextWithEndElement
                text = String.valueOf((byte) (content.get() & 0xff));
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x8B: // Int16TextWithEndElement
                dataSize = 2;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getShort());
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x8D: // Int32TextWithEndElement
                dataSize = 4;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getInt());
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x8F: // Int64TextWithEndElement
                dataSize = 8;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getLong());
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x91: // FloatTextWithEndElement
                dataSize = 4;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getFloat());
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x93: // DoubleTextWithEndElement
                dataSize = 8;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = String.valueOf(ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN).getDouble());
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x95: // DecimalTextWithEndElement
                dataSize = 16;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = makeDecimal(bytes);
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x97: // DateTimeTextWithEndElement
                dataSize = 8;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = makeDate(bytes);
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x99: // Chars8TextWithEndElement
                dataSize = (content.get() & 0xff);
                bytes = new byte[dataSize];
                content.get(bytes);
                text = new String(bytes, "UTF-8");
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x9B: // Chars16TextWithEndElement
                dataSize = 2;
                bytes = new byte[dataSize];
                content.get(bytes);
                word = (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff);
                bytes = new byte[(int) word];
                content.get(bytes);
                text = new String(bytes, "UTF-8");
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0x9F: // Bytes8TextWithEndElement
                dataSize = (content.get() & 0xff);
                bytes = new byte[dataSize];
                content.get(bytes);
                text = new String(Base64.encode(bytes), "UTF-8");
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xA1: // Bytes16TextWithEndElement
                dataSize = 2;
                bytes = new byte[dataSize];
                content.get(bytes);
                word = (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff);
                bytes = new byte[(int) word];
                content.get(bytes);
                text = new String(Base64.encode(bytes), "UTF-8");
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xA3: // Bytes32TextWithEndElement
                dataSize = 4;
                bytes = new byte[dataSize];
                content.get(bytes);
                word = (bytes[3] & 0xff) << 24 | (bytes[2] & 0xff) << 16 | (bytes[1] & 0xff) << 8
                        | (bytes[0] & 0xff);
                bytes = new byte[(int) word];
                content.get(bytes);
                text = new String(Base64.encode(bytes), "UTF-8");
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xA6: // EndListText
                listMode = false;
                return xml;
            case 0xA9: // EmptyTextWithEndElement
                checkBracket();
                xml += "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xAB: // DictionaryTextWithEndElement
                word = readInt(content);
                text = dictionary.get(word);
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0XAD: // UniqueIdTextWithEndElement
                dataSize = 16;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = makeUrn(bytes);
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xAF: // TimeSpanTextWithEndElement
                dataSize = 8;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = makeTimeSpan(bytes);
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0XB1: // UuidTextWithEndElement
                dataSize = 16;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = makeUuid(bytes);
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xB3: // UInt64TextWithEndElement
                dataSize = 8;
                bytes = new byte[dataSize];
                content.get(bytes);
                text = makeUint64(bytes);
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xB5: // BoolTextWithEndElement
                text = String.valueOf((content.get() != 0));
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xB7: // UnicodeChars8TextWithEndElement
                dataSize = (content.get() & 0xff);
                bytes = new byte[dataSize];
                content.get(bytes);
                text = "";
                byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
                while (byteBuffer.hasRemaining()) {
                    text += byteBuffer.getChar();
                }
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xB9: // UnicodeChars16TextWithEndElement
                dataSize = 2;
                bytes = new byte[dataSize];
                content.get(bytes);
                word = (bytes[1] & 0xff) << 8 | (bytes[0] & 0xff);
                bytes = new byte[(int) word];
                content.get(bytes);
                text = "";
                byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
                while (byteBuffer.hasRemaining()) {
                    text += byteBuffer.getChar();
                }
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xBB: // UnicodeChars32TextWithEndElement
                dataSize = 4;
                bytes = new byte[dataSize];
                content.get(bytes);
                word = (bytes[3] & 0xff) << 24 | (bytes[2] & 0xff) << 16 | (bytes[1] & 0xff) << 8
                        | (bytes[0] & 0xff);
                bytes = new byte[(int) word];
                content.get(bytes);
                text = "";
                byteBuffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
                while (byteBuffer.hasRemaining()) {
                    text += byteBuffer.getChar();
                }
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            case 0xBD: // QNameDictionaryTextWithEndElement
                letter = (char) ('a' + (content.get()));
                text = letter + ":";
                word = readInt(content);
                text += dictionary.get(word);
                checkBracket();
                xml += text + "</" + stack.lastElement() + ">\n";
                stack.remove(stack.lastElement());
                break;
            default:
                checkBracket();
                if (listMode && xml.length() > 0) {
                    xml += " ";
                }
                xml += readText(content, RecordType);
            }
            if (isElement(RecordType)) {
                tagOpened = true;
            }
        }
        return xml;
    }

    private void checkBracket() {
        checkBracket(false);
    }

    private boolean isElement(int type) {
        return type >= 0x40 && type <= 0x77;
    }

    private void checkBracket(boolean nl) {
        if ((xml.trim().lastIndexOf(">") != xml.trim().length() && xml.length() > 0) && tagOpened) {
            tagOpened = false;
            xml += ">";
            if (nl) {
                xml += "\n";
            }
        }
    }
}