/*
 * Copyright 1999-2005 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.jndi.ldap;

import java.net.*;
import java.io.*;
import java.util.Vector;
import java.util.Hashtable;

import javax.naming.*;
import javax.naming.directory.*;
import javax.naming.ldap.*;

import com.sun.jndi.ldap.pool.PooledConnection;
import com.sun.jndi.ldap.pool.PoolCallback;
import com.sun.jndi.ldap.sasl.LdapSasl;
import com.sun.jndi.ldap.sasl.SaslInputStream;

/**
 * LDAP (RFC-1777) and LDAPv3 (RFC-2251) compliant client
 *
 * This class represents a connection to an LDAP client.
 * Callers interact with this class at an LDAP operation level.
 * That is, the caller invokes a method to do a SEARCH or MODRDN
 * operation and gets back the result.
 * The caller uses the constructor to create a connection to the server.
 * It then needs to use authenticate() to perform an LDAP BIND.
 * Note that for v3, BIND is optional so authenticate() might not
 * actually send a BIND. authenticate() can be used later on to issue
 * a BIND, for example, for a v3 client that wants to change the connection's
 * credentials.
 *<p>
 * Multiple LdapCtx might share the same LdapClient. For example, contexts
 * derived from the same initial context would share the same LdapClient
 * until changes to a context's properties necessitates its own LdapClient.
 * LdapClient methods that access shared data are thread-safe (i.e., caller
 * does not have to sync).
 *<p>
 * Fields:
 *   isLdapv3 - no sync; initialized and updated within sync authenticate();
 *       always updated when connection is "quiet" and not shared;
 *       read access from outside LdapClient not sync
 *   referenceCount - sync within LdapClient; exception is forceClose() which
 *       is used by Connection thread to close connection upon receiving
 *       an Unsolicited Notification.
 *       access from outside LdapClient must sync;
 *   conn - no sync; Connection takes care of its own sync
 *   unsolicited - sync Vector; multiple operations sync'ed
 *
 * @author Vincent Ryan
 * @author Jagane Sundar
 * @author Rosanna Lee
 */

public final class LdapClient implements PooledConnection {
    // ---------------------- Constants ----------------------------------
    private static final int debug = 0;
    static final boolean caseIgnore = true;

    // Default list of binary attributes
    private static final Hashtable defaultBinaryAttrs = new Hashtable(23,0.75f);
    static {
        defaultBinaryAttrs.put("userpassword", Boolean.TRUE);      //2.5.4.35
        defaultBinaryAttrs.put("javaserializeddata", Boolean.TRUE);
                                                //1.3.6.1.4.1.42.2.27.4.1.8
        defaultBinaryAttrs.put("javaserializedobject", Boolean.TRUE);
                                                // 1.3.6.1.4.1.42.2.27.4.1.2
        defaultBinaryAttrs.put("jpegphoto", Boolean.TRUE);
                                                //0.9.2342.19200300.100.1.60
        defaultBinaryAttrs.put("audio", Boolean.TRUE);  //0.9.2342.19200300.100.1.55
        defaultBinaryAttrs.put("thumbnailphoto", Boolean.TRUE);
                                                //1.3.6.1.4.1.1466.101.120.35
        defaultBinaryAttrs.put("thumbnaillogo", Boolean.TRUE);
                                                //1.3.6.1.4.1.1466.101.120.36
        defaultBinaryAttrs.put("usercertificate", Boolean.TRUE);     //2.5.4.36
        defaultBinaryAttrs.put("cacertificate", Boolean.TRUE);       //2.5.4.37
        defaultBinaryAttrs.put("certificaterevocationlist", Boolean.TRUE);
                                                //2.5.4.39
        defaultBinaryAttrs.put("authorityrevocationlist", Boolean.TRUE); //2.5.4.38
        defaultBinaryAttrs.put("crosscertificatepair", Boolean.TRUE);    //2.5.4.40
        defaultBinaryAttrs.put("photo", Boolean.TRUE);   //0.9.2342.19200300.100.1.7
        defaultBinaryAttrs.put("personalsignature", Boolean.TRUE);
                                                //0.9.2342.19200300.100.1.53
        defaultBinaryAttrs.put("x500uniqueidentifier", Boolean.TRUE); //2.5.4.45
    }

    private static final String DISCONNECT_OID = "1.3.6.1.4.1.1466.20036";


    // ----------------------- instance fields ------------------------
    boolean isLdapv3;         // Used by LdapCtx
    int referenceCount = 1;   // Used by LdapCtx for check for sharing

    Connection conn;  // Connection to server; has reader thread
                      // used by LdapCtx for StartTLS

    final private PoolCallback pcb;
    final private boolean pooled;
    private boolean authenticateCalled = false;

    ////////////////////////////////////////////////////////////////////////////
    //
    // constructor: Create an authenticated connection to server
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapClient(String host, int port, String socketFactory,
        int connectTimeout, int readTimeout, OutputStream trace, PoolCallback pcb)
        throws NamingException {

        if (debug > 0)
            System.err.println("LdapClient: constructor called " + host + ":" + port );
        conn = new Connection(this, host, port, socketFactory, connectTimeout, readTimeout,
            trace);

        this.pcb = pcb;
        pooled = (pcb != null);
    }

    synchronized boolean authenticateCalled() {
        return authenticateCalled;
    }

    synchronized LdapResult
    authenticate(boolean initial, String name, Object pw, int version,
        String authMechanism, Control[] ctls,  Hashtable env)
        throws NamingException {

        authenticateCalled = true;

        try {
            ensureOpen();
        } catch (IOException e) {
            NamingException ne = new CommunicationException();
            ne.setRootCause(e);
            throw ne;
        }

        switch (version) {
        case LDAP_VERSION3_VERSION2:
        case LDAP_VERSION3:
            isLdapv3 = true;
            break;
        case LDAP_VERSION2:
            isLdapv3 = false;
            break;
        default:
            throw new CommunicationException("Protocol version " + version +
                " not supported");
        }

        LdapResult res = null;

        if (authMechanism.equalsIgnoreCase("none") ||
            authMechanism.equalsIgnoreCase("anonymous")) {

            // Perform LDAP bind if we are reauthenticating, using LDAPv2,
            // supporting failover to LDAPv2, or controls have been supplied.
            if (!initial ||
                (version == LDAP_VERSION2) ||
                (version == LDAP_VERSION3_VERSION2) ||
                ((ctls != null) && (ctls.length > 0))) {
                try {
                    // anonymous bind; update name/pw for LDAPv2 retry
                    res = ldapBind(name=null, (byte[])(pw=null), ctls, null,
                        false);
                    if (res.status == LdapClient.LDAP_SUCCESS) {
                        conn.setBound();
                    }
                } catch (IOException e) {
                    NamingException ne =
                        new CommunicationException("anonymous bind failed: " +
                        conn.host + ":" + conn.port);
                    ne.setRootCause(e);
                    throw ne;
                }
            } else {
                // Skip LDAP bind for LDAPv3 anonymous bind
                res = new LdapResult();
                res.status = LdapClient.LDAP_SUCCESS;
            }
        } else if (authMechanism.equalsIgnoreCase("simple")) {
            // simple authentication
            byte[] encodedPw = null;
            try {
                encodedPw = encodePassword(pw, isLdapv3);
                res = ldapBind(name, encodedPw, ctls, null, false);
                if (res.status == LdapClient.LDAP_SUCCESS) {
                    conn.setBound();
                }
            } catch (IOException e) {
                NamingException ne =
                    new CommunicationException("simple bind failed: " +
                        conn.host + ":" + conn.port);
                ne.setRootCause(e);
                throw ne;
            } finally {
                // If pw was copied to a new array, clear that array as
                // a security precaution.
                if (encodedPw != pw && encodedPw != null) {
                    for (int i = 0; i < encodedPw.length; i++) {
                        encodedPw[i] = 0;
                    }
                }
            }
        } else if (isLdapv3) {
            // SASL authentication
            try {
                res = LdapSasl.saslBind(this, conn, conn.host, name, pw,
                    authMechanism, env, ctls);
                if (res.status == LdapClient.LDAP_SUCCESS) {
                    conn.setBound();
                }
            } catch (IOException e) {
                NamingException ne =
                    new CommunicationException("SASL bind failed: " +
                    conn.host + ":" + conn.port);
                ne.setRootCause(e);
                throw ne;
            }
        } else {
            throw new AuthenticationNotSupportedException(authMechanism);
        }

        //
        // re-try login using v2 if failing over
        //
        if (initial &&
            (res.status == LdapClient.LDAP_PROTOCOL_ERROR) &&
            (version == LdapClient.LDAP_VERSION3_VERSION2) &&
            (authMechanism.equalsIgnoreCase("none") ||
                authMechanism.equalsIgnoreCase("anonymous") ||
                authMechanism.equalsIgnoreCase("simple"))) {

            byte[] encodedPw = null;
            try {
                isLdapv3 = false;
                encodedPw = encodePassword(pw, false);
                res = ldapBind(name, encodedPw, ctls, null, false);
                if (res.status == LdapClient.LDAP_SUCCESS) {
                    conn.setBound();
                }
            } catch (IOException e) {
                NamingException ne =
                    new CommunicationException(authMechanism + ":" +
                        conn.host +     ":" + conn.port);
                ne.setRootCause(e);
                throw ne;
            } finally {
                // If pw was copied to a new array, clear that array as
                // a security precaution.
                if (encodedPw != pw && encodedPw != null) {
                    for (int i = 0; i < encodedPw.length; i++) {
                        encodedPw[i] = 0;
                    }
                }
            }
        }

        // principal name not found
        // (map NameNotFoundException to AuthenticationException)
        // %%% This is a workaround for Netscape servers returning
        // %%% no such object when the principal name is not found
        // %%% Note that when this workaround is applied, it does not allow
        // %%% response controls to be recorded by the calling context
        if (res.status == LdapClient.LDAP_NO_SUCH_OBJECT) {
            throw new AuthenticationException(
                getErrorMessage(res.status, res.errorMessage));
        }
        conn.setV3(isLdapv3);
        return res;
    }

    /**
     * Sends an LDAP Bind request.
     * Cannot be private; called by LdapSasl
     * @param dn The possibly null DN to use in the BIND request. null if anonymous.
     * @param toServer The possibly null array of bytes to send to the server.
     * @param auth The authentication mechanism
     *
     */
    synchronized public LdapResult ldapBind(String dn, byte[]toServer,
        Control[] bindCtls, String auth, boolean pauseAfterReceipt)
        throws java.io.IOException, NamingException {

        ensureOpen();

        // flush outstanding requests
        conn.abandonOutstandingReqs(null);

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();
        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        //
        // build the bind request.
        //
        ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
            ber.encodeInt(curMsgId);
            ber.beginSeq(LdapClient.LDAP_REQ_BIND);
                ber.encodeInt(isLdapv3 ? LDAP_VERSION3 : LDAP_VERSION2);
                ber.encodeString(dn, isLdapv3);

                // if authentication mechanism specified, it is SASL
                if (auth != null) {
                    ber.beginSeq(Ber.ASN_CONTEXT | Ber.ASN_CONSTRUCTOR | 3);
                        ber.encodeString(auth, isLdapv3);    // SASL mechanism
                        if (toServer != null) {
                            ber.encodeOctetString(toServer,
                                Ber.ASN_OCTET_STR);
                        }
                    ber.endSeq();
                } else {
                    if (toServer != null) {
                        ber.encodeOctetString(toServer, Ber.ASN_CONTEXT);
                    } else {
                        ber.encodeOctetString(null, Ber.ASN_CONTEXT, 0, 0);
                    }
                }
            ber.endSeq();

            // Encode controls
            if (isLdapv3) {
                encodeControls(ber, bindCtls);
            }
        ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId, pauseAfterReceipt);
        if (toServer != null) {
            ber.reset();        // clear internally-stored password
        }

        // Read reply
        BerDecoder rber = conn.readReply(req);

        rber.parseSeq(null);    // init seq
        rber.parseInt();        // msg id
        if (rber.parseByte() !=  LDAP_REP_BIND) {
            return res;
        }

        rber.parseLength();
        parseResult(rber, res, isLdapv3);

        // handle server's credentials (if present)
        if (isLdapv3 &&
            (rber.bytesLeft() > 0) &&
            (rber.peekByte() == (Ber.ASN_CONTEXT | 7))) {
            res.serverCreds = rber.parseOctetString((Ber.ASN_CONTEXT | 7), null);
        }

        res.resControls = isLdapv3 ? parseControls(rber) : null;

        conn.removeRequest(req);
        return res;
    }

    /**
     * Determines whether SASL encryption/integrity is in progress.
     * This check is made prior to reauthentication. You cannot reauthenticate
     * over an encrypted/integrity-protected SASL channel. You must
     * close the channel and open a new one.
     */
    boolean usingSaslStreams() {
        return (conn.inStream instanceof SaslInputStream);
    }

    synchronized void incRefCount() {
        ++referenceCount;
        if (debug > 1) {
            System.err.println("LdapClient.incRefCount: " + referenceCount + " " + this);
        }

    }

    /**
     * Returns the encoded password.
     */
    private static byte[] encodePassword(Object pw, boolean v3) throws IOException {

        if (pw instanceof char[]) {
            pw = new String((char[])pw);
        }

        if (pw instanceof String) {
            if (v3) {
                return ((String)pw).getBytes("UTF8");
            } else {
                return ((String)pw).getBytes("8859_1");
            }
        } else {
            return (byte[])pw;
        }
    }

    synchronized void close(Control[] reqCtls, boolean hardClose) {
        --referenceCount;

        if (debug > 1) {
            System.err.println("LdapClient: " + this);
            System.err.println("LdapClient: close() called: " + referenceCount);
            (new Throwable()).printStackTrace();
        }

        if (referenceCount <= 0 && conn != null) {
            if (debug > 0) System.err.println("LdapClient: closed connection " + this);
            if (!pooled) {
                // Not being pooled; continue with closing
                conn.cleanup(reqCtls, false);
                conn = null;
            } else {
                // Pooled

                // Is this a real close or a request to return conn to pool
                if (hardClose) {
                    conn.cleanup(reqCtls, false);
                    conn = null;
                    pcb.removePooledConnection(this);
                } else {
                    pcb.releasePooledConnection(this);
                }
            }
        }
    }

    // NOTE: Should NOT be synchronized otherwise won't be able to close
    private void forceClose(boolean cleanPool) {
        referenceCount = 0; // force closing of connection

        if (debug > 1) {
            System.err.println("LdapClient: forceClose() of " + this);
        }

        if (conn != null) {
            if (debug > 0) System.err.println(
                "LdapClient: forced close of connection " + this);
            conn.cleanup(null, false);
            conn = null;

            if (cleanPool) {
                pcb.removePooledConnection(this);
            }
        }
    }

    protected void finalize() {
        if (debug > 0) System.err.println("LdapClient: finalize " + this);
        forceClose(pooled);
    }

    /*
     * Used by connection pooling to close physical connection.
     */
    synchronized public void closeConnection() {
        forceClose(false); // this is a pool callback so no need to clean pool
    }

    /**
     * Called by Connection.cleanup(). LdapClient should
     * notify any unsolicited listeners and removing itself from any pool.
     * This is almost like forceClose(), except it doesn't call
     * Connection.cleanup() (because this is called from cleanup()).
     */
    void processConnectionClosure() {
        // Notify listeners
        if (unsolicited.size() > 0) {
            String msg;
            if (conn != null) {
                msg = conn.host + ":" + conn.port + " connection closed";
            } else {
                msg = "Connection closed";
            }
            notifyUnsolicited(new CommunicationException(msg));
        }

        // Remove from pool
        if (pooled) {
            pcb.removePooledConnection(this);
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP search. also includes methods to encode rfc 1558 compliant filters
    //
    ////////////////////////////////////////////////////////////////////////////

    static final int SCOPE_BASE_OBJECT = 0;
    static final int SCOPE_ONE_LEVEL = 1;
    static final int SCOPE_SUBTREE = 2;

    LdapResult search(String dn, int scope, int deref, int sizeLimit,
                      int timeLimit, boolean attrsOnly, String attrs[],
                      String filter, int batchSize, Control[] reqCtls,
                      Hashtable binaryAttrs, boolean waitFirstReply)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_SEARCH);
                    ber.encodeString(dn == null ? "" : dn, isLdapv3);
                    ber.encodeInt(scope, LBER_ENUMERATED);
                    ber.encodeInt(deref, LBER_ENUMERATED);
                    ber.encodeInt(sizeLimit);
                    ber.encodeInt(timeLimit);
                    ber.encodeBoolean(attrsOnly);
                    Filter.encodeFilterString(ber, filter, isLdapv3);
                    ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                        ber.encodeStringArray(attrs, isLdapv3);
                    ber.endSeq();
                ber.endSeq();
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();

         LdapRequest req = conn.writeRequest(ber, curMsgId);

         res.msgId = curMsgId;
         res.status = LdapClient.LDAP_SUCCESS; //optimistic
         if (waitFirstReply) {
             // get first reply
             res = getSearchReply(req, batchSize, res, binaryAttrs);
         }
         return res;
    }

    /*
     * Abandon the search operation and remove it from the message queue.
     */
    void clearSearchReply(LdapResult res, Control[] ctls) {
        if (res != null && conn != null) {

            // Only send an LDAP abandon operation when clearing the search
            // reply from a one-level or subtree search.
            LdapRequest req = conn.findRequest(res.msgId);
            if (req == null) {
                return;
            }

            // OK if req got removed after check; double removal attempt
            // but otherwise no harm done

            // Send an LDAP abandon only if the search operation has not yet
            // completed.
            if (req.hasSearchCompleted()) {
                conn.removeRequest(req);
            } else {
                conn.abandonRequest(req, ctls);
            }
        }
    }

    /*
     * Retrieve the next batch of entries and/or referrals.
     */
    LdapResult getSearchReply(int batchSize, LdapResult res,
        Hashtable binaryAttrs) throws IOException, NamingException {

        ensureOpen();

        LdapRequest req;

        if ((req = conn.findRequest(res.msgId)) == null) {
            return null;
        }

        return getSearchReply(req, batchSize, res, binaryAttrs);
    }

    private LdapResult getSearchReply(LdapRequest req,
        int batchSize, LdapResult res, Hashtable binaryAttrs)
        throws IOException, NamingException {

        if (batchSize == 0)
            batchSize = Integer.MAX_VALUE;

        if (res.entries != null) {
            res.entries.setSize(0); // clear the (previous) set of entries
        } else {
            res.entries =
                new Vector(batchSize == Integer.MAX_VALUE ? 32 : batchSize);
        }

        if (res.referrals != null) {
            res.referrals.setSize(0); // clear the (previous) set of referrals
        }

        BerDecoder replyBer;    // Decoder for response
        int seq;                // Request id

        Attributes lattrs;      // Attribute set read from response
        Attribute la;           // Attribute read from response
        String DN;              // DN read from response
        LdapEntry le;           // LDAP entry representing response
        int[] seqlen;           // Holder for response length
        int endseq;             // Position of end of response

        for (int i = 0; i < batchSize;) {
            replyBer = conn.readReply(req);

            //
            // process search reply
            //
            replyBer.parseSeq(null);                    // init seq
            replyBer.parseInt();                        // req id
            seq = replyBer.parseSeq(null);

            if (seq == LDAP_REP_SEARCH) {

                // handle LDAPv3 search entries
                lattrs = new BasicAttributes(caseIgnore);
                DN = replyBer.parseString(isLdapv3);
                le = new LdapEntry(DN, lattrs);
                seqlen = new int[1];

                replyBer.parseSeq(seqlen);
                endseq = replyBer.getParsePosition() + seqlen[0];
                while ((replyBer.getParsePosition() < endseq) &&
                    (replyBer.bytesLeft() > 0)) {
                    la = parseAttribute(replyBer, binaryAttrs);
                    lattrs.put(la);
                }
                le.respCtls = isLdapv3 ? parseControls(replyBer) : null;

                res.entries.addElement(le);
                i++;

            } else if ((seq == LDAP_REP_SEARCH_REF) && isLdapv3) {

                // handle LDAPv3 search reference
                Vector URLs = new Vector(4);

                // %%% Although not strictly correct, some LDAP servers
                //     encode the SEQUENCE OF tag in the SearchResultRef
                if (replyBer.peekByte() ==
                    (Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR)) {
                    replyBer.parseSeq(null);
                }

                while ((replyBer.bytesLeft() > 0) &&
                    (replyBer.peekByte() == Ber.ASN_OCTET_STR)) {

                    URLs.addElement(replyBer.parseString(isLdapv3));
                }

                if (res.referrals == null) {
                    res.referrals = new Vector(4);
                }
                res.referrals.addElement(URLs);
                res.resControls = isLdapv3 ? parseControls(replyBer) : null;

                // Save referral and continue to get next search result

            } else if (seq == LDAP_REP_EXTENSION) {

                parseExtResponse(replyBer, res); //%%% ignore for now

            } else if (seq == LDAP_REP_RESULT) {

                parseResult(replyBer, res, isLdapv3);
                res.resControls = isLdapv3 ? parseControls(replyBer) : null;

                conn.removeRequest(req);
                return res;     // Done with search
            }
        }

        return res;
    }

    private Attribute parseAttribute(BerDecoder ber, Hashtable binaryAttrs)
        throws IOException {

        int len[] = new int[1];
        int seq = ber.parseSeq(null);
        String attrid = ber.parseString(isLdapv3);
        boolean hasBinaryValues = isBinaryValued(attrid, binaryAttrs);
        Attribute la = new LdapAttribute(attrid);

        if ((seq = ber.parseSeq(len)) == LBER_SET) {
            int attrlen = len[0];
            while (ber.bytesLeft() > 0 && attrlen > 0) {
                try {
                    attrlen -= parseAttributeValue(ber, la, hasBinaryValues);
                } catch (IOException ex) {
                    ber.seek(attrlen);
                    break;
                }
            }
        } else {
            // Skip the rest of the sequence because it is not what we want
            ber.seek(len[0]);
        }
        return la;
    }

    //
    // returns number of bytes that were parsed. Adds the values to attr
    //
    private int parseAttributeValue(BerDecoder ber, Attribute la,
        boolean hasBinaryValues) throws IOException {

        int len[] = new int[1];

        if (hasBinaryValues) {
            la.add(ber.parseOctetString(ber.peekByte(), len));
        } else {
            la.add(ber.parseStringWithTag(Ber.ASN_SIMPLE_STRING, isLdapv3, len));
        }
        return len[0];
    }

    private boolean isBinaryValued(String attrid, Hashtable binaryAttrs) {
        String id = attrid.toLowerCase();

        return ((id.indexOf(";binary") != -1) ||
            defaultBinaryAttrs.containsKey(id) ||
            ((binaryAttrs != null) && (binaryAttrs.containsKey(id))));
    }

    // package entry point; used by Connection
    static void parseResult(BerDecoder replyBer, LdapResult res, boolean isLdapv3)
        throws IOException {

        res.status = replyBer.parseEnumeration();
        res.matchedDN = replyBer.parseString(isLdapv3);
        res.errorMessage = replyBer.parseString(isLdapv3);

        // handle LDAPv3 referrals (if present)
        if (isLdapv3 &&
            (replyBer.bytesLeft() > 0) &&
            (replyBer.peekByte() == LDAP_REP_REFERRAL)) {

            Vector URLs = new Vector(4);
            int[] seqlen = new int[1];

            replyBer.parseSeq(seqlen);
            int endseq = replyBer.getParsePosition() + seqlen[0];
            while ((replyBer.getParsePosition() < endseq) &&
                (replyBer.bytesLeft() > 0)) {

                URLs.addElement(replyBer.parseString(isLdapv3));
            }

            if (res.referrals == null) {
                res.referrals = new Vector(4);
            }
            res.referrals.addElement(URLs);
        }
    }

    // package entry point; used by Connection
    static Vector parseControls(BerDecoder replyBer) throws IOException {

        // handle LDAPv3 controls (if present)
        if ((replyBer.bytesLeft() > 0) && (replyBer.peekByte() == LDAP_CONTROLS)) {
            Vector ctls = new Vector(4);
            String controlOID;
            boolean criticality = false; // default
            byte[] controlValue = null;  // optional
            int[] seqlen = new int[1];

            replyBer.parseSeq(seqlen);
            int endseq = replyBer.getParsePosition() + seqlen[0];
            while ((replyBer.getParsePosition() < endseq) &&
                (replyBer.bytesLeft() > 0)) {

                replyBer.parseSeq(null);
                controlOID = replyBer.parseString(true);

                if ((replyBer.bytesLeft() > 0) &&
                    (replyBer.peekByte() == Ber.ASN_BOOLEAN)) {
                    criticality = replyBer.parseBoolean();
                }
                if ((replyBer.bytesLeft() > 0) &&
                    (replyBer.peekByte() == Ber.ASN_OCTET_STR)) {
                    controlValue =
                        replyBer.parseOctetString(Ber.ASN_OCTET_STR, null);
                }
                if (controlOID != null) {
                    ctls.addElement(
                        new BasicControl(controlOID, criticality, controlValue));
                }
            }
            return ctls;
        } else {
            return null;
        }
    }

    private void parseExtResponse(BerDecoder replyBer, LdapResult res)
        throws IOException {

        parseResult(replyBer, res, isLdapv3);

        if ((replyBer.bytesLeft() > 0) &&
            (replyBer.peekByte() == LDAP_REP_EXT_OID)) {
            res.extensionId =
                replyBer.parseStringWithTag(LDAP_REP_EXT_OID, isLdapv3, null);
        }
        if ((replyBer.bytesLeft() > 0) &&
            (replyBer.peekByte() == LDAP_REP_EXT_VAL)) {
            res.extensionValue =
                replyBer.parseOctetString(LDAP_REP_EXT_VAL, null);
        }

        res.resControls = parseControls(replyBer);
    }

    //
    // Encode LDAPv3 controls
    //
    static void encodeControls(BerEncoder ber, Control[] reqCtls)
        throws IOException {

        if ((reqCtls == null) || (reqCtls.length == 0)) {
            return;
        }

        byte[] controlVal;

        ber.beginSeq(LdapClient.LDAP_CONTROLS);

            for (int i = 0; i < reqCtls.length; i++) {
                ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                    ber.encodeString(reqCtls[i].getID(), true); // control OID
                    if (reqCtls[i].isCritical()) {
                        ber.encodeBoolean(true); // critical control
                    }
                    if ((controlVal = reqCtls[i].getEncodedValue()) != null) {
                        ber.encodeOctetString(controlVal, Ber.ASN_OCTET_STR);
                    }
                ber.endSeq();
            }
        ber.endSeq();
    }

    /**
     * Reads the next reply corresponding to msgId, outstanding on requestBer.
     * Processes the result and any controls.
     */
    private LdapResult processReply(LdapRequest req,
        LdapResult res, int responseType) throws IOException, NamingException {

        BerDecoder rber = conn.readReply(req);

        rber.parseSeq(null);    // init seq
        rber.parseInt();        // msg id
        if (rber.parseByte() !=  responseType) {
            return res;
        }

        rber.parseLength();
        parseResult(rber, res, isLdapv3);
        res.resControls = isLdapv3 ? parseControls(rber) : null;

        conn.removeRequest(req);

        return res;     // Done with operation
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP modify:
    //  Modify the DN dn with the operations on attributes attrs.
    //  ie, operations[0] is the operation to be performed on
    //  attrs[0];
    //          dn - DN to modify
    //          operations - add, delete or replace
    //          attrs - array of Attribute
    //          reqCtls - array of request controls
    //
    ////////////////////////////////////////////////////////////////////////////

    static final int ADD = 0;
    static final int DELETE = 1;
    static final int REPLACE = 2;

    LdapResult modify(String dn, int operations[], Attribute attrs[],
                      Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (dn == null || operations.length != attrs.length)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

        ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
            ber.encodeInt(curMsgId);
            ber.beginSeq(LDAP_REQ_MODIFY);
                ber.encodeString(dn, isLdapv3);
                ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                    for (int i = 0; i < operations.length; i++) {
                        ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                            ber.encodeInt(operations[i], LBER_ENUMERATED);

                            // zero values is not permitted for the add op.
                            if ((operations[i] == ADD) && hasNoValue(attrs[i])) {
                                throw new InvalidAttributeValueException(
                                    "'" + attrs[i].getID() + "' has no values.");
                            } else {
                                encodeAttribute(ber, attrs[i]);
                            }
                        ber.endSeq();
                    }
                ber.endSeq();
            ber.endSeq();
            if (isLdapv3) encodeControls(ber, reqCtls);
        ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId);

        return processReply(req, res, LDAP_REP_MODIFY);
    }

    private void encodeAttribute(BerEncoder ber, Attribute attr)
        throws IOException, NamingException {

        ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
            ber.encodeString(attr.getID(), isLdapv3);
            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR | 1);
                NamingEnumeration enum_ = attr.getAll();
                Object val;
                while (enum_.hasMore()) {
                    val = enum_.next();
                    if (val instanceof String) {
                        ber.encodeString((String)val, isLdapv3);
                    } else if (val instanceof byte[]) {
                        ber.encodeOctetString((byte[])val, Ber.ASN_OCTET_STR);
                    } else if (val == null) {
                        // no attribute value
                    } else {
                        throw new InvalidAttributeValueException(
                            "Malformed '" + attr.getID() + "' attribute value");
                    }
                }
            ber.endSeq();
        ber.endSeq();
    }

    private static boolean hasNoValue(Attribute attr) throws NamingException {
        return attr.size() == 0 || (attr.size() == 1 && attr.get() == null);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP add
    //          Adds entry to the Directory
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult add(LdapEntry entry, Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (entry == null || entry.DN == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();
        Attribute attr;

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_ADD);
                    ber.encodeString(entry.DN, isLdapv3);
                    ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                        NamingEnumeration enum_ = entry.attributes.getAll();
                        while (enum_.hasMore()) {
                            attr = (Attribute)enum_.next();

                            // zero values is not permitted
                            if (hasNoValue(attr)) {
                                throw new InvalidAttributeValueException(
                                    "'" + attr.getID() + "' has no values.");
                            } else {
                                encodeAttribute(ber, attr);
                            }
                        }
                    ber.endSeq();
                ber.endSeq();
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId);
        return processReply(req, res, LDAP_REP_ADD);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP delete
    //          deletes entry from the Directory
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult delete(String DN, Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (DN == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.encodeString(DN, LDAP_REQ_DELETE, isLdapv3);
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId);

        return processReply(req, res, LDAP_REP_DELETE);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP modrdn
    //  Changes the last element of DN to newrdn
    //          dn - DN to change
    //          newrdn - new RDN to rename to
    //          deleteoldrdn - boolean whether to delete old attrs or not
    //          newSuperior - new place to put the entry in the tree
    //                        (ignored if server is LDAPv2)
    //          reqCtls - array of request controls
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult moddn(String DN, String newrdn, boolean deleteOldRdn,
                     String newSuperior, Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        boolean changeSuperior = (newSuperior != null &&
                                  newSuperior.length() > 0);

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (DN == null || newrdn == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_MODRDN);
                    ber.encodeString(DN, isLdapv3);
                    ber.encodeString(newrdn, isLdapv3);
                    ber.encodeBoolean(deleteOldRdn);
                    if(isLdapv3 && changeSuperior) {
                        //System.err.println("changin superior");
                        ber.encodeString(newSuperior, LDAP_SUPERIOR_DN, isLdapv3);
                    }
                ber.endSeq();
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();


        LdapRequest req = conn.writeRequest(ber, curMsgId);

        return processReply(req, res, LDAP_REP_MODRDN);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP compare
    //  Compare attribute->value pairs in dn
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult compare(String DN, String type, String value, Control[] reqCtls)
        throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (DN == null || type == null || value == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_COMPARE);
                    ber.encodeString(DN, isLdapv3);
                    ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                        ber.encodeString(type, isLdapv3);

                        // replace any escaped characters in the value
                        byte[] val = isLdapv3 ?
                            value.getBytes("UTF8") : value.getBytes("8859_1");
                        ber.encodeOctetString(
                            Filter.unescapeFilterValue(val, 0, val.length),
                            Ber.ASN_OCTET_STR);

                    ber.endSeq();
                ber.endSeq();
                if (isLdapv3) encodeControls(ber, reqCtls);
            ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId);

        return processReply(req, res, LDAP_REP_COMPARE);
    }

    ////////////////////////////////////////////////////////////////////////////
    //
    // LDAP extended operation
    //
    ////////////////////////////////////////////////////////////////////////////

    LdapResult extendedOp(String id, byte[] request, Control[] reqCtls,
        boolean pauseAfterReceipt) throws IOException, NamingException {

        ensureOpen();

        LdapResult res = new LdapResult();
        res.status = LDAP_OPERATIONS_ERROR;

        if (id == null)
            return res;

        BerEncoder ber = new BerEncoder();
        int curMsgId = conn.getMsgId();

            ber.beginSeq(Ber.ASN_SEQUENCE | Ber.ASN_CONSTRUCTOR);
                ber.encodeInt(curMsgId);
                ber.beginSeq(LDAP_REQ_EXTENSION);
                    ber.encodeString(id,
                        Ber.ASN_CONTEXT | 0, isLdapv3);//[0]
                    if (request != null) {
                        ber.encodeOctetString(request,
                            Ber.ASN_CONTEXT | 1);//[1]
                    }
                ber.endSeq();
                encodeControls(ber, reqCtls); // always v3
            ber.endSeq();

        LdapRequest req = conn.writeRequest(ber, curMsgId, pauseAfterReceipt);

        BerDecoder rber = conn.readReply(req);

        rber.parseSeq(null);    // init seq
        rber.parseInt();        // msg id
        if (rber.parseByte() !=  LDAP_REP_EXTENSION) {
            return res;
        }

        rber.parseLength();
        parseExtResponse(rber, res);
        conn.removeRequest(req);

        return res;     // Done with operation
    }



    ////////////////////////////////////////////////////////////////////////////
    //
    // Some BER definitions convenient for LDAP
    //
    ////////////////////////////////////////////////////////////////////////////

    static final int LDAP_VERSION3_VERSION2 = 32;
    static final int LDAP_VERSION2 = 0x02;
    static final int LDAP_VERSION3 = 0x03;              // LDAPv3
    static final int LDAP_VERSION = LDAP_VERSION3;

    static final int LDAP_REF_FOLLOW = 0x01;            // follow referrals
    static final int LDAP_REF_THROW = 0x02;             // throw referral ex.
    static final int LDAP_REF_IGNORE = 0x03;            // ignore referrals

    static final String LDAP_URL = "ldap://";           // LDAPv3
    static final String LDAPS_URL = "ldaps://";         // LDAPv3

    static final int LBER_BOOLEAN = 0x01;
    static final int LBER_INTEGER = 0x02;
    static final int LBER_BITSTRING = 0x03;
    static final int LBER_OCTETSTRING = 0x04;
    static final int LBER_NULL = 0x05;
    static final int LBER_ENUMERATED = 0x0a;
    static final int LBER_SEQUENCE = 0x30;
    static final int LBER_SET = 0x31;

    static final int LDAP_SUPERIOR_DN = 0x80;

    static final int LDAP_REQ_BIND = 0x60;      // app + constructed
    static final int LDAP_REQ_UNBIND = 0x42;    // app + primitive
    static final int LDAP_REQ_SEARCH = 0x63;    // app + constructed
    static final int LDAP_REQ_MODIFY = 0x66;    // app + constructed
    static final int LDAP_REQ_ADD = 0x68;       // app + constructed
    static final int LDAP_REQ_DELETE = 0x4a;    // app + primitive
    static final int LDAP_REQ_MODRDN = 0x6c;    // app + constructed
    static final int LDAP_REQ_COMPARE = 0x6e;   // app + constructed
    static final int LDAP_REQ_ABANDON = 0x50;   // app + primitive
    static final int LDAP_REQ_EXTENSION = 0x77; // app + constructed    (LDAPv3)

    static final int LDAP_REP_BIND = 0x61;      // app + constructed | 1
    static final int LDAP_REP_SEARCH = 0x64;    // app + constructed | 4
    static final int LDAP_REP_SEARCH_REF = 0x73;// app + constructed    (LDAPv3)
    static final int LDAP_REP_RESULT = 0x65;    // app + constructed | 5
    static final int LDAP_REP_MODIFY = 0x67;    // app + constructed | 7
    static final int LDAP_REP_ADD = 0x69;       // app + constructed | 9
    static final int LDAP_REP_DELETE = 0x6b;    // app + primitive | b
    static final int LDAP_REP_MODRDN = 0x6d;    // app + primitive | d
    static final int LDAP_REP_COMPARE = 0x6f;   // app + primitive | f
    static final int LDAP_REP_EXTENSION = 0x78; // app + constructed    (LDAPv3)

    static final int LDAP_REP_REFERRAL = 0xa3;  // ctx + constructed    (LDAPv3)
    static final int LDAP_REP_EXT_OID = 0x8a;   // ctx + primitive      (LDAPv3)
    static final int LDAP_REP_EXT_VAL = 0x8b;   // ctx + primitive      (LDAPv3)

    // LDAPv3 Controls

    static final int LDAP_CONTROLS = 0xa0;      // ctx + constructed    (LDAPv3)
    static final String LDAP_CONTROL_MANAGE_DSA_IT = "2.16.840.1.113730.3.4.2";
    static final String LDAP_CONTROL_PREFERRED_LANG = "1.3.6.1.4.1.1466.20035";
    static final String LDAP_CONTROL_PAGED_RESULTS = "1.2.840.113556.1.4.319";
    static final String LDAP_CONTROL_SERVER_SORT_REQ = "1.2.840.113556.1.4.473";
    static final String LDAP_CONTROL_SERVER_SORT_RES = "1.2.840.113556.1.4.474";

    ////////////////////////////////////////////////////////////////////////////
    //
    // return codes
    //
    ////////////////////////////////////////////////////////////////////////////

    static final int LDAP_SUCCESS = 0;
    static final int LDAP_OPERATIONS_ERROR = 1;
    static final int LDAP_PROTOCOL_ERROR = 2;
    static final int LDAP_TIME_LIMIT_EXCEEDED = 3;
    static final int LDAP_SIZE_LIMIT_EXCEEDED = 4;
    static final int LDAP_COMPARE_FALSE = 5;
    static final int LDAP_COMPARE_TRUE = 6;
    static final int LDAP_AUTH_METHOD_NOT_SUPPORTED = 7;
    static final int LDAP_STRONG_AUTH_REQUIRED = 8;
    static final int LDAP_PARTIAL_RESULTS = 9;                  // Slapd
    static final int LDAP_REFERRAL = 10;                        // LDAPv3
    static final int LDAP_ADMIN_LIMIT_EXCEEDED = 11;            // LDAPv3
    static final int LDAP_UNAVAILABLE_CRITICAL_EXTENSION = 12;  // LDAPv3
    static final int LDAP_CONFIDENTIALITY_REQUIRED = 13;        // LDAPv3
    static final int LDAP_SASL_BIND_IN_PROGRESS = 14;           // LDAPv3
    static final int LDAP_NO_SUCH_ATTRIBUTE = 16;
    static final int LDAP_UNDEFINED_ATTRIBUTE_TYPE = 17;
    static final int LDAP_INAPPROPRIATE_MATCHING = 18;
    static final int LDAP_CONSTRAINT_VIOLATION = 19;
    static final int LDAP_ATTRIBUTE_OR_VALUE_EXISTS = 20;
    static final int LDAP_INVALID_ATTRIBUTE_SYNTAX = 21;
    static final int LDAP_NO_SUCH_OBJECT = 32;
    static final int LDAP_ALIAS_PROBLEM = 33;
    static final int LDAP_INVALID_DN_SYNTAX = 34;
    static final int LDAP_IS_LEAF = 35;
    static final int LDAP_ALIAS_DEREFERENCING_PROBLEM = 36;
    static final int LDAP_INAPPROPRIATE_AUTHENTICATION = 48;
    static final int LDAP_INVALID_CREDENTIALS = 49;
    static final int LDAP_INSUFFICIENT_ACCESS_RIGHTS = 50;
    static final int LDAP_BUSY = 51;
    static final int LDAP_UNAVAILABLE = 52;
    static final int LDAP_UNWILLING_TO_PERFORM = 53;
    static final int LDAP_LOOP_DETECT = 54;
    static final int LDAP_NAMING_VIOLATION = 64;
    static final int LDAP_OBJECT_CLASS_VIOLATION = 65;
    static final int LDAP_NOT_ALLOWED_ON_NON_LEAF = 66;
    static final int LDAP_NOT_ALLOWED_ON_RDN = 67;
    static final int LDAP_ENTRY_ALREADY_EXISTS = 68;
    static final int LDAP_OBJECT_CLASS_MODS_PROHIBITED = 69;
    static final int LDAP_AFFECTS_MULTIPLE_DSAS = 71;           // LDAPv3
    static final int LDAP_OTHER = 80;

    static final String[] ldap_error_message = {
        "Success",                                      // 0
        "Operations Error",                             // 1
        "Protocol Error",                               // 2
        "Timelimit Exceeded",                           // 3
        "Sizelimit Exceeded",                           // 4
        "Compare False",                                // 5
        "Compare True",                                 // 6
        "Authentication Method Not Supported",          // 7
        "Strong Authentication Required",               // 8
        null,
        "Referral",                                     // 10
        "Administrative Limit Exceeded",                // 11
        "Unavailable Critical Extension",               // 12
        "Confidentiality Required",                     // 13
        "SASL Bind In Progress",                        // 14
        null,
        "No Such Attribute",                            // 16
        "Undefined Attribute Type",                     // 17
        "Inappropriate Matching",                       // 18
        "Constraint Violation",                         // 19
        "Attribute Or Value Exists",                    // 20
        "Invalid Attribute Syntax",                     // 21
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        "No Such Object",                               // 32
        "Alias Problem",                                // 33
        "Invalid DN Syntax",                            // 34
        null,
        "Alias Dereferencing Problem",                  // 36
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        "Inappropriate Authentication",                 // 48
        "Invalid Credentials",                          // 49
        "Insufficient Access Rights",                   // 50
        "Busy",                                         // 51
        "Unavailable",                                  // 52
        "Unwilling To Perform",                         // 53
        "Loop Detect",                                  // 54
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        "Naming Violation",                             // 64
        "Object Class Violation",                       // 65
        "Not Allowed On Non-leaf",                      // 66
        "Not Allowed On RDN",                           // 67
        "Entry Already Exists",                         // 68
        "Object Class Modifications Prohibited",        // 69
        null,
        "Affects Multiple DSAs",                        // 71
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        "Other",                                        // 80
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null,
        null
    };


    /*
     * Generate an error message from the LDAP error code and error diagnostic.
     * The message format is:
     *
     *     "[LDAP: error code <errorCode> - <errorMessage>]"
     *
     * where <errorCode> is a numeric error code
     * and <errorMessage> is a textual description of the error (if available)
     *
     */
    static String getErrorMessage(int errorCode, String errorMessage) {

        String message = "[LDAP: error code " + errorCode;

        if ((errorMessage != null) && (errorMessage.length() != 0)) {

            // append error message from the server
            message = message + " - " + errorMessage + "]";

        } else {

            // append built-in error message
            try {
                if (ldap_error_message[errorCode] != null) {
                    message = message + " - " + ldap_error_message[errorCode] +
                                "]";
                }
            } catch (ArrayIndexOutOfBoundsException ex) {
                message = message + "]";
            }
        }
        return message;
    }


    ////////////////////////////////////////////////////////////////////////////
    //
    // Unsolicited notification support.
    //
    // An LdapClient maintains a list of LdapCtx that have registered
    // for UnsolicitedNotifications. This is a list because a single
    // LdapClient might be shared among multiple contexts.
    //
    // When addUnsolicited() is invoked, the LdapCtx is added to the list.
    //
    // When Connection receives an unsolicited notification (msgid == 0),
    // it invokes LdapClient.processUnsolicited(). processUnsolicited()
    // parses the Extended Response. If there are registered listeners,
    // LdapClient creates an UnsolicitedNotification from the response
    // and informs each LdapCtx to fire an event for the notification.
    // If it is a DISCONNECT notification, the connection is closed and a
    // NamingExceptionEvent is fired to the listeners.
    //
    // When the connection is closed out-of-band like this, the next
    // time a method is invoked on LdapClient, an IOException is thrown.
    //
    // removeUnsolicited() is invoked to remove an LdapCtx from this client.
    //
    ////////////////////////////////////////////////////////////////////////////
    private Vector unsolicited = new Vector(3);
    void addUnsolicited(LdapCtx ctx) {
        if (debug > 0) {
            System.err.println("LdapClient.addUnsolicited" + ctx);
        }
        unsolicited.addElement(ctx);
    }

    void removeUnsolicited(LdapCtx ctx) {
        if (debug > 0) {
            System.err.println("LdapClient.removeUnsolicited" + ctx);
        }
        synchronized (unsolicited) {
            if (unsolicited.size() == 0) {
                return;
            }
            unsolicited.removeElement(ctx);
        }
    }

    // NOTE: Cannot be synchronized because this is called asynchronously
    // by the reader thread in Connection. Instead, sync on 'unsolicited' Vector.
    void processUnsolicited(BerDecoder ber) {
        if (debug > 0) {
            System.err.println("LdapClient.processUnsolicited");
        }
      synchronized (unsolicited) {
        try {
            // Parse the response
            LdapResult res = new LdapResult();

            ber.parseSeq(null); // init seq
            ber.parseInt();             // msg id; should be 0; ignored
            if (ber.parseByte() != LDAP_REP_EXTENSION) {
                throw new IOException(
                    "Unsolicited Notification must be an Extended Response");
            }
            ber.parseLength();
            parseExtResponse(ber, res);

            if (DISCONNECT_OID.equals(res.extensionId)) {
                // force closing of connection
                forceClose(pooled);
            }

            if (unsolicited.size() > 0) {
                // Create an UnsolicitedNotification using the parsed data
                // Need a 'ctx' object because we want to use the context's
                // list of provider control factories.
                UnsolicitedNotification notice = new UnsolicitedResponseImpl(
                    res.extensionId,
                    res.extensionValue,
                    res.referrals,
                    res.status,
                    res.errorMessage,
                    res.matchedDN,
                    (res.resControls != null) ?
            ((LdapCtx)unsolicited.elementAt(0)).convertControls(res.resControls) :
                    null);

                // Fire UnsolicitedNotification events to listeners
                notifyUnsolicited(notice);

                // If "disconnect" notification,
                // notify unsolicited listeners via NamingException
                if (DISCONNECT_OID.equals(res.extensionId)) {
                    notifyUnsolicited(
                        new CommunicationException("Connection closed"));
                }
            }
        } catch (IOException e) {
            if (unsolicited.size() == 0)
                return;  // no one registered; ignore

            NamingException ne = new CommunicationException(
                "Problem parsing unsolicited notification");
            ne.setRootCause(e);

            notifyUnsolicited(ne);

        } catch (NamingException e) {
            notifyUnsolicited(e);
        }
      }
    }


    private void notifyUnsolicited(Object e) {
        for (int i = 0; i < unsolicited.size(); i++) {
            ((LdapCtx)unsolicited.elementAt(i)).fireUnsolicited(e);
        }
        if (e instanceof NamingException) {
            unsolicited.setSize(0);  // no more listeners after exception
        }
    }

    private void ensureOpen() throws IOException {
        if (conn == null || !conn.useable) {
            if (conn != null && conn.closureReason != null) {
                throw conn.closureReason;
            } else {
                throw new IOException("connection closed");
            }
        }
    }

    // package private (used by LdapCtx)
    static LdapClient getInstance(boolean usePool, String hostname, int port,
        String factory, int connectTimeout, int readTimeout, OutputStream trace,
        int version, String authMechanism, Control[] ctls, String protocol,
        String user, Object passwd, Hashtable env) throws NamingException {

        if (usePool) {
            if (LdapPoolManager.isPoolingAllowed(factory, trace,
                    authMechanism, protocol, env)) {
                LdapClient answer = LdapPoolManager.getLdapClient(
                        hostname, port, factory, connectTimeout, readTimeout,
                        trace, version, authMechanism, ctls, protocol, user,
                        passwd, env);
                answer.referenceCount = 1;   // always one when starting out
                return answer;
            }
        }
        return new LdapClient(hostname, port, factory, connectTimeout,
                                        readTimeout, trace, null);
    }
}
