/*
 * Copyright (c) 1999, 2024, 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 javax.naming;

import java.util.Hashtable;

/**
 * This interface represents a naming context, which
 * consists of a set of name-to-object bindings.
 * It contains methods for examining and updating these bindings.
 *
 * <h2>Names</h2>
 * Each name passed as an argument to a {@code Context} method is relative
 * to that context.  The empty name is used to name the context itself.
 * A name parameter may never be null.
 * <p>
 * Most of the methods have overloaded versions with one taking a
 * <code>Name</code> parameter and one taking a <code>String</code>.
 * These overloaded versions are equivalent in that if
 * the <code>Name</code> and <code>String</code> parameters are just
 * different representations of the same name, then the overloaded
 * versions of the same methods behave the same.
 * In the method descriptions below, only one version is fully documented.
 * The second version instead has a link to the first:  the same
 * documentation applies to both.
 * <p>
 * For systems that support federation, {@code String} name arguments to
 * {@code Context} methods are composite names. Name arguments that are
 * instances of {@code CompositeName} are treated as composite names,
 * while {@code Name} arguments that are not instances of
 * {@code CompositeName} are treated as compound names (which might be
 * instances of {@code CompoundName} or other implementations of compound
 * names). This allows the results of {@code NameParser.parse()} to be used as
 * arguments to the {@code Context} methods.
 * Prior to JNDI 1.2, all name arguments were treated as composite names.
 *<p>
 * Furthermore, for systems that support federation, all names returned
 * in a {@code NamingEnumeration}
 * from {@code list()} and {@code listBindings()} are composite names
 * represented as strings.
 * See {@code CompositeName} for the string syntax of names.
 *<p>
 * For systems that do not support federation, the name arguments (in
 * either {@code Name} or {@code String} forms) and the names returned in
 * {@code NamingEnumeration} may be names in their own namespace rather than
 * names in a composite namespace, at the discretion of the service
 * provider.
 *
 *<h2>Exceptions</h2>
 * All the methods in this interface can throw a {@code NamingException} or
 * any of its subclasses. See {@code NamingException} and their subclasses
 * for details on each exception.
 *
 *<h2>Concurrent Access</h2>
 * A Context instance is not guaranteed to be synchronized against
 * concurrent access by multiple threads.  Threads that need to access
 * a single Context instance concurrently should synchronize amongst
 * themselves and provide the necessary locking.  Multiple threads
 * each manipulating a different Context instance need not
 * synchronize.  Note that the {@link #lookup(Name) lookup}
 * method, when passed an empty name, will return a new Context instance
 * representing the same naming context.
 *<p>
 * For purposes of concurrency control,
 * a Context operation that returns a {@code NamingEnumeration} is
 * not considered to have completed while the enumeration is still in
 * use, or while any referrals generated by that operation are still
 * being followed.
 *
 *
 *<h2>Parameters</h2>
 * A {@code Name} parameter passed to any method of the
 * {@code Context} interface or one of its subinterfaces
 * will not be modified by the service provider.
 * The service provider may keep a reference to it
 * for the duration of the operation, including any enumeration of the
 * method's results and the processing of any referrals generated.
 * The caller should not modify the object during this time.
 * A {@code Name} returned by any such method is owned by the caller.
 * The caller may subsequently modify it; the service provider may not.
 *
 *
 *<h2>Environment Properties</h2>
 *<p>
 * JNDI applications need a way to communicate various preferences
 * and properties that define the environment in which naming and
 * directory services are accessed. For example, a context might
 * require specification of security credentials in order to access
 * the service. Another context might require that server configuration
 * information be supplied. These are referred to as the <em>environment</em>
 * of a context. The {@code Context} interface provides methods for
 * retrieving and updating this environment.
 *<p>
 * The environment is inherited from the parent context as
 * context methods proceed from one context to the next. Changes to
 * the environment of one context do not directly affect those
 * of other contexts.
 *<p>
 * It is implementation-dependent when environment properties are used
 * and/or verified for validity.  For example, some of the
 * security-related properties are used by service providers to "log in"
 * to the directory.  This login process might occur at the time the
 * context is created, or the first time a method is invoked on the
 * context.  When, and whether this occurs at all, is
 * implementation-dependent.  When environment properties are added or
 * removed from the context, verifying the validity of the changes is again
 * implementation-dependent. For example, verification of some properties
 * might occur at the time the change is made, or at the time the next
 * operation is performed on the context, or not at all.
 *<p>
 * Any object with a reference to a context may examine that context's
 * environment.  Sensitive information such as clear-text
 * passwords should not be stored there unless the implementation is
 * known to protect it.
 *
 *<p>
 *<a id=RESOURCEFILES></a>
 *<h2>Resource Files</h2>
 *<p>
 * To simplify the task of setting up the environment
 * required by a JNDI application,
 * application components and service providers may be distributed
 * along with <em>resource files.</em>
 * A JNDI resource file is a file in the properties file format (see
 * {@link java.util.Properties#load java.util.Properties}),
 * containing a list of key/value pairs.
 * The key is the name of the property (e.g. "java.naming.factory.object")
 * and the value is a string in the format defined
 * for that property.  Here is an example of a JNDI resource file:
 *
 * <blockquote>{@code
 * java.naming.factory.object=com.sun.jndi.ldap.AttrsToCorba:com.wiz.from.Person
 * java.naming.factory.state=com.sun.jndi.ldap.CorbaToAttrs:com.wiz.from.Person
 * java.naming.factory.control=com.sun.jndi.ldap.ResponseControlFactory
 * }</blockquote>
 *
 * The JNDI class library reads the resource files and makes the property
 * values freely available.  Thus JNDI resource files should be considered
 * to be "world readable", and sensitive information such as clear-text
 * passwords should not be stored there.
 *<p>
 * There are two kinds of JNDI resource files:
 * <em>provider</em> and <em>application</em>.
 *
 * <h3>Provider Resource Files</h3>
 *
 * Each service provider has an optional resource that lists properties
 * specific to that provider.  The name of this resource is:
 * <blockquote>
 * [<em>prefix</em>/]{@code jndiprovider.properties}
 * </blockquote>
 * where <em>prefix</em> is
 * the package name of the provider's context implementation(s),
 * with each period (".") converted to a slash ("/").
 *
 * For example, suppose a service provider defines a context
 * implementation with class name {@code com.sun.jndi.ldap.LdapCtx}.
 * The provider resource for this provider is named
 * {@code com/sun/jndi/ldap/jndiprovider.properties}.  If the class is
 * not in a package, the resource's name is simply
 * {@code jndiprovider.properties}.
 *
 * <p>
 * <a id=LISTPROPS></a>
 * Certain methods in the JNDI class library make use of the standard
 * JNDI properties that specify lists of JNDI factories:
 * <ul>
 * <li>java.naming.factory.object
 * <li>java.naming.factory.state
 * <li>java.naming.factory.control
 * <li>java.naming.factory.url.pkgs
 * </ul>
 * The JNDI library will consult the provider resource file
 * when determining the values of these properties.
 * Properties other than these may be set in the provider
 * resource file at the discretion of the service provider.
 * The service provider's documentation should clearly state which
 * properties are allowed; other properties in the file will be ignored.
 *
 * <h3>Application Resource Files</h3>
 *
 * When an application is deployed, it will generally have several
 * codebase directories and JARs in its classpath. JNDI locates (using
 * {@link ClassLoader#getResources ClassLoader.getResources()})
 * all <em>application resource files</em> named {@code jndi.properties}
 * in the classpath.
 * In addition, if the Java installation directory contains a built-in
 * properties file, typically {@code conf/jndi.properties},
 * JNDI treats it as an additional application resource file.
 * All of the properties contained in these files are placed
 * into the environment of the initial context.  This environment
 * is then inherited by other contexts.
 *
 * <p>
 * For each property found in more than one application resource file,
 * JNDI uses the first value found or, in a few cases where it makes
 * sense to do so, it concatenates all of the values (details are given
 * below).
 * For example, if the "java.naming.factory.object" property is found in
 * three {@code jndi.properties} resource files, the
 * list of object factories is a concatenation of the property
 * values from all three files.
 * Using this scheme, each deployable component is responsible for
 * listing the factories that it exports.  JNDI automatically
 * collects and uses all of these export lists when searching for factory
 * classes.
 *
 * <h3>Search Algorithm for Properties</h3>
 *
 * When JNDI constructs an initial context, the context's environment
 * is initialized with properties defined in the environment parameter
 * passed to the constructor, the system properties,
 * and the application resource files.  See
 * <a href=InitialContext.html#ENVIRONMENT>{@code InitialContext}</a>
 * for details.
 * This initial environment is then inherited by other context instances.
 *
 * <p>
 * When the JNDI class library needs to determine
 * the value of a property, it does so by merging
 * the values from the following two sources, in order:
 * <ol>
 * <li>The environment of the context being operated on.
 * <li>The provider resource file ({@code jndiprovider.properties})
 * for the context being operated on.
 * </ol>
 * For each property found in both of these two sources,
 * JNDI determines the property's value as follows.  If the property is
 * one of the standard JNDI properties that specify a list of JNDI
 * factories (listed <a href=#LISTPROPS>above</a>), the values are
 * concatenated into a single colon-separated list.  For other
 * properties, only the first value found is used.
 *
 * <p>
 * When a service provider needs to determine the value of a property,
 * it will generally take that value directly from the environment.
 * A service provider may define provider-specific properties
 * to be placed in its own provider resource file.  In that
 * case it should merge values as described in the previous paragraph.
 *
 * <p>
 * In this way, each service provider developer can specify a list of
 * factories to use with that service provider. These can be modified by
 * the application resources specified by the deployer of the application,
 * which in turn can be modified by the user.
 *
 * @author Rosanna Lee
 * @author Scott Seligman
 * @author R. Vasudevan
 *
 * @since 1.3
 */

public interface Context {

    /**
     * Retrieves the named object.
     * If {@code name} is empty, returns a new instance of this context
     * (which represents the same naming context as this context, but its
     * environment may be modified independently and it may be accessed
     * concurrently).
     *
     * @param name
     *          the name of the object to look up
     * @return  the object bound to {@code name}
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #lookup(String)
     * @see #lookupLink(Name)
     */
    public Object lookup(Name name) throws NamingException;

    /**
     * Retrieves the named object.
     * See {@link #lookup(Name)} for details.
     * @param name
     *          the name of the object to look up
     * @return  the object bound to {@code name}
     * @throws  NamingException if a naming exception is encountered
     */
    public Object lookup(String name) throws NamingException;

    /**
     * Binds a name to an object.
     * All intermediate contexts and the target context (that named by all
     * but terminal atomic component of the name) must already exist.
     *
     * @param name
     *          the name to bind; may not be empty
     * @param obj
     *          the object to bind; possibly null
     * @throws  NameAlreadyBoundException if name is already bound
     * @throws  javax.naming.directory.InvalidAttributesException
     *          if object did not supply all mandatory attributes
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #bind(String, Object)
     * @see #rebind(Name, Object)
     * @see javax.naming.directory.DirContext#bind(Name, Object,
     *          javax.naming.directory.Attributes)
     */
    public void bind(Name name, Object obj) throws NamingException;

    /**
     * Binds a name to an object.
     * See {@link #bind(Name, Object)} for details.
     *
     * @param name
     *          the name to bind; may not be empty
     * @param obj
     *          the object to bind; possibly null
     * @throws  NameAlreadyBoundException if name is already bound
     * @throws  javax.naming.directory.InvalidAttributesException
     *          if object did not supply all mandatory attributes
     * @throws  NamingException if a naming exception is encountered
     */
    public void bind(String name, Object obj) throws NamingException;

    /**
     * Binds a name to an object, overwriting any existing binding.
     * All intermediate contexts and the target context (that named by all
     * but terminal atomic component of the name) must already exist.
     *
     * <p> If the object is a {@code DirContext}, any existing attributes
     * associated with the name are replaced with those of the object.
     * Otherwise, any existing attributes associated with the name remain
     * unchanged.
     *
     * @param name
     *          the name to bind; may not be empty
     * @param obj
     *          the object to bind; possibly null
     * @throws  javax.naming.directory.InvalidAttributesException
     *          if object did not supply all mandatory attributes
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #rebind(String, Object)
     * @see #bind(Name, Object)
     * @see javax.naming.directory.DirContext#rebind(Name, Object,
     *          javax.naming.directory.Attributes)
     * @see javax.naming.directory.DirContext
     */
    public void rebind(Name name, Object obj) throws NamingException;

    /**
     * Binds a name to an object, overwriting any existing binding.
     * See {@link #rebind(Name, Object)} for details.
     *
     * @param name
     *          the name to bind; may not be empty
     * @param obj
     *          the object to bind; possibly null
     * @throws  javax.naming.directory.InvalidAttributesException
     *          if object did not supply all mandatory attributes
     * @throws  NamingException if a naming exception is encountered
     */
    public void rebind(String name, Object obj) throws NamingException;

    /**
     * Unbinds the named object.
     * Removes the terminal atomic name in <code>name</code>
     * from the target context--that named by all but the terminal
     * atomic part of <code>name</code>.
     *
     * <p> This method is idempotent.
     * It succeeds even if the terminal atomic name
     * is not bound in the target context, but throws
     * {@code NameNotFoundException}
     * if any of the intermediate contexts do not exist.
     *
     * <p> Any attributes associated with the name are removed.
     * Intermediate contexts are not changed.
     *
     * @param name
     *          the name to unbind; may not be empty
     * @throws  NameNotFoundException if an intermediate context does not exist
     * @throws  NamingException if a naming exception is encountered
     * @see #unbind(String)
     */
    public void unbind(Name name) throws NamingException;

    /**
     * Unbinds the named object.
     * See {@link #unbind(Name)} for details.
     *
     * @param name
     *          the name to unbind; may not be empty
     * @throws  NameNotFoundException if an intermediate context does not exist
     * @throws  NamingException if a naming exception is encountered
     */
    public void unbind(String name) throws NamingException;

    /**
     * Binds a new name to the object bound to an old name, and unbinds
     * the old name.  Both names are relative to this context.
     * Any attributes associated with the old name become associated
     * with the new name.
     * Intermediate contexts of the old name are not changed.
     *
     * @param oldName
     *          the name of the existing binding; may not be empty
     * @param newName
     *          the name of the new binding; may not be empty
     * @throws  NameAlreadyBoundException if {@code newName} is already bound
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #rename(String, String)
     * @see #bind(Name, Object)
     * @see #rebind(Name, Object)
     */
    public void rename(Name oldName, Name newName) throws NamingException;

    /**
     * Binds a new name to the object bound to an old name, and unbinds
     * the old name.
     * See {@link #rename(Name, Name)} for details.
     *
     * @param oldName
     *          the name of the existing binding; may not be empty
     * @param newName
     *          the name of the new binding; may not be empty
     * @throws  NameAlreadyBoundException if {@code newName} is already bound
     * @throws  NamingException if a naming exception is encountered
     */
    public void rename(String oldName, String newName) throws NamingException;

    /**
     * Enumerates the names bound in the named context, along with the
     * class names of objects bound to them.
     * The contents of any subcontexts are not included.
     *
     * <p> If a binding is added to or removed from this context,
     * its effect on an enumeration previously returned is undefined.
     *
     * @param name
     *          the name of the context to list
     * @return  an enumeration of the names and class names of the
     *          bindings in this context.  Each element of the
     *          enumeration is of type {@code NameClassPair}.
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #list(String)
     * @see #listBindings(Name)
     * @see NameClassPair
     */
    public NamingEnumeration<NameClassPair> list(Name name)
        throws NamingException;

    /**
     * Enumerates the names bound in the named context, along with the
     * class names of objects bound to them.
     * See {@link #list(Name)} for details.
     *
     * @param name
     *          the name of the context to list
     * @return  an enumeration of the names and class names of the
     *          bindings in this context.  Each element of the
     *          enumeration is of type {@code NameClassPair}.
     * @throws  NamingException if a naming exception is encountered
     */
    public NamingEnumeration<NameClassPair> list(String name)
        throws NamingException;

    /**
     * Enumerates the names bound in the named context, along with the
     * objects bound to them.
     * The contents of any subcontexts are not included.
     *
     * <p> If a binding is added to or removed from this context,
     * its effect on an enumeration previously returned is undefined.
     *
     * @param name
     *          the name of the context to list
     * @return  an enumeration of the bindings in this context.
     *          Each element of the enumeration is of type
     *          {@code Binding}.
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #listBindings(String)
     * @see #list(Name)
     * @see Binding
      */
    public NamingEnumeration<Binding> listBindings(Name name)
        throws NamingException;

    /**
     * Enumerates the names bound in the named context, along with the
     * objects bound to them.
     * See {@link #listBindings(Name)} for details.
     *
     * @param name
     *          the name of the context to list
     * @return  an enumeration of the bindings in this context.
     *          Each element of the enumeration is of type
     *          {@code Binding}.
     * @throws  NamingException if a naming exception is encountered
     */
    public NamingEnumeration<Binding> listBindings(String name)
        throws NamingException;

    /**
     * Destroys the named context and removes it from the namespace.
     * Any attributes associated with the name are also removed.
     * Intermediate contexts are not destroyed.
     *
     * <p> This method is idempotent.
     * It succeeds even if the terminal atomic name
     * is not bound in the target context, but throws
     * {@code NameNotFoundException}
     * if any of the intermediate contexts do not exist.
     *
     * <p> In a federated naming system, a context from one naming system
     * may be bound to a name in another.  One can subsequently
     * look up and perform operations on the foreign context using a
     * composite name.  However, an attempt destroy the context using
     * this composite name will fail with
     * {@code NotContextException}, because the foreign context is not
     * a "subcontext" of the context in which it is bound.
     * Instead, use {@code unbind()} to remove the
     * binding of the foreign context.  Destroying the foreign context
     * requires that the {@code destroySubcontext()} be performed
     * on a context from the foreign context's "native" naming system.
     *
     * @param name
     *          the name of the context to be destroyed; may not be empty
     * @throws  NameNotFoundException if an intermediate context does not exist
     * @throws  NotContextException if the name is bound but does not name a
     *          context, or does not name a context of the appropriate type
     * @throws  ContextNotEmptyException if the named context is not empty
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #destroySubcontext(String)
     */
    public void destroySubcontext(Name name) throws NamingException;

    /**
     * Destroys the named context and removes it from the namespace.
     * See {@link #destroySubcontext(Name)} for details.
     *
     * @param name
     *          the name of the context to be destroyed; may not be empty
     * @throws  NameNotFoundException if an intermediate context does not exist
     * @throws  NotContextException if the name is bound but does not name a
     *          context, or does not name a context of the appropriate type
     * @throws  ContextNotEmptyException if the named context is not empty
     * @throws  NamingException if a naming exception is encountered
     */
    public void destroySubcontext(String name) throws NamingException;

    /**
     * Creates and binds a new context.
     * Creates a new context with the given name and binds it in
     * the target context (that named by all but terminal atomic
     * component of the name).  All intermediate contexts and the
     * target context must already exist.
     *
     * @param name
     *          the name of the context to create; may not be empty
     * @return  the newly created context
     *
     * @throws  NameAlreadyBoundException if name is already bound
     * @throws  javax.naming.directory.InvalidAttributesException
     *          if creation of the subcontext requires specification of
     *          mandatory attributes
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #createSubcontext(String)
     * @see javax.naming.directory.DirContext#createSubcontext
     */
    public Context createSubcontext(Name name) throws NamingException;

    /**
     * Creates and binds a new context.
     * See {@link #createSubcontext(Name)} for details.
     *
     * @param name
     *          the name of the context to create; may not be empty
     * @return  the newly created context
     *
     * @throws  NameAlreadyBoundException if name is already bound
     * @throws  javax.naming.directory.InvalidAttributesException
     *          if creation of the subcontext requires specification of
     *          mandatory attributes
     * @throws  NamingException if a naming exception is encountered
     */
    public Context createSubcontext(String name) throws NamingException;

    /**
     * Retrieves the named object, following links except
     * for the terminal atomic component of the name.
     * If the object bound to {@code name} is not a link,
     * returns the object itself.
     *
     * @param name
     *          the name of the object to look up
     * @return  the object bound to {@code name}, not following the
     *          terminal link (if any).
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #lookupLink(String)
     */
    public Object lookupLink(Name name) throws NamingException;

    /**
     * Retrieves the named object, following links except
     * for the terminal atomic component of the name.
     * See {@link #lookupLink(Name)} for details.
     *
     * @param name
     *          the name of the object to look up
     * @return  the object bound to {@code name}, not following the
     *          terminal link (if any)
     * @throws  NamingException if a naming exception is encountered
     */
    public Object lookupLink(String name) throws NamingException;

    /**
     * Retrieves the parser associated with the named context.
     * In a federation of namespaces, different naming systems will
     * parse names differently.  This method allows an application
     * to get a parser for parsing names into their atomic components
     * using the naming convention of a particular naming system.
     * Within any single naming system, {@code NameParser} objects
     * returned by this method must be equal (using the {@code equals()}
     * test).
     *
     * @param name
     *          the name of the context from which to get the parser
     * @return  a name parser that can parse compound names into their atomic
     *          components
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #getNameParser(String)
     * @see CompoundName
     */
    public NameParser getNameParser(Name name) throws NamingException;

    /**
     * Retrieves the parser associated with the named context.
     * See {@link #getNameParser(Name)} for details.
     *
     * @param name
     *          the name of the context from which to get the parser
     * @return  a name parser that can parse compound names into their atomic
     *          components
     * @throws  NamingException if a naming exception is encountered
     */
    public NameParser getNameParser(String name) throws NamingException;

    /**
     * Composes the name of this context with a name relative to
     * this context.
     * Given a name (<code>name</code>) relative to this context, and
     * the name (<code>prefix</code>) of this context relative to one
     * of its ancestors, this method returns the composition of the
     * two names using the syntax appropriate for the naming
     * system(s) involved.  That is, if <code>name</code> names an
     * object relative to this context, the result is the name of the
     * same object, but relative to the ancestor context.  None of the
     * names may be null.
     * <p>
     * For example, if this context is named "wiz.com" relative
     * to the initial context, then
     * <pre>
     *  composeName("east", "wiz.com")  </pre>
     * might return <code>"east.wiz.com"</code>.
     * If instead this context is named "org/research", then
     * <pre>
     *  composeName("user/jane", "org/research")        </pre>
     * might return <code>"org/research/user/jane"</code> while
     * <pre>
     *  composeName("user/jane", "research")    </pre>
     * returns <code>"research/user/jane"</code>.
     *
     * @param name
     *          a name relative to this context
     * @param prefix
     *          the name of this context relative to one of its ancestors
     * @return  the composition of <code>prefix</code> and <code>name</code>
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #composeName(String, String)
     */
    public Name composeName(Name name, Name prefix)
        throws NamingException;

    /**
     * Composes the name of this context with a name relative to
     * this context.
     * See {@link #composeName(Name, Name)} for details.
     *
     * @param name
     *          a name relative to this context
     * @param prefix
     *          the name of this context relative to one of its ancestors
     * @return  the composition of <code>prefix</code> and <code>name</code>
     * @throws  NamingException if a naming exception is encountered
     */
    public String composeName(String name, String prefix)
            throws NamingException;

    /**
     * Adds a new environment property to the environment of this
     * context.  If the property already exists, its value is overwritten.
     * See class description for more details on environment properties.
     *
     * @param propName
     *          the name of the environment property to add; may not be null
     * @param propVal
     *          the value of the property to add; may not be null
     * @return  the previous value of the property, or null if the property was
     *          not in the environment before
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #getEnvironment()
     * @see #removeFromEnvironment(String)
     */
    public Object addToEnvironment(String propName, Object propVal)
        throws NamingException;

    /**
     * Removes an environment property from the environment of this
     * context.  See class description for more details on environment
     * properties.
     *
     * @param propName
     *          the name of the environment property to remove; may not be null
     * @return  the previous value of the property, or null if the property was
     *          not in the environment
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #getEnvironment()
     * @see #addToEnvironment(String, Object)
     */
    public Object removeFromEnvironment(String propName)
        throws NamingException;

    /**
     * Retrieves the environment in effect for this context.
     * See class description for more details on environment properties.
     *
     * <p> The caller should not make any changes to the object returned:
     * their effect on the context is undefined.
     * The environment of this context may be changed using
     * {@code addToEnvironment()} and {@code removeFromEnvironment()}.
     *
     * @return  the environment of this context; never null
     * @throws  NamingException if a naming exception is encountered
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    public Hashtable<?,?> getEnvironment() throws NamingException;

    /**
     * Closes this context.
     * This method releases this context's resources immediately, instead of
     * waiting for them to be released automatically by the garbage collector.
     *
     * <p> This method is idempotent:  invoking it on a context that has
     * already been closed has no effect.  Invoking any other method
     * on a closed context is not allowed, and results in undefined behaviour.
     *
     * @throws  NamingException if a naming exception is encountered
     */
    public void close() throws NamingException;

    /**
     * Retrieves the full name of this context within its own namespace.
     *
     * <p> Many naming services have a notion of a "full name" for objects
     * in their respective namespaces.  For example, an LDAP entry has
     * a distinguished name, and a DNS record has a fully qualified name.
     * This method allows the client application to retrieve this name.
     * The string returned by this method is not a JNDI composite name
     * and should not be passed directly to context methods.
     * In naming systems for which the notion of full name does not
     * make sense, {@code OperationNotSupportedException} is thrown.
     *
     * @return  this context's name in its own namespace; never null
     * @throws  OperationNotSupportedException if the naming system does
     *          not have the notion of a full name
     * @throws  NamingException if a naming exception is encountered
     *
     * @since 1.3
     */
    public String getNameInNamespace() throws NamingException;

// public static final:  JLS says recommended style is to omit these modifiers
// because they are the default

    /**
     * Constant that holds the name of the environment property
     * for specifying the initial context factory to use. The value
     * of the property should be the fully qualified class name
     * of the factory class that will create an initial context.
     * This property may be specified in the environment parameter
     * passed to the initial context constructor,
     * a system property, or an application resource file.
     * If it is not specified in any of these sources,
     * {@code NoInitialContextException} is thrown when an initial
     * context is required to complete an operation.
     *
     * <p> The value of this constant is "java.naming.factory.initial".
     *
     * @see InitialContext
     * @see javax.naming.directory.InitialDirContext
     * @see javax.naming.spi.NamingManager#getInitialContext
     * @see javax.naming.spi.InitialContextFactory
     * @see NoInitialContextException
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String INITIAL_CONTEXT_FACTORY = "java.naming.factory.initial";

    /**
     * Constant that holds the name of the environment property
     * for specifying the list of object factories to use. The value
     * of the property should be a colon-separated list of the fully
     * qualified class names of factory classes that will create an object
     * given information about the object.
     * This property may be specified in the environment, a system property,
     * or one or more resource files.
     *
     * <p> The value of this constant is "java.naming.factory.object".
     *
     * @see javax.naming.spi.NamingManager#getObjectInstance
     * @see javax.naming.spi.ObjectFactory
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String OBJECT_FACTORIES = "java.naming.factory.object";

    /**
     * Constant that holds the name of the environment property
     * for specifying the list of state factories to use. The value
     * of the property should be a colon-separated list of the fully
     * qualified class names of state factory classes that will be used
     * to get an object's state given the object itself.
     * This property may be specified in the environment, a system property,
     * or one or more resource files.
     *
     * <p> The value of this constant is "java.naming.factory.state".
     *
     * @see javax.naming.spi.NamingManager#getStateToBind
     * @see javax.naming.spi.StateFactory
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     * @since 1.3
     */
    String STATE_FACTORIES = "java.naming.factory.state";

    /**
     * Constant that holds the name of the environment property
     * for specifying the list of package prefixes to use when
     * loading in URL context factories. The value
     * of the property should be a colon-separated list of package
     * prefixes for the class name of the factory class that will create
     * a URL context factory.
     * This property may be specified in the environment, a system property,
     * or one or more resource files.
     * The prefix {@code com.sun.jndi.url} is always appended to
     * the possibly empty list of package prefixes.
     *
     * <p> The value of this constant is "java.naming.factory.url.pkgs".
     *
     * @see javax.naming.spi.NamingManager#getObjectInstance
     * @see javax.naming.spi.NamingManager#getURLContext
     * @see javax.naming.spi.ObjectFactory
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String URL_PKG_PREFIXES = "java.naming.factory.url.pkgs";

    /**
     * Constant that holds the name of the environment property
     * for specifying configuration information for the service provider
     * to use. The value of the property should contain a URL string
     * (e.g. "ldap://somehost:389").
     * This property may be specified in the environment, a system property,
     * or a resource file.
     * If it is not specified in any of these sources,
     * the default configuration is determined by the service provider.
     *
     * <p> The value of this constant is "java.naming.provider.url".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String PROVIDER_URL = "java.naming.provider.url";

    /**
     * Constant that holds the name of the environment property
     * for specifying the DNS host and domain names to use for the
     * JNDI URL context (for example, "dns://somehost/wiz.com").
     * This property may be specified in the environment, a system property,
     * or a resource file.
     * If it is not specified in any of these sources
     * and the program attempts to use a JNDI URL containing a DNS name,
     * a {@code ConfigurationException} will be thrown.
     *
     * <p> The value of this constant is "java.naming.dns.url".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String DNS_URL = "java.naming.dns.url";

    /**
     * Constant that holds the name of the environment property for
     * specifying the authoritativeness of the service requested.
     * If the value of the property is the string "true", it means
     * that the access is to the most authoritative source (i.e. bypass
     * any cache or replicas). If the value is anything else,
     * the source need not be (but may be) authoritative.
     * If unspecified, the value defaults to "false".
     *
     * <p> The value of this constant is "java.naming.authoritative".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String AUTHORITATIVE = "java.naming.authoritative";

    /**
     * Constant that holds the name of the environment property for
     * specifying the batch size to use when returning data via the
     * service's protocol. This is a hint to the provider to return
     * the results of operations in batches of the specified size, so
     * the provider can optimize its performance and usage of resources.
     * The value of the property is the string representation of an
     * integer.
     * If unspecified, the batch size is determined by the service
     * provider.
     *
     * <p> The value of this constant is "java.naming.batchsize".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String BATCHSIZE = "java.naming.batchsize";

    /**
     * Constant that holds the name of the environment property for
     * specifying how referrals encountered by the service provider
     * are to be processed. The value of the property is one of the
     * following strings:
     * <dl>
     * <dt>"follow"
     * <dd>follow referrals automatically
     * <dt>"ignore"
     * <dd>ignore referrals
     * <dt>"throw"
     * <dd>throw {@code ReferralException} when a referral is encountered.
     * </dl>
     * If this property is not specified, the default is
     * determined by the provider.
     *
     * <p> The value of this constant is "java.naming.referral".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String REFERRAL = "java.naming.referral";

    /**
     * Constant that holds the name of the environment property for
     * specifying the security protocol to use.
     * Its value is a string determined by the service provider
     * (e.g. "ssl").
     * If this property is unspecified,
     * the behaviour is determined by the service provider.
     *
     * <p> The value of this constant is "java.naming.security.protocol".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String SECURITY_PROTOCOL = "java.naming.security.protocol";

    /**
     * Constant that holds the name of the environment property for
     * specifying the security level to use.
     * Its value is one of the following strings:
     * "none", "simple", "strong".
     * If this property is unspecified,
     * the behaviour is determined by the service provider.
     *
     * <p> The value of this constant is "java.naming.security.authentication".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String SECURITY_AUTHENTICATION = "java.naming.security.authentication";

    /**
     * Constant that holds the name of the environment property for
     * specifying the identity of the principal for authenticating
     * the caller to the service. The format of the principal
     * depends on the authentication scheme.
     * If this property is unspecified,
     * the behaviour is determined by the service provider.
     *
     * <p> The value of this constant is "java.naming.security.principal".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String SECURITY_PRINCIPAL = "java.naming.security.principal";

    /**
     * Constant that holds the name of the environment property for
     * specifying the credentials of the principal for authenticating
     * the caller to the service. The value of the property depends
     * on the authentication scheme. For example, it could be a hashed
     * password, clear-text password, key, certificate, and so on.
     * If this property is unspecified,
     * the behaviour is determined by the service provider.
     *
     * <p> The value of this constant is "java.naming.security.credentials".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */

    String SECURITY_CREDENTIALS = "java.naming.security.credentials";
    /**
     * Constant that holds the name of the environment property for
     * specifying the preferred language to use with the service.
     * The value of the property is a colon-separated list of language
     * tags as defined in RFC 1766.
     * If this property is unspecified,
     * the language preference is determined by the service provider.
     *
     * <p> The value of this constant is "java.naming.language".
     *
     * @see #addToEnvironment(String, Object)
     * @see #removeFromEnvironment(String)
     */
    String LANGUAGE = "java.naming.language";
};
