/*
 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.jndi.ldap;


import java.util.Enumeration;
import java.util.Vector;
import java.util.Locale;

import javax.naming.*;
import javax.naming.directory.Attributes;
import javax.naming.directory.Attribute;
import javax.naming.directory.BasicAttributes;


/**
 * <code>LdapName</code> implements compound names for LDAP v3 as
 * specified by RFC 2253.
 *<p>
 * RFC 2253 has a few ambiguities and outright inconsistencies.  These
 * are resolved as follows:
 * <ul>
 * <li> RFC 2253 leaves the term "whitespace" undefined.  The
 *      definition of "optional-space" given in RFC 1779 is used in
 *      its place:  either a space character or a carriage return ("\r").
 * <li> Whitespace is allowed on either side of ',', ';', '=', and '+'.
 *      Such whitespace is accepted but not generated by this code,
 *      and is ignored when comparing names.
 * <li> AttributeValue strings containing '=' or non-leading '#'
 *      characters (unescaped) are accepted.
 * </ul>
 *<p>
 * String names passed to <code>LdapName</code> or returned by it
 * use the full 16-bit Unicode character set.  They may also contain
 * characters encoded into UTF-8 with each octet represented by a
 * three-character substring such as "\\B4".
 * They may not, however, contain characters encoded into UTF-8 with
 * each octet represented by a single character in the string:  the
 * meaning would be ambiguous.
 *<p>
 * <code>LdapName</code> will properly parse all valid names, but
 * does not attempt to detect all possible violations when parsing
 * invalid names.  It's "generous".
 *<p>
 * When names are tested for equality, attribute types and binary
 * values are case-insensitive, and string values are by default
 * case-insensitive.
 * String values with different but equivalent usage of quoting,
 * escaping, or UTF8-hex-encoding are considered equal.  The order of
 * components in multi-valued RDNs (such as "ou=Sales+cn=Bob") is not
 * significant.
 *
 * @author Scott Seligman
 */

public final class LdapName implements Name {

    private transient String unparsed;  // if non-null, the DN in unparsed form
    private transient Vector<Rdn> rdns;      // parsed name components
    private transient boolean valuesCaseSensitive = false;

    /**
     * Constructs an LDAP name from the given DN.
     *
     * @param name      An LDAP DN.  To JNDI, a compound name.
     *
     * @throws InvalidNameException if a syntax violation is detected.
     */
    public LdapName(String name) throws InvalidNameException {
        unparsed = name;
        parse();
    }

    /*
     * Constructs an LDAP name given its parsed components and, optionally
     * (if "name" is not null), the unparsed DN.
     */
    @SuppressWarnings("unchecked") // clone()
    private LdapName(String name, Vector<Rdn> rdns) {
        unparsed = name;
        this.rdns = (Vector<Rdn>)rdns.clone();
    }

    /*
     * Constructs an LDAP name given its parsed components (the elements
     * of "rdns" in the range [beg,end)) and, optionally
     * (if "name" is not null), the unparsed DN.
     */
    private LdapName(String name, Vector<Rdn> rdns, int beg, int end) {
        unparsed = name;
        this.rdns = new Vector<>();
        for (int i = beg; i < end; i++) {
            this.rdns.addElement(rdns.elementAt(i));
        }
    }


    public Object clone() {
        return new LdapName(unparsed, rdns);
    }

    public String toString() {
        if (unparsed != null) {
            return unparsed;
        }

        StringBuffer buf = new StringBuffer();
        for (int i = rdns.size() - 1; i >= 0; i--) {
            if (i < rdns.size() - 1) {
                buf.append(',');
            }
            Rdn rdn = rdns.elementAt(i);
            buf.append(rdn);
        }

        unparsed = new String(buf);
        return unparsed;
    }

    public boolean equals(Object obj) {
        return ((obj instanceof LdapName) &&
                (compareTo(obj) == 0));
    }

    public int compareTo(Object obj) {
        LdapName that = (LdapName)obj;

        if ((obj == this) ||                    // check possible shortcuts
            (unparsed != null && unparsed.equals(that.unparsed))) {
            return 0;
        }

        // Compare RDNs one by one, lexicographically.
        int minSize = Math.min(rdns.size(), that.rdns.size());
        for (int i = 0 ; i < minSize; i++) {
            // Compare a single pair of RDNs.
            Rdn rdn1 = rdns.elementAt(i);
            Rdn rdn2 = that.rdns.elementAt(i);

            int diff = rdn1.compareTo(rdn2);
            if (diff != 0) {
                return diff;
            }
        }
        return (rdns.size() - that.rdns.size());        // longer DN wins
    }

    public int hashCode() {
        // Sum up the hash codes of the components.
        int hash = 0;

        // For each RDN...
        for (int i = 0; i < rdns.size(); i++) {
            Rdn rdn = rdns.elementAt(i);
            hash += rdn.hashCode();
        }
        return hash;
    }

    public int size() {
        return rdns.size();
    }

    public boolean isEmpty() {
        return rdns.isEmpty();
    }

    public Enumeration<String> getAll() {
        final Enumeration<Rdn> enum_ = rdns.elements();

        return new Enumeration<String>() {
            public boolean hasMoreElements() {
                return enum_.hasMoreElements();
            }
            public String nextElement() {
                return enum_.nextElement().toString();
            }
        };
    }

    public String get(int pos) {
        return rdns.elementAt(pos).toString();
    }

    public Name getPrefix(int pos) {
        return new LdapName(null, rdns, 0, pos);
    }

    public Name getSuffix(int pos) {
        return new LdapName(null, rdns, pos, rdns.size());
    }

    public boolean startsWith(Name n) {
        int len1 = rdns.size();
        int len2 = n.size();
        return (len1 >= len2 &&
                matches(0, len2, n));
    }

    public boolean endsWith(Name n) {
        int len1 = rdns.size();
        int len2 = n.size();
        return (len1 >= len2 &&
                matches(len1 - len2, len1, n));
    }

    /**
     * Controls whether string-values are treated as case-sensitive
     * when the string values within names are compared.  The default
     * behavior is case-insensitive comparison.
     */
     public void setValuesCaseSensitive(boolean caseSensitive) {
         toString();
         rdns = null;   // clear any cached information
         try {
             parse();
         } catch (InvalidNameException e) {
             // shouldn't happen
             throw new IllegalStateException("Cannot parse name: " + unparsed);
         }
         valuesCaseSensitive = caseSensitive;
     }

    /*
     * Helper method for startsWith() and endsWith().
     * Returns true if components [beg,end) match the components of "n".
     * If "n" is not an LdapName, each of its components is parsed as
     * the string form of an RDN.
     * The following must hold:  end - beg == n.size().
     */
    private boolean matches(int beg, int end, Name n) {
        for (int i = beg; i < end; i++) {
            Rdn rdn;
            if (n instanceof LdapName) {
                LdapName ln = (LdapName)n;
                rdn = ln.rdns.elementAt(i - beg);
            } else {
                String rdnString = n.get(i - beg);
                try {
                    rdn = (new DnParser(rdnString, valuesCaseSensitive)).getRdn();
                } catch (InvalidNameException e) {
                    return false;
                }
            }

            if (!rdn.equals(rdns.elementAt(i))) {
                return false;
            }
        }
        return true;
    }

    public Name addAll(Name suffix) throws InvalidNameException {
        return addAll(size(), suffix);
    }

    /*
     * If "suffix" is not an LdapName, each of its components is parsed as
     * the string form of an RDN.
     */
    public Name addAll(int pos, Name suffix) throws InvalidNameException {
        if (suffix instanceof LdapName) {
            LdapName s = (LdapName)suffix;
            for (int i = 0; i < s.rdns.size(); i++) {
                rdns.insertElementAt(s.rdns.elementAt(i), pos++);
            }
        } else {
            Enumeration<String> comps = suffix.getAll();
            while (comps.hasMoreElements()) {
                DnParser p = new DnParser(comps.nextElement(),
                    valuesCaseSensitive);
                rdns.insertElementAt(p.getRdn(), pos++);
            }
        }
        unparsed = null;                                // no longer valid
        return this;
    }

    public Name add(String comp) throws InvalidNameException {
        return add(size(), comp);
    }

    public Name add(int pos, String comp) throws InvalidNameException {
        Rdn rdn = (new DnParser(comp, valuesCaseSensitive)).getRdn();
        rdns.insertElementAt(rdn, pos);
        unparsed = null;                                // no longer valid
        return this;
    }

    public Object remove(int pos) throws InvalidNameException {
        String comp = get(pos);
        rdns.removeElementAt(pos);
        unparsed = null;                                // no longer valid
        return comp;
    }


    private void parse() throws InvalidNameException {
        rdns = (new DnParser(unparsed, valuesCaseSensitive)).getDn();
    }

    /*
     * Best guess as to what RFC 2253 means by "whitespace".
     */
    private static boolean isWhitespace(char c) {
        return (c == ' ' || c == '\r');
    }

    /**
     * Given the value of an attribute, returns a string suitable
     * for inclusion in a DN.  If the value is a string, this is
     * accomplished by using backslash (\) to escape the following
     * characters:
     *<ul>
     *<li>leading and trailing whitespace
     *<li><pre>, = + < > # ; " \</pre>
     *</ul>
     * If the value is a byte array, it is converted to hex
     * notation (such as "#CEB1DF80").
     */
    public static String escapeAttributeValue(Object val) {
        return TypeAndValue.escapeValue(val);
    }

    /**
     * Given an attribute value formated according to RFC 2253,
     * returns the unformated value.  Returns a string value as
     * a string, and a binary value as a byte array.
     */
    public static Object unescapeAttributeValue(String val) {
        return TypeAndValue.unescapeValue(val);
    }

    /**
     * Serializes only the unparsed DN, for compactness and to avoid
     * any implementation dependency.
     *
     * @serialdata      The DN string and a boolean indicating whether
     * the values are case sensitive.
     */
    private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
        s.writeObject(toString());
        s.writeBoolean(valuesCaseSensitive);
    }

    private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
        unparsed = (String)s.readObject();
        valuesCaseSensitive = s.readBoolean();
        try {
            parse();
        } catch (InvalidNameException e) {
            // shouldn't happen
            throw new java.io.StreamCorruptedException(
                    "Invalid name: " + unparsed);
        }
    }

    static final long serialVersionUID = -1595520034788997356L;


    /*
     * DnParser implements a recursive descent parser for a single DN.
     */
    static class DnParser {

        private final String name;      // DN being parsed
        private final char[] chars;     // characters in LDAP name being parsed
        private final int len;          // length of "chars"
        private int cur = 0;            // index of first unconsumed char in "chars"
        private boolean valuesCaseSensitive;

        /*
         * Given an LDAP DN in string form, returns a parser for it.
         */
        DnParser(String name, boolean valuesCaseSensitive)
            throws InvalidNameException {
            this.name = name;
            len = name.length();
            chars = name.toCharArray();
            this.valuesCaseSensitive = valuesCaseSensitive;
        }

        /*
         * Parses the DN, returning a Vector of its RDNs.
         */
        Vector<Rdn> getDn() throws InvalidNameException {
            cur = 0;
            Vector<Rdn> rdns = new Vector<>(len / 3 + 10);  // leave room for growth

            if (len == 0) {
                return rdns;
            }

            rdns.addElement(parseRdn());
            while (cur < len) {
                if (chars[cur] == ',' || chars[cur] == ';') {
                    ++cur;
                    rdns.insertElementAt(parseRdn(), 0);
                } else {
                    throw new InvalidNameException("Invalid name: " + name);
                }
            }
            return rdns;
        }

        /*
         * Parses the DN, if it is known to contain a single RDN.
         */
        Rdn getRdn() throws InvalidNameException {
            Rdn rdn = parseRdn();
            if (cur < len) {
                throw new InvalidNameException("Invalid RDN: " + name);
            }
            return rdn;
        }

        /*
         * Parses the next RDN and returns it.  Throws an exception if
         * none is found.  Leading and trailing whitespace is consumed.
         */
        private Rdn parseRdn() throws InvalidNameException {

            Rdn rdn = new Rdn();
            while (cur < len) {
                consumeWhitespace();
                String attrType = parseAttrType();
                consumeWhitespace();
                if (cur >= len || chars[cur] != '=') {
                    throw new InvalidNameException("Invalid name: " + name);
                }
                ++cur;          // consume '='
                consumeWhitespace();
                String value = parseAttrValue();
                consumeWhitespace();

                rdn.add(new TypeAndValue(attrType, value, valuesCaseSensitive));
                if (cur >= len || chars[cur] != '+') {
                    break;
                }
                ++cur;          // consume '+'
            }
            return rdn;
        }

        /*
         * Returns the attribute type that begins at the next unconsumed
         * char.  No leading whitespace is expected.
         * This routine is more generous than RFC 2253.  It accepts
         * attribute types composed of any nonempty combination of Unicode
         * letters, Unicode digits, '.', '-', and internal space characters.
         */
        private String parseAttrType() throws InvalidNameException {

            final int beg = cur;
            while (cur < len) {
                char c = chars[cur];
                if (Character.isLetterOrDigit(c) ||
                      c == '.' ||
                      c == '-' ||
                      c == ' ') {
                    ++cur;
                } else {
                    break;
                }
            }
            // Back out any trailing spaces.
            while ((cur > beg) && (chars[cur - 1] == ' ')) {
                --cur;
            }

            if (beg == cur) {
                throw new InvalidNameException("Invalid name: " + name);
            }
            return new String(chars, beg, cur - beg);
        }

        /*
         * Returns the attribute value that begins at the next unconsumed
         * char.  No leading whitespace is expected.
         */
        private String parseAttrValue() throws InvalidNameException {

            if (cur < len && chars[cur] == '#') {
                return parseBinaryAttrValue();
            } else if (cur < len && chars[cur] == '"') {
                return parseQuotedAttrValue();
            } else {
                return parseStringAttrValue();
            }
        }

        private String parseBinaryAttrValue() throws InvalidNameException {
            final int beg = cur;
            ++cur;                      // consume '#'
            while (cur < len &&
                   Character.isLetterOrDigit(chars[cur])) {
                ++cur;
            }
            return new String(chars, beg, cur - beg);
        }

        private String parseQuotedAttrValue() throws InvalidNameException {

            final int beg = cur;
            ++cur;                      // consume '"'

            while ((cur < len) && chars[cur] != '"') {
                if (chars[cur] == '\\') {
                    ++cur;              // consume backslash, then what follows
                }
                ++cur;
            }
            if (cur >= len) {   // no closing quote
                throw new InvalidNameException("Invalid name: " + name);
            }
            ++cur       ;       // consume closing quote

            return new String(chars, beg, cur - beg);
        }

        private String parseStringAttrValue() throws InvalidNameException {

            final int beg = cur;
            int esc = -1;       // index of the most recently escaped character

            while ((cur < len) && !atTerminator()) {
                if (chars[cur] == '\\') {
                    ++cur;              // consume backslash, then what follows
                    esc = cur;
                }
                ++cur;
            }
            if (cur > len) {            // 'twas backslash followed by nothing
                throw new InvalidNameException("Invalid name: " + name);
            }

            // Trim off (unescaped) trailing whitespace.
            int end;
            for (end = cur; end > beg; end--) {
                if (!isWhitespace(chars[end - 1]) || (esc == end - 1)) {
                    break;
                }
            }
            return new String(chars, beg, end - beg);
        }

        private void consumeWhitespace() {
            while ((cur < len) && isWhitespace(chars[cur])) {
                ++cur;
            }
        }

        /*
         * Returns true if next unconsumed character is one that terminates
         * a string attribute value.
         */
        private boolean atTerminator() {
            return (cur < len &&
                    (chars[cur] == ',' ||
                     chars[cur] == ';' ||
                     chars[cur] == '+'));
        }
    }


    /*
     * Class Rdn represents a set of TypeAndValue.
     */
    static class Rdn {

        /*
         * A vector of the TypeAndValue elements of this Rdn.
         * It is sorted to facilitate set operations.
         */
        private final Vector<TypeAndValue> tvs = new Vector<>();

        void add(TypeAndValue tv) {

            // Set i to index of first element greater than tv, or to
            // tvs.size() if there is none.
            int i;
            for (i = 0; i < tvs.size(); i++) {
                int diff = tv.compareTo(tvs.elementAt(i));
                if (diff == 0) {
                    return;             // tv is a duplicate:  ignore it
                } else if (diff < 0) {
                    break;
                }
            }

            tvs.insertElementAt(tv, i);
        }

        public String toString() {
            StringBuffer buf = new StringBuffer();
            for (int i = 0; i < tvs.size(); i++) {
                if (i > 0) {
                    buf.append('+');
                }
                buf.append(tvs.elementAt(i));
            }
            return new String(buf);
        }

        public boolean equals(Object obj) {
            return ((obj instanceof Rdn) &&
                    (compareTo(obj) == 0));
        }

        // Compare TypeAndValue components one by one, lexicographically.
        public int compareTo(Object obj) {
            Rdn that = (Rdn)obj;
            int minSize = Math.min(tvs.size(), that.tvs.size());
            for (int i = 0; i < minSize; i++) {
                // Compare a single pair of type/value pairs.
                TypeAndValue tv = tvs.elementAt(i);
                int diff = tv.compareTo(that.tvs.elementAt(i));
                if (diff != 0) {
                    return diff;
                }
            }
            return (tvs.size() - that.tvs.size());      // longer RDN wins
        }

        public int hashCode() {
            // Sum up the hash codes of the components.
            int hash = 0;

            // For each type/value pair...
            for (int i = 0; i < tvs.size(); i++) {
                hash += tvs.elementAt(i).hashCode();
            }
            return hash;
        }

        Attributes toAttributes() {
            Attributes attrs = new BasicAttributes(true);
            TypeAndValue tv;
            Attribute attr;

            for (int i = 0; i < tvs.size(); i++) {
                tv = tvs.elementAt(i);
                if ((attr = attrs.get(tv.getType())) == null) {
                    attrs.put(tv.getType(), tv.getUnescapedValue());
                } else {
                    attr.add(tv.getUnescapedValue());
                }
            }
            return attrs;
        }
    }


    /*
     * Class TypeAndValue represents an attribute type and its
     * corresponding value.
     */
    static class TypeAndValue {

        private final String type;
        private final String value;             // value, escaped or quoted
        private final boolean binary;
        private final boolean valueCaseSensitive;

        // If non-null, a canonical represention of the value suitable
        // for comparison using String.compareTo().
        private String comparable = null;

        TypeAndValue(String type, String value, boolean valueCaseSensitive) {
            this.type = type;
            this.value = value;
            binary = value.startsWith("#");
            this.valueCaseSensitive = valueCaseSensitive;
        }

        public String toString() {
            return (type + "=" + value);
        }

        public int compareTo(Object obj) {
            // NB: Any change here affecting equality must be
            //     reflected in hashCode().

            TypeAndValue that = (TypeAndValue)obj;

            int diff = type.compareToIgnoreCase(that.type);
            if (diff != 0) {
                return diff;
            }
            if (value.equals(that.value)) {     // try shortcut
                return 0;
            }
            return getValueComparable().compareTo(that.getValueComparable());
        }

        public boolean equals(Object obj) {
            // NB:  Any change here must be reflected in hashCode().
            if (!(obj instanceof TypeAndValue)) {
                return false;
            }
            TypeAndValue that = (TypeAndValue)obj;
            return (type.equalsIgnoreCase(that.type) &&
                    (value.equals(that.value) ||
                     getValueComparable().equals(that.getValueComparable())));
        }

        public int hashCode() {
            // If two objects are equal, their hash codes must match.
            return (type.toUpperCase(Locale.ENGLISH).hashCode() +
                    getValueComparable().hashCode());
        }

        /*
         * Returns the type.
         */
        String getType() {
            return type;
        }

        /*
         * Returns the unescaped value.
         */
        Object getUnescapedValue() {
            return unescapeValue(value);
        }

        /*
         * Returns a canonical representation of "value" suitable for
         * comparison using String.compareTo().  If "value" is a string,
         * it is returned with escapes and quotes stripped away, and
         * hex-encoded UTF-8 converted to 16-bit Unicode chars.
         * If value's case is to be ignored, it is returned in uppercase.
         * If "value" is binary, it is returned in uppercase but
         * otherwise unmodified.
         */
        private String getValueComparable() {
            if (comparable != null) {
                return comparable;      // return cached result
            }

            // cache result
            if (binary) {
                comparable = value.toUpperCase(Locale.ENGLISH);
            } else {
                comparable = (String)unescapeValue(value);
                if (!valueCaseSensitive) {
                    // ignore case
                    comparable = comparable.toUpperCase(Locale.ENGLISH);
                }
            }
            return comparable;
        }

        /*
         * Given the value of an attribute, returns a string suitable
         * for inclusion in a DN.
         */
        static String escapeValue(Object val) {
            return (val instanceof byte[])
                ? escapeBinaryValue((byte[])val)
                : escapeStringValue((String)val);
        }

        /*
         * Given the value of a string-valued attribute, returns a
         * string suitable for inclusion in a DN.  This is accomplished by
         * using backslash (\) to escape the following characters:
         *      leading and trailing whitespace
         *      , = + < > # ; " \
         */
        private static String escapeStringValue(String val) {

            final String escapees = ",=+<>#;\"\\";
            char[] chars = val.toCharArray();
            StringBuffer buf = new StringBuffer(2 * val.length());

            // Find leading and trailing whitespace.
            int lead;   // index of first char that is not leading whitespace
            for (lead = 0; lead < chars.length; lead++) {
                if (!isWhitespace(chars[lead])) {
                    break;
                }
            }
            int trail;  // index of last char that is not trailing whitespace
            for (trail = chars.length - 1; trail >= 0; trail--) {
                if (!isWhitespace(chars[trail])) {
                    break;
                }
            }

            for (int i = 0; i < chars.length; i++) {
                char c = chars[i];
                if ((i < lead) || (i > trail) || (escapees.indexOf(c) >= 0)) {
                    buf.append('\\');
                }
                buf.append(c);
            }
            return new String(buf);
        }

        /*
         * Given the value of a binary attribute, returns a string
         * suitable for inclusion in a DN (such as "#CEB1DF80").
         */
        private static String escapeBinaryValue(byte[] val) {

            StringBuffer buf = new StringBuffer(1 + 2 * val.length);
            buf.append("#");

            for (int i = 0; i < val.length; i++) {
                byte b = val[i];
                buf.append(Character.forDigit(0xF & (b >>> 4), 16));
                buf.append(Character.forDigit(0xF & b, 16));
            }

            return (new String(buf)).toUpperCase(Locale.ENGLISH);
        }

        /*
         * Given an attribute value formated according to RFC 2253,
         * returns the unformated value.  Escapes and quotes are
         * stripped away, and hex-encoded UTF-8 is converted to 16-bit
         * Unicode chars.  Returns a string value as a String, and a
         * binary value as a byte array.
         */
        static Object unescapeValue(String val) {

            char[] chars = val.toCharArray();
            int beg = 0;
            int end = chars.length;

            // Trim off leading and trailing whitespace.
            while ((beg < end) && isWhitespace(chars[beg])) {
                ++beg;
            }
            while ((beg < end) && isWhitespace(chars[end - 1])) {
                --end;
            }

            // Add back the trailing whitespace with a preceding '\'
            // (escaped or unescaped) that was taken off in the above
            // loop. Whether or not to retain this whitespace is
            // decided below.
            if (end != chars.length &&
                    (beg < end) &&
                    chars[end - 1] == '\\') {
                end++;
            }
            if (beg >= end) {
                return "";
            }

            if (chars[beg] == '#') {
                // Value is binary (eg: "#CEB1DF80").
                return decodeHexPairs(chars, ++beg, end);
            }

            // Trim off quotes.
            if ((chars[beg] == '\"') && (chars[end - 1] == '\"')) {
                ++beg;
                --end;
            }

            StringBuffer buf = new StringBuffer(end - beg);
            int esc = -1; // index of the last escaped character

            for (int i = beg; i < end; i++) {
                if ((chars[i] == '\\') && (i + 1 < end)) {
                    if (!Character.isLetterOrDigit(chars[i + 1])) {
                        ++i;                    // skip backslash
                        buf.append(chars[i]);   // snarf escaped char
                        esc = i;
                    } else {

                        // Convert hex-encoded UTF-8 to 16-bit chars.
                        byte[] utf8 = getUtf8Octets(chars, i, end);
                        if (utf8.length > 0) {
                            try {
                                buf.append(new String(utf8, "UTF8"));
                            } catch (java.io.UnsupportedEncodingException e) {
                                // shouldn't happen
                            }
                            i += utf8.length * 3 - 1;
                        } else {
                            throw new IllegalArgumentException(
                                "Not a valid attribute string value:" +
                                val +", improper usage of backslash");
                        }
                    }
                } else {
                    buf.append(chars[i]);       // snarf unescaped char
                }
            }

            // Get rid of the unescaped trailing whitespace with the
            // preceding '\' character that was previously added back.
            int len = buf.length();
            if (isWhitespace(buf.charAt(len - 1)) && esc != (end - 1)) {
                buf.setLength(len - 1);
            }

            return new String(buf);
        }


        /*
         * Given an array of chars (with starting and ending indexes into it)
         * representing bytes encoded as hex-pairs (such as "CEB1DF80"),
         * returns a byte array containing the decoded bytes.
         */
        private static byte[] decodeHexPairs(char[] chars, int beg, int end) {
            byte[] bytes = new byte[(end - beg) / 2];
            for (int i = 0; beg + 1 < end; i++) {
                int hi = Character.digit(chars[beg], 16);
                int lo = Character.digit(chars[beg + 1], 16);
                if (hi < 0 || lo < 0) {
                    break;
                }
                bytes[i] = (byte)((hi<<4) + lo);
                beg += 2;
            }
            if (beg != end) {
                throw new IllegalArgumentException(
                        "Illegal attribute value: #" + new String(chars));
            }
            return bytes;
        }

        /*
         * Given an array of chars (with starting and ending indexes into it),
         * finds the largest prefix consisting of hex-encoded UTF-8 octets,
         * and returns a byte array containing the corresponding UTF-8 octets.
         *
         * Hex-encoded UTF-8 octets look like this:
         *      \03\B1\DF\80
         */
        private static byte[] getUtf8Octets(char[] chars, int beg, int end) {
            byte[] utf8 = new byte[(end - beg) / 3];    // allow enough room
            int len = 0;        // index of first unused byte in utf8

            while ((beg + 2 < end) &&
                   (chars[beg++] == '\\')) {
                int hi = Character.digit(chars[beg++], 16);
                int lo = Character.digit(chars[beg++], 16);
                if (hi < 0 || lo < 0) {
                    break;
                }
                utf8[len++] = (byte)((hi<<4) + lo);
            }

            if (len == utf8.length) {
                return utf8;
            } else {
                byte[] res = new byte[len];
                System.arraycopy(utf8, 0, res, 0, len);
                return res;
            }
        }
    }


    /*
     * For testing.
     */
/*
    public static void main(String[] args) {

        try {
            if (args.length == 1) {             // parse and print components
                LdapName n = new LdapName(args[0]);

                Enumeration rdns = n.rdns.elements();
                while (rdns.hasMoreElements()) {
                    Rdn rdn = (Rdn)rdns.nextElement();
                    for (int i = 0; i < rdn.tvs.size(); i++) {
                        System.out.print("[" + rdn.tvs.elementAt(i) + "]");
                    }
                    System.out.println();
                }

            } else {                            // compare two names
                LdapName n1 = new LdapName(args[0]);
                LdapName n2 = new LdapName(args[1]);
                n1.unparsed = null;
                n2.unparsed = null;
                boolean eq = n1.equals(n2);
                System.out.println("[" + n1 + (eq ? "] == [" : "] != [")
                                   + n2 + "]");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
*/
}
