/*
 * Copyright (c) 1999, 2017, 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.io.*;
import java.util.Locale;
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<String, Boolean> 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 {

        int readTimeout = conn.readTimeout;
        conn.readTimeout = conn.connectTimeout;
        LdapResult res = null;

        try {
            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");
            }

            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;
        } finally {
            conn.readTimeout = readTimeout;
        }
    }

    /**
     * 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);
            }
        }
    }

    @SuppressWarnings("deprecation")
    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<String, Boolean> binaryAttrs,
                      boolean waitFirstReply, int replyQueueCapacity)
        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, false, replyQueueCapacity);

         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<String, Boolean> 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<String, Boolean> 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<String> 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<String, Boolean> 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<String, Boolean> binaryAttrs) {
        String id = attrid.toLowerCase(Locale.ENGLISH);

        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<String> 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<Control> parseControls(BerDecoder replyBer) throws IOException {

        // handle LDAPv3 controls (if present)
        if ((replyBer.bytesLeft() > 0) && (replyBer.peekByte() == LDAP_CONTROLS)) {
            Vector<Control> 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<? extends Attribute> enum_ =
                                entry.attributes.getAll();
                        while (enum_.hasMore()) {
                            attr = 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 int LDAP_REF_FOLLOW_SCHEME = 0x04;     // follow referrals of the same scheme

    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<LdapCtx> 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);
        }
            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");
        }
        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);
            }

            LdapCtx first = null;
            UnsolicitedNotification notice = null;

            synchronized (unsolicited) {
                if (unsolicited.size() > 0) {
                    first = unsolicited.elementAt(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.
                    notice = new UnsolicitedResponseImpl(
                        res.extensionId,
                        res.extensionValue,
                        res.referrals,
                        res.status,
                        res.errorMessage,
                        res.matchedDN,
                        (res.resControls != null) ?
                        first.convertControls(res.resControls) :
                        null);
                }
            }

            if (notice != 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) {
            NamingException ne = new CommunicationException(
                "Problem parsing unsolicited notification");
            ne.setRootCause(e);

            notifyUnsolicited(ne);

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


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

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