/*
 * Copyright (c) 2000, 2015, 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.
 */

/*
 * Differences from original:
 *
 * - do not include orb.idl
 * - include IOP.idl, Messaging.idl and CORBAX.idl
 * - renamed component parameter names to tagged_component (so that they 
 *   do not conflict with the CORBA 3.0 "component" keyword).
 * - javadocs added (synchronized with orbos/00-08-06)
 * 
 * NOTE: After compilation of this IDL file, all Helper and Holder classes
 * that are not needed are removed.
 */
#include "IOP.idl"
#include "Messaging.idl"
#include "CORBAX.idl"
#include "corba.idl"

#pragma prefix "omg.org"

#ifndef CORBA3
#define local
#endif

module Dynamic {

  /**
   * <code>NVList</code> PIDL represented by <code>ParameterList</code> IDL.  
   * This exists in order to keep the Portable Interceptor IDL from becoming 
   * PIDL.
   */
  struct Parameter {
    any argument;
    CORBA::ParameterMode mode;
  };

  /**
   * <code>NVList</code> PIDL represented by <code>ParameterList</code> IDL.  
   * This exists in order to keep the Portable Interceptor IDL from becoming 
   * PIDL.
   */
  typedef sequence<Parameter> ParameterList;

  /**
   * <code>ContextList</code> PIDL represented by <code>ContextList</code> 
   * IDL.  This exists in order to keep the Portable Interceptor IDL from 
   * becoming PIDL.
   */
  typedef CORBA::StringSeq ContextList;

  /**
   * <code>ExceptionList</code> PIDL represented by <code>ExceptionList</code> 
   * IDL.  This exists in order to keep the Portable Interceptor IDL from 
   * becoming PIDL.
   */
  typedef sequence<CORBA::TypeCode> ExceptionList;

  /**
   * <code>Context</code> PIDL represented by <code>RequestContext</code> 
   * IDL.  This exists in order to keep the Portable Interceptor IDL from o
   * becoming PIDL.
   * <p>
   * <code>Context</code> objects are encoded as <code>String[]</code>.  The 
   * <code>Strings</code> occur in pairs.  The first <code>String</code> in 
   * each pair is the context property name and the second <code>String</code>
   * in each pair is the associated value.
   */
  typedef CORBA::StringSeq RequestContext;
};

module PortableInterceptor {
  /**
   * All Portable Interceptors implement Interceptor.
   */
  local interface Interceptor {
    /**
     * Returns the name of the interceptor.
     * <p>
     * Each Interceptor may have a name that may be used administratively 
     * to order the lists of Interceptors. Only one Interceptor of a given 
     * name can be registered with the ORB for each Interceptor type. An 
     * Interceptor may be anonymous, i.e., have an empty string as the name 
     * attribute. Any number of anonymous Interceptors may be registered with 
     * the ORB.
     *
     * @return the name of the interceptor.
     */
    readonly attribute string name;

    // Added in ptc/00-08-06
    /**
     * Provides an opportunity to destroy this interceptor.
     * The destroy method is called during <code>ORB.destroy</code>. When an 
     * application calls <code>ORB.destroy</code>, the ORB:
     * <ol>
     *   <li>waits for all requests in progress to complete</li>
     *   <li>calls the <code>Interceptor.destroy</code> operation for each 
     *       interceptor</li>
     *   <li>completes destruction of the ORB</li>
     * </ol>
     * Method invocations from within <code>Interceptor.destroy</code> on 
     * object references for objects implemented on the ORB being destroyed 
     * result in undefined behavior. However, method invocations on objects 
     * implemented on an ORB other than the one being destroyed are 
     * permitted. (This means that the ORB being destroyed is still capable 
     * of acting as a client, but not as a server.) 
     */
    void destroy();
  };


  /**
   * The <code>ForwardRequest</code> exception is the means by which an 
   * Interceptor can indicate to the ORB that a retry of the request should 
   * occur with the new object given in the exception. This behavior of 
   * causing a retry only occurs if the ORB receives a ForwardRequest from 
   * an interceptor. If <code>ForwardRequest</code> is thrown anywhere else 
   * it is passed through the ORB as is normal for a user exception. 
   * <p>
   * If an Interceptor throws a <code>ForwardRequest</code> exception in 
   * response to a call of an interceptor, no other Interceptors are called 
   * for that interception point. The remaining Interceptors in the Flow Stack 
   * shall have their appropriate ending interception point called: 
   * <code>receive_other</code> on the client, or <code>send_other</code> on 
   * the server. The <code>reply_status</code> in the 
   * <code>receive_other</code> or <code>send_other</code> would be 
   * <code>LOCATION_FORWARD</code>.
   */
  exception ForwardRequest {
    /** 
     * The new object to forward the request to.
     */
    Object forward;
//   Change in ptc/00-08-06
//    boolean permanent;
  };

  /** Reply status, represented as an int */
  typedef short ReplyStatus;

  // Valid reply_status values:

  /**
   * Indicates a successful Reply Status. One possible value for 
   * <code>RequestInfo.reply_status</code>.
   * @see RequestInfo#reply_status
   * @see SYSTEM_EXCEPTION
   * @see USER_EXCEPTION
   * @see LOCATION_FORWARD
   * @see TRANSPORT_RETRY
   */
  const ReplyStatus SUCCESSFUL = 0;

  /**
   * Indicates a SystemException reply status. One possible value for 
   * <code>RequestInfo.reply_status</code>.
   * @see RequestInfo#reply_status
   * @see SUCCESSFUL
   * @see USER_EXCEPTION
   * @see LOCATION_FORWARD
   * @see TRANSPORT_RETRY
   */
  const ReplyStatus SYSTEM_EXCEPTION = 1;

  /**
   * Indicates a UserException reply status. One possible value for 
   * <code>RequestInfo.reply_status</code>.
   * @see RequestInfo#reply_status
   * @see SUCCESSFUL
   * @see SYSTEM_EXCEPTION
   * @see LOCATION_FORWARD
   * @see TRANSPORT_RETRY
   */
  const ReplyStatus USER_EXCEPTION = 2;

  /**
   * Indicates a LocationForward reply status. One possible value for 
   * <code>RequestInfo.reply_status</code>.
   * @see RequestInfo#reply_status
   * @see SUCCESSFUL
   * @see SYSTEM_EXCEPTION
   * @see USER_EXCEPTION
   * @see TRANSPORT_RETRY
   */
  const ReplyStatus LOCATION_FORWARD = 3;

// Changes in ptc/00-08-06
//  const ReplyStatus LOCATION_FORWARD_PERMANENT = 4;

  /**
   * Indicates a Transport Retry reply status. One possible value for 
   * <code>RequestInfo.reply_status</code>.
   * @see RequestInfo#reply_status
   * @see SUCCESSFUL
   * @see SYSTEM_EXCEPTION
   * @see USER_EXCEPTION
   * @see LOCATION_FORWARD
   */
  const ReplyStatus TRANSPORT_RETRY = 4;

  /**
   * XXX
   */
  const ReplyStatus UNKNOWN = 5;

  /** Slot id, represented as an int */
  typedef unsigned long SlotId;

  /**
   * This exception is thrown when <code>get_slot</code> or 
   * <code>set_slot</code> is called on a slot that has not been allocated.
   */
  exception InvalidSlot {};

  /**
   * Portable Interceptors Current (also known as <code>PICurrent</code>) 
   * is merely a slot table, the slots of which are used by each service to 
   * transfer their context data between their context and the request's or 
   * reply's service context. Each service which wishes to use PICurrent 
   * reserves a slot or slots at initialization time and uses those slots 
   * during the processing of requests and replies.
   * <p>
   * Before an invocation is made, PICurrent is obtained via a call to 
   * <code>ORB.resolve_initial_references( "PICurrent" )</code>. From within 
   * the interception points, the data on PICurrent that has moved from the 
   * thread scope to the request scope is available via the 
   * <code>get_slot</code> operation on the <code>RequestInfo</code> object. 
   * A PICurrent can still be obtained via 
   * <code>resolve_initial_references</code>, but that is the Interceptor's 
   * thread scope PICurrent.
   */
  local interface Current : CORBA::Current {

    /**
     * Retrieves the slot data the application set in PICurrent via 
     * <code>get_slot</code>.  The data is in the form of an Any. 
     * <p>
     * If the given slot has not been set, an Any containing a type code 
     * with a <code>TCKind</code> value of <code>tk_null</code> and no value 
     * is returned. 
     *
     * @param id The <code>SlotId</code> of the slot from which the data will 
     *     be returned. 
     * @return The data, in the form of an Any, of the given slot identifier.
     * @exception InvalidSlot thrown if get_slot is called on a slot that 
     *     has not been allocated. 
     * @exception BAD_INV_ORDER thrown if <code>get_slot</code> is called 
     *     from within an ORB initializer 
     */
    any get_slot (in SlotId id) raises (InvalidSlot);

    /**
     * Sets data in a slot. The data is in the form of an Any. If data 
     * already exists in that slot, it is overridden. 
     *
     * @param id The <code>SlotId</code> of the slot to which the data will 
     *     be set. 
     * @param data The data, in the form of an Any, which will be set 
     *     to the identified slot. 
     * @exception InvalidSlot thrown if <code>set_slot</code> is called on 
     *     a slot that has not been allocated.
     * @exception BAD_INV_ORDER thrown if <code>set_slot</code> is called 
     *     from within an ORB initializer. 
     */
    void set_slot (in SlotId id, in any data) raises (InvalidSlot);
  };

  /**
   * Request Information, accessible to Interceptors.
   * <p>
   * Each interception point is given an object through which the 
   * Interceptor can access request information. Client-side and server-side 
   * interception points are concerned with different information, so there 
   * are two information objects: <code>ClientRequestInfo</code> is passed 
   * to the client-side interception points and <code>ServerRequestInfo</code>
   * is passed to the server-side interception points. But there is 
   * information that is common to both, so they both inherit from a common 
   * interface: <code>RequestInfo</code>.
   *
   * @see ClientRequestInfo
   * @see ServerRequestInfo
   */
  local interface RequestInfo {
    /**
     * Returns an id that uniquely identifies an active request/reply 
     * sequence. Once a request/reply sequence is concluded this ID may be 
     * reused. Note that this id is not the same as the GIOP 
     * <code>request_id</code>. If GIOP is the transport mechanism used, 
     * then these IDs may very well be the same, but this is not guaranteed 
     * nor required.
     */
    readonly attribute unsigned long request_id;

    /**
     * Returns the name of the operation being invoked.
     */
    readonly attribute string operation;

    /**
     * Returns an array of <code>Parameter</code> objects, containing the 
     * arguments on the operation being invoked.  If there are no arguments, 
     * this attribute will be a zero length array. 
     * <p>
     * Not all environments provide access to the arguments. With the Java 
     * portable bindings, for example, the arguments are not available. 
     * In these environments, when this attribute is accessed, 
     * <code>NO_RESOURCES</code> will be thrown with a standard minor code 
     * of 1.
     * <p>
     * <i>Note: Arguments are available for DSI/DII calls.</i>
     *
     * @exception NO_RESOURCES thrown if arguments are not available.
     * @see <a href="package-summary.html#unimpl">
     *     <code>PortableInterceptor</code> package comments for 
     *     limitations / unimplemented features</a>
     */
    readonly attribute Dynamic::ParameterList arguments;

    /**
     * Returns an array of <code>TypeCode</code> objects describing the 
     * <code>TypeCode</code>s of the user exceptions that this operation 
     * invocation may throw. If there are no user exceptions, this 
     * will return a zero length array. 
     * <p>
     * Not all environments provide access to the exception list. With 
     * the Java portable bindings, for example, the exception list is 
     * not available. In these environments, when this attribute is 
     * accessed, <code>NO_RESOURCES</code> will be thrown with a 
     * standard minor code of 1.
     * <p>
     * <i>Note: Exceptions are available for DSI/DII calls.</i>
     *
     * @exception NO_RESOURCES thrown if exceptions are not available.
     * @see <a href="package-summary.html#unimpl">
     *     <code>PortableInterceptor</code> package comments for 
     *     limitations / unimplemented features</a>
     */
    readonly attribute Dynamic::ExceptionList exceptions;

    /**
     * Returns an array of <code>String</code> objects describing the 
     * contexts that may be passed on this operation invocation.  If there 
     * are no contexts, this will return a zero length array. 
     * <p>
     * Not all environments provide access to the context list. With the 
     * Java portable bindings, for example, the context list is not 
     * available. In these environments, when this attribute is accessed, 
     * <code>NO_RESOURCES</code> will be thrown with a standard minor code 
     * of 1.
     * <p>
     * <i>Note: Contexts are available for DSI/DII calls.</i>
     *
     * @exception NO_RESOURCES thrown if contexts are not available.
     * @see <a href="package-summary.html#unimpl">
     *     <code>PortableInterceptor</code> package comments for 
     *     limitations / unimplemented features</a>
     */
    readonly attribute Dynamic::ContextList contexts;

    /**
     * Returns an array of <code>String</code> objects containing the 
     * contexts being sent on the request.
     * <p>
     * Not all environments provide access to the context. With the Java 
     * portable bindings, for example, the context is not available. In 
     * these environments, when this attribute is accessed, NO_RESOURCES will 
     * be thrown with standard minor code of 1.
     * <p>
     * <i>Note: <code>operation_context</code> is available for 
     * DSI/DII calls.</i>
     *
     * @exception NO_RESOURCES thrown if operation context is not available.
     * @see <a href="package-summary.html#unimpl">
     *     <code>PortableInterceptor</code> package comments for 
     *     limitations / unimplemented features</a>
     */
    readonly attribute Dynamic::RequestContext operation_context;

    /**
     * Returns an any containing the result of the operation invocation. 
     * If the operation return type is void, this attribute will be an any 
     * containing a type code with a <code>TCKind</code> value of 
     * <code>tk_void</code> and no value. 
     * <p>
     * Not all environments provide access to the result. With the Java 
     * portable bindings, for example, the result is not available. In 
     * these environments, when this attribute is accessed, 
     * <code>NO_RESOURCES</code> will be thrown with a standard minor code of 
     * 1.
     * <p>
     * <i>Note: Result is available for DSI/DII calls.</i>
     *
     * @exception NO_RESOURCES thrown if result is not available.
     * @see <a href="package-summary.html#unimpl">
     *     <code>PortableInterceptor</code> package comments for 
     *     limitations / unimplemented features</a>
     */
    readonly attribute any result;

    /**
     * Indicates whether a response is expected. 
     * <p>
     * On the client, a reply is not returned when 
     * <code>response_expected</code> is false, so <code>receive_reply</code> 
     * cannot be called. <code>receive_other</code> is called unless an 
     * exception occurs, in which case <code>receive_exception</code> is 
     * called. 
     * <p>
     * On the client, within <code>send_poll</code>, this attribute is true.
     */
    readonly attribute boolean response_expected;

    /**
     * Defines how far the request shall progress before control is returned
     * to the client.  This is defined in the Messaging specification, and 
     * is pertinent only when <code>response_expected</code> is false. If 
     * <code>response_expected</code> is true, the value of 
     * <code>sync_scope</code> is undefined. This attribute may have one of 
     * the following values: 
     * <ul>
     *   <li><code>Messaging.SYNC_NONE</code></li>
     *   <li><code>Messaging.SYNC_WITH_TRANSPORT</code></li>
     *   <li><code>Messaging.SYNC_WITH_SERVER</code></li>
     *   <li><code>Messaging.SYNC_WITH_TARGET</code></li>
     * </ul>
     * On the server, for all scopes, a reply will be created from the 
     * return of the target operation call, but the reply will not return 
     * to the client. Although it does not return to the client, it does 
     * occur, so the normal server-side interception points are 
     * followed (i.e., <code>receive_request_service_contexts</code>, 
     * <code>receive_request</code>, <code>send_reply</code> or 
     * <code>send_exception</code>). 
     * <p>
     * For <code>SYNC_WITH_SERVER</code> and <code>SYNC_WITH_TARGET</code>, 
     * the server does send an empty reply back to the client before the 
     * target is invoked. This reply is not intercepted by server-side 
     * Interceptors.
     * 
     * @see <a href="package-summary.html#unimpl">
     *     <code>PortableInterceptor</code> package comments for 
     *     limitations / unimplemented features</a>
     */
    readonly attribute Messaging::SyncScope sync_scope;

    /**
     * Describes the state of the result of the operation invocation. The
     * return value can be one of the following: 
     * <ul>
     *   <li><code>PortableInterceptor.SUCCESSFUL</code></li>
     *   <li><code>PortableInterceptor.SYSTEM_EXCEPTION</code></li>
     *   <li><code>PortableInterceptor.USER_EXCEPTION</code></li>
     *   <li><code>PortableInterceptor.LOCATION_FORWARD</code></li>
     *   <li><code>PortableInterceptor.TRANSPORT_RETRY</code></li>
     * </ul>
     * On the client:
     * <ul>
     *   <li>Within the <code>receive_reply</code> interception point, this 
     *       will only return <code>SUCCESSFUL</code>.</li>
     *   <li>Within the <code>receive_exception</code> interception point, 
     *       this will be either <code>SYSTEM_EXCEPTION</code> or 
     *       <code>USER_EXCEPTION</code>.</li>
     *   <li>Within the <code>receive_other</code> interception point, this 
     *       will be any of: <code>SUCCESSFUL</code>, 
     *       <code>LOCATION_FORWARD</code>, or <code>TRANSPORT_RETRY</code>. 
     *       <code>SUCCESSFUL</code> means an asynchronous request returned 
     *       successfully. <code>LOCATION_FORWARD</code> means that a reply 
     *       came back with <code>LOCATION_FORWARD</code> as its status. 
     *       <code>TRANSPORT_RETRY</code> means that the transport 
     *       mechanism indicated a retry - a GIOP reply with a status of 
     *       <code>NEEDS_ADDRESSING_MODE</code>, for instance. </li>
     * </ul>
     * On the server: 
     * <ul>
     *   <li>Within the <code>send_reply</code> interception point, this 
     *       will only be <code>SUCCESSFUL</code>.</li>
     *   <li>Within the <code>send_exception</code> interception point, 
     *       this will be either <code>SYSTEM_EXCEPTION</code> or 
     *       <code>USER_EXCEPTION</code>.</li>
     *   <li>Within the <code>send_other</code> interception point, this 
     *       attribute will be any of: <code>SUCCESSFUL</code>, or 
     *       <code>LOCATION_FORWARD</code>. <code>SUCCESSFUL</code> means 
     *       an asynchronous request returned successfully. 
     *       <code>LOCATION_FORWARD</code> means that a reply came back 
     *       with <code>LOCATION_FORWARD</code> as its status.</li>
     * </ul>
     * 
     * @see SUCCESSFUL
     * @see SYSTEM_EXCEPTION
     * @see USER_EXCEPTION
     * @see LOCATION_FORWARD
     * @see TRANSPORT_RETRY
     */
    readonly attribute ReplyStatus reply_status;

    /** 
     * Contains the object to which the request will be forwarded, if the 
     * <code>reply_status</code> attribute is <code>LOCATION_FORWARD</code>.
     * It is indeterminate whether a forwarded request will actually occur.
     */
    readonly attribute Object forward_reference;

    /**
     * Returns the data from the given slot of the 
     * <code>PortableInterceptor.Current</code> that is in the scope of 
     * the request. 
     * <p>
     * If the given slot has not been set, then an any containing a 
     * type code with a <code>TCKind</code> value of <code>tk_null</code> is 
     * returned. 
     *
     * @param id The <code>SlotId</code> of the slot which is to be 
     *     returned. 
     * @return The slot data, in the form of an any, obtained with the 
     *     given identifier.
     * @exception InvalidSlot thrown if the ID does not define an 
     *    allocated slot.
     * @see Current
     */
    any get_slot (in SlotId id) raises (InvalidSlot);

    /**
     * Returns a copy of the service context with the given ID that 
     * is associated with the request. 
     *
     * @param id The <code>IOP.ServiceId</code> of the service context 
     *     which is to be returned. 
     * @return The <code>IOP.ServiceContext</code> obtained with the 
     *     given identifier.
     * @exception BAD_PARAM thrown with a standard minor code of 26, if the 
     *     request's service context does not contain an entry for that ID.
     */
    IOP::ServiceContext get_request_service_context 
      (in IOP::ServiceId id);

    /**
     * Returns a copy of the service context with the given ID that 
     * is associated with the reply. 
     * 
     * @param id The <code>IOP.ServiceId</code> of the service context 
     *     which is to be returned. 
     * @return The <code>IOP.ServiceContext</code> obtained with the given 
     *     identifier. 
     * @exception BAD_PARAM thrown with a standard minor code of 26 if the 
     *     request's service context does not contain an entry for that ID.
     */
    IOP::ServiceContext get_reply_service_context 
      (in IOP::ServiceId id);
  };

  /**
   * Request Information, accessible to client-side request interceptors.
   * <p>
   * Some attributes and operations on <code>ClientRequestInfo</code> are 
   * not valid at all interception points.  The following table shows the 
   * validity of each attribute or operation.  If it is not valid, attempting 
   * to access it will result in a <code>BAD_INV_ORDER</code> being thrown
   * with a standard minor code of 14.
   *
   * <table border=1 summary="Shows the validity of each attribute or operation">
   *  <thead>
   *    <tr>
   *      <th>&nbsp;</th>
   *      <th id="send_req">send_request</th>
   *      <th id="send_poll">send_poll</th>
   *      <th id="rec_reply">receive_reply</th>
   *      <th id="rec_ex">receive_exception</th>
   *      <th id="rec_oth">receive_other</th>
   *    </tr>
   *  </thead>
   *  <tbody>
   *
   *  <tr>
   *     <td id="ri" colspan=6><i>Inherited from RequestInfo:</i></td>
   *  </tr>
   * 
   *  <tr><th id="req_id"><p align="left">request_id</p></th>
   *  <td headers="ri req_id send_req">yes</td> 
   *  <td headers="ri req_id send_poll">yes</td> 
   *  <td headers="ri req_id rec_reply">yes</td> 
   *  <td headers="ri req_id rec_ex">yes</td> 
   *  <td headers="ri req_id rec_oth">yes</td></tr>
   * 
   *  <tr><th id="op"><p align="left">operation</p></th>
   *  <td headers="ri op send_req">yes</td> 
   *  <td headers="ri op send_poll">yes</td> 
   *  <td headers="ri op rec_reply">yes</td> 
   *  <td headers="ri op rec_ex">yes</td> 
   *  <td headers="ri op rec_oth">yes</td></tr>
   *
   *  <tr><th id="arg"><p align="left">arguments</p></th>
   *  <td headers="ri arg send_req">yes<sub>1</sub></td>
   *  <td headers="ri arg send_poll">no </td> 
   *  <td headers="ri arg rec_reply">yes</td> 
   *  <td headers="ri arg rec_ex">no </td> 
   *  <td headers="ri arg rec_oth">no </td></tr>
   *
   *  <tr><th id="exc"><p align="left">exceptions</p></th>
   *  <td headers="ri exc send_req">yes</td> 
   *  <td headers="ri exc send_poll">no </td> 
   *  <td headers="ri exc rec_reply">yes</td> 
   *  <td headers="ri exc rec_ex">yes</td> 
   *  <td headers="ri exc rec_oth">yes</td></tr>
   *
   *  <tr><th id="con"><p align="left">contexts</p></th>
   *  <td headers="ri con send_req">yes</td> 
   *  <td headers="ri con send_poll">no </td> 
   *  <td headers="ri con rec_reply">yes</td> 
   *  <td headers="ri con rec_ex">yes</td> 
   *  <td headers="ri con rec_oth">yes</td></tr>
   *
   *  <tr><th id="op_con"><p align="left">operation_context</p></th>
   *  <td headers="ri op_con send_req">yes</td> 
   *  <td headers="ri op_con send_poll">no </td> 
   *  <td headers="ri op_con rec_reply">yes</td> 
   *  <td headers="ri op_con rec_ex">yes</td> 
   *  <td headers="ri op_con rec_oth">yes</td>
   *  </tr>
   *
   *  <tr><th id="result"><p align="left">result</p></th>
   *  <td headers="ri result send_req">no </td> 
   *  <td headers="ri result send_poll">no </td> 
   *  <td headers="ri result rec_reply">yes</td> 
   *  <td headers="ri result rec_ex">no </td> 
   *  <td headers="ri result rec_oth">no </td>
   *  </tr>
   *
   *  <tr><th id="res_exp"><p align="left">response_expected</p></th>
   *  <td headers="ri res_exp send_req">yes</td> 
   *  <td headers="ri res_exp send_poll">yes</td> 
   *  <td headers="ri res_exp rec_reply">yes</td> 
   *  <td headers="ri res_exp rec_ex">yes</td> 
   *  <td headers="ri res_exp rec_oth">yes</td></tr>
   *
   *  <tr><th id="sync_sco"><p align="left">sync_scope</p></th>
   *  <td headers="ri sync_sco send_req">yes</td> 
   *  <td headers="ri sync_sco send_poll">no </td> 
   *  <td headers="ri sync_sco rec_reply">yes</td> 
   *  <td headers="ri sync_sco rec_ex">yes</td> 
   *  <td headers="ri sync_sco rec_oth">yes</td>
   *  </tr>
   *
   *  <tr><th id="rep_stat"><p align="left">reply_status</p></th>
   *  <td headers="ri rep_stat send_req">no </td> 
   *  <td headers="ri rep_stat send_poll">no </td> 
   *  <td headers="ri rep_stat rec_reply">yes</td> 
   *  <td headers="ri rep_stat rec_ex">yes</td> 
   *  <td headers="ri rep_stat rec_oth">yes</td></tr>
   *
   *  <tr><th id="for_ref"><p align="left">forward_reference</p></th>
   *  <td headers="ri for_ref send_req">no </td>
   *  <td headers="ri for_ref send_poll">no </td> 
   *  <td headers="ri for_ref rec_reply">no </td> 
   *  <td headers="ri for_ref rec_ex">no </td> 
   *  <td headers="ri for_ref rec_oth">yes<sub>2</sub>
   *  </td></tr>
   *
   *  <tr><th id="get_slot"><p align="left">get_slot</p></th>
   *  <td headers="ri get_slot send_req">yes</td> 
   *  <td headers="ri get_slot send_poll">yes</td> 
   *  <td headers="ri get_slot rec_reply">yes</td> 
   *  <td headers="ri get_slot rec_ex">yes</td> 
   *  <td headers="ri get_slot rec_oth">yes</td></tr>
   *
   *  <tr><th id="grsc"><p align="left">get_request_service_context</p></th>
   *  <td headers="ri grsc send_req">yes</td> 
   *  <td headers="ri grsc send_poll">no </td> 
   *  <td headers="ri grsc rec_reply">yes</td> 
   *  <td headers="ri grsc rec_ex">yes</td> 
   *  <td headers="ri grsc rec_oth">yes</td></tr>
   *
   *  <tr><th id="gpsc"><p align="left">get_reply_service_context</p></th>
   *  <td headers="ri gpsc send_req">no </td> 
   *  <td headers="ri gpsc send_poll">no </td> 
   *  <td headers="ri gpsc rec_reply">yes</td> 
   *  <td headers="ri gpsc rec_ex">yes</td> 
   *  <td headers="ri gpsc rec_oth">yes</td>
   *  </tr>
   *
   *  <tr>
   *    <td id="cri" colspan=6><i>ClientRequestInfo-specific:</i></td>
   *  </tr>
   *
   *  <tr><th id="target"><p align="left">target</p></th>
   *  <td headers="cri target send_req">yes</td> 
   *  <td headers="cri target send_poll">yes</td> 
   *  <td headers="cri target rec_reply">yes</td> 
   *  <td headers="cri target rec_ex">yes</td> 
   *  <td headers="cri target rec_oth">yes</td></tr>
   *
   *  <tr><th id="eftarget"><p align="left">effective_target</p></th>
   *  <td headers="cri eftarget send_req">yes</td> 
   *  <td headers="cri eftarget send_poll">yes</td> 
   *  <td headers="cri eftarget rec_reply">yes</td> 
   *  <td headers="cri eftarget rec_ex">yes</td> 
   *  <td headers="cri eftarget rec_oth">yes</td>
   *  </tr>
   *
   *  <tr><th id="efprof"><p align="left">effective_profile</p></th>
   *  <td headers="cri efprof send_req">yes</td> 
   *  <td headers="cri efprof send_poll">yes</td> 
   *  <td headers="cri efprof rec_reply">yes</td> 
   *  <td headers="cri efprof rec_ex">yes</td> 
   *  <td headers="cri efprof rec_oth">yes</td></tr>
   *
   *  <tr><th id="rxp"><p align="left">received_exception</p></th>
   *  <td headers="cri rxp send_req">no </td> 
   *  <td headers="cri rxp send_poll">no </td> 
   *  <td headers="cri rxp rec_reply">no </td> 
   *  <td headers="cri rxp rec_ex">yes</td> 
   *  <td headers="cri rxp rec_oth">no </td></tr>
   *
   *  <tr><th id="rei"><p align="left">received_exception_id</p></th>
   *  <td headers="cri rei send_req">no </td> 
   *  <td headers="cri rei send_poll">no </td> 
   *  <td headers="cri rei rec_reply">no </td> 
   *  <td headers="cri rei rec_ex">yes</td> 
   *  <td headers="cri rei rec_oth">no </td></tr>
   *
   *  <tr><th id="gec"><p align="left">get_effective_component</p></th>
   *  <td headers="cri gec send_req">yes</td> 
   *  <td headers="cri gec send_poll">no </td> 
   *  <td headers="cri gec rec_reply">yes</td> 
   *  <td headers="cri gec rec_ex">yes</td> 
   *  <td headers="cri gec rec_oth">yes</td></tr>
   *
   *  <tr><th id="gecs"><p align="left">get_effective_components</p></th>
   *  <td headers="cri gecs send_req">yes</td> 
   *  <td headers="cri gecs send_poll">no </td> 
   *  <td headers="cri gecs rec_reply">yes</td> 
   *  <td headers="cri gecs rec_ex">yes</td> 
   *  <td headers="cri gecs rec_oth">yes</td></tr>
   *
   *  <tr><th id="grpcy"><p align="left">get_request_policy</p></th>
   *  <td headers="cri grpcy send_req">yes</td>
   *  <td headers="cri grpcy send_poll">no </td> 
   *  <td headers="cri grpcy rec_reply">yes</td> 
   *  <td headers="cri grpcy rec_ex">yes</td> 
   *  <td headers="cri grpcy rec_oth">yes</td></tr>
   *
   *  <tr><th id="arsc"><p align="left">add_request_service_context</p></th>
   *    <td headers="cri arsc send_req">yes</td> 
   *    <td headers="cri arsc send_poll">no </td> 
   *    <td headers="cri arsc rec_reply">no </td> 
   *    <td headers="cri arsc rec_ex">no </td> 
   *    <td headers="cri arsc rec_oth">no </td></tr>
   *
   *   </tbody>
   * </table>
   *
   * <ol>
   *   <li>When <code>ClientRequestInfo</code> is passed to 
   *       <code>send_request</code>, there is an entry in the list for every 
   *       argument, whether in, inout, or out.  But only the in and inout 
   *       arguments will be available.</li>
   *   <li>If the <code>reply_status</code> atribute is not 
   *       <code>LOCATION_FORWARD</code>, accessing this attribute will 
   *       throw <code>BAD_INV_ORDER</code> with a standard minor code of 
   *       14.</li>
   * </ol>
   *
   * @see ClientRequestInterceptor
   */
  local interface ClientRequestInfo : RequestInfo {

    /**
     * Returns the object which the client called to perform the 
     * operation. 
     *
     * @see #effective_target
     */
    readonly attribute Object target;

    /**
     * Returns the actual object on which the operation will be invoked. 
     * If the <code>reply_status</code> is <code>LOCATION_FORWARD</code>, 
     * then on subsequent requests, <code>effective_target</code> will 
     * contain the forwarded IOR while target will remain unchanged. 
     *
     * @see #target
     */
    readonly attribute Object effective_target;

    /**
     * Returns the profile that will be used to send the request. If a 
     * location forward has occurred for this operation's object and 
     * that object's profile changed accordingly, then this profile will 
     * be that located profile.
     */
    readonly attribute IOP::TaggedProfile effective_profile;

    /** 
     * Returns an any which contains the exception to be returned to 
     * the client. 
     * <p>
     * If the exception is a user exception which cannot be inserted 
     * into an any (e.g., it is unknown or the bindings don t provide 
     * the <code>TypeCode</code>), then this attribute will be an any 
     * containing the system exception <code>UNKNOWN</code> with a 
     * standard minor code of 1. However, the repository id of 
     * the exception is available in the <code>received_exception_id</code> 
     * attribute.
     * 
     * @see #received_exception_id
     */
    readonly attribute any received_exception;

    /**
     * Returns the repository id of the exception to be returned to 
     * the client.
     *
     * @see #received_exception
     * @see <a href="package-summary.html#unimpl">
     *     <code>PortableInterceptor</code> package comments for 
     *     limitations / unimplemented features</a>
     */
    readonly attribute CORBA::RepositoryId received_exception_id;

    /** 
     * Returns the <code>IOP.TaggedComponent</code> with the given ID from 
     * the profile selected for this request. 
     * <p>
     * If there is more than one component for a given component ID, it 
     * is undefined which component this operation returns. If there is 
     * more than one component for a given component ID, 
     * <code>get_effective_components</code> should be called instead. 
     * 
     * @param id The component id of the component which 
     *     is to be returned. 
     * @return The <code>IOP.TaggedComponent</code> obtained with the 
     *     given identifier.
     * @exception BAD_PARAM thrown, with a standard minor code of 28, if
     *     no component exists for the given component ID.
     * @see #get_effective_components
     */
    IOP::TaggedComponent get_effective_component 
      (in IOP::ComponentId id);

    /**
     * Returns an array of all tagged components with the given ID from the 
     * profile selected for this request. 
     * 
     * @param id The component id of the components which are to be returned. 
     * @return An array of <code>TaggedComponent</code> objects, each of 
     *     which contains the given identifier.
     * @exception BAD_PARAM thrown, with a standard minor code of 28, if
     *     no component exists for the given component ID.
     * @see #get_effective_component
     */
    IOP::TaggedComponentSeq get_effective_components 
      (in IOP::ComponentId id);

    /**
     * Returns the given policy in effect for this operation. 
     * 
     * @exception INV_POLICY thrown, with a standard minor code of 1, if the 
     *     policy type is not valid either because the specified type is 
     *     not supported by this ORB or because a policy object of that type 
     *     is not associated with this Object
     * @param type The policy type which specifies the policy to be 
     *     returned. 
     * @return The <code>CORBA.Policy</code> obtained with the given type.
     * @see <a href="package-summary.html#unimpl">
     *     <code>PortableInterceptor</code> package comments for 
     *     limitations / unimplemented features</a>
     */
    CORBA::Policy get_request_policy 
      (in CORBA::PolicyType type);

    /** 
     * Allows Interceptors to add service contexts to the request. 
     * <p>
     * There is no declaration of the order of the service contexts. 
     * They may or may not appear in the order that they are added. 
     *
     * @param service_context The <code>IOP.ServiceContext</code> to be 
     *     added to the request. 
     * @param replace Indicates the behavior of this operation when a 
     *     service context already exists with the given ID. If false, 
     *     then <code>BAD_INV_ORDER</code> with a standard minor code of 15 
     *     is thrown. If true, then the existing service context is 
     *     replaced by the new one.
     */
    void add_request_service_context (
      in IOP::ServiceContext service_context,
      in boolean replace);
  };

  // Should be type string
  typedef string ServerId ;

  // This should actually be the CORBA::ORBid type once that is available
  typedef string ORBId ;

  /** The name of an object adapter. This is unique only within
   * the scope of the ORB that created the object adapter.
   */
  typedef org::omg::CORBA::StringSeq AdapterName ;

  /** Type of an object id. This provides the identity of a particular
   * object that was created by an object adapter.
   */
  typedef org::omg::CORBA::OctetSeq ObjectId ;

  /**
   * Request Information, accessible to server-side request interceptors.
   * <p>
   * Some attributes and operations on <code>ServerRequestInfo</code> are not 
   * valid at all interception points.  The following table shows the validity 
   * of each attribute or operation.  If it is not valid, attempting to access 
   * it will result in a <code>BAD_INV_ORDER</code> being thrown with a 
   * standard minor code of 14.
   *
   *
   * <table border=1 summary="Shows the validity of each attribute or operation">
   *   <thead>
   *     <tr>
   *       <th>&nbsp;</th>
   *       <th id="rec_req_ser_con" valign="bottom">receive_request_<br>service_contexts</th>
   *       <th id="rec_req"  valign="bottom">receive_request</th>
   *       <th id="send_rep" valign="bottom">send_reply</th>
   *       <th id="send_exc" valign="bottom">send_exception</th>
   *       <th id="send_oth" valign="bottom">send_other</th>
   *     </tr>
   *   </thead>
   *  <tbody>
   *
   *
   * <tr>
   *   <td id="ri" colspan=6><i>Inherited from RequestInfo:</i></td>
   * </tr>
   *
   * <tr><th id="req_id"><p align="left">request_id</p></th>
   * <td headers="ri req_id rec_req_ser_con">yes</td> 
   * <td headers="ri req_id rec_req">yes</td> 
   * <td headers="ri req_id send_rep">yes</td> 
   * <td headers="ri req_id send_exc">yes</td> 
   * <td headers="ri req_id send_oth">yes</td></tr>
   *
   * <tr><th id="op"><p align="left">operation</p></th>
   * <td headers="ri op rec_req_ser_con">yes</td> 
   * <td headers="ri op rec_req">yes</td> 
   * <td headers="ri op send_rep">yes</td> 
   * <td headers="ri op send_exc">yes</td> 
   * <td headers="ri op send_oth">yes</td></tr>
   *
   * <tr><th id="args"><p align="left">arguments</p></th>
   * <td headers="ri args rec_req_ser_con">no </td> 
   * <td headers="ri args rec_req">yes<sub>1</sub></td>
   * <td headers="ri args send_rep">yes</td> 
   * <td headers="ri args send_exc">no<sub>2</sub></td>
   * <td headers="ri args send_oth">no<sub>2</sub>
   * </td></tr>
   *
   * <tr><th id="exps"><p align="left">exceptions</p></th>
   * <td headers="ri exps rec_req_ser_con">no </td> 
   * <td headers="ri exps rec_req">yes</td> 
   * <td headers="ri exps send_rep">yes</td> 
   * <td headers="ri exps send_exc">yes</td> 
   * <td headers="ri exps send_oth">yes</td></tr>
   *
   * <tr><th id="contexts"><p align="left">contexts</p></th>
   * <td headers="ri contexts rec_req_ser_con">no </td> 
   * <td headers="ri contexts rec_req">yes</td> 
   * <td headers="ri contexts send_rep">yes</td> 
   * <td headers="ri contexts send_exc">yes</td> 
   * <td headers="ri contexts send_oth">yes</td></tr>
   *
   * <tr><th id="op_con"><p align="left">operation_context</p></th>
   * <td headers="ri op_con rec_req_ser_con">no </td> 
   * <td headers="ri op_con rec_req">yes</td> 
   * <td headers="ri op_con send_rep">yes</td> 
   * <td headers="ri op_con send_exc">no </td> 
   * <td headers="ri op_con send_oth">no </td>
   * </tr>
   * 
   * <tr><th id="result"><p align="left">result</p></th>
   * <td headers="ri result rec_req_ser_con">no </td> 
   * <td headers="ri result rec_req">no </td> 
   * <td headers="ri result send_rep">yes</td> 
   * <td headers="ri result send_exc">no </td> 
   * <td headers="ri result send_oth">no </td>
   * </tr>
   *
   * <tr><th id="res_ex"><p align="left">response_expected</p></th>
   * <td headers="ri res_ex rec_req_ser_con">yes</td> 
   * <td headers="ri res_ex rec_req">yes</td> 
   * <td headers="ri res_ex send_rep">yes</td> 
   * <td headers="ri res_ex send_exc">yes</td> 
   * <td headers="ri res_ex send_oth">yes</td></tr>
   *
   * <tr><th id="syn_scp"><p align="left">sync_scope</p></th>
   * <td headers="ri syn_scp rec_req_ser_con">yes</td> 
   * <td headers="ri syn_scp rec_req">yes</td> 
   * <td headers="ri syn_scp send_rep">yes</td> 
   * <td headers="ri syn_scp send_exc">yes</td> 
   * <td headers="ri syn_scp send_oth">yes</td></tr>
   * 
   *    <tr><td><b>request_id</b></td>
   *    <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>operation</b></td>
   *    <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>arguments</b></td>
   *    <td>no </td> <td>yes<sub>1</sub></td>
   *                              <td>yes</td> <td>no<sub>2</sub></td> 
   *                                                        <td>no<sub>2</sub>
   *                                                        </td></tr>
   * 
   *    <tr><td><b>exceptions</b></td>
   *    <td>no </td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>contexts</b></td>
   *    <td>no </td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>operation_context</b></td>
   *    <td>no </td> <td>yes</td> <td>yes</td> <td>no </td> <td>no </td></tr>
   * 
   *    <tr><td><b>result</b></td>
   *    <td>no </td> <td>no </td> <td>yes</td> <td>no </td> <td>no </td></tr>
   * 
   *    <tr><td><b>response_expected</b></td>
   *    <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>sync_scope</b></td>
   *    <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>reply_status</b></td>
   *    <td>no </td> <td>no </td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>forward_reference</b></td>
   *    <td>no </td> <td>no </td> <td>no </td> <td>no </td> <td>yes<sub>2</sub>
   * 								</td></tr>
   * 
   *    <tr><td><b>get_slot</b></td>
   *    <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>get_request_service_context</b></td>
   *    <td>yes</td> <td>no </td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>get_reply_service_context</b></td>
   *    <td>no </td> <td>no </td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr>
   *      <td colspan=6><i>ServerRequestInfo-specific:</i></td>
   *    </tr>
   * 
   *    <tr><td><b>sending_exception</b></td>
   *    <td>no </td> <td>no </td> <td>no </td> <td>yes</td> <td>no </td></tr>
   * 
   *    <tr><td><b>object_id</b></td>
   *    <td>no </td> <td>yes</td> <td>yes</td> <td>yes<sub>3</sub></td> 
   * 						       <td>yes<sub>3</sub>
   * 						                </td></tr>
   * 
   *    <tr><td><b>adapter_id</b></td>
   *    <td>no </td> <td>yes</td> <td>yes</td> <td>yes<sub>3</sub></td> 
   * 						       <td>yes<sub>3</sub>
   * 								</td></tr>
   * 
   *    <tr><td><b>server_id</b></td>
   *    <td>no </td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   *
   *    <tr><td><b>orb_id</b></td>
   *    <td>no </td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   *
   *    <tr><td><b>adapter_name</b></td>
   *    <td>no </td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   *
   *    <tr><td><b>target_most_derived_interface</b></td>
   *    <td>no </td> <td>yes</td> <td>no<sub>4</sub></td> 
   * 					  <td>no<sub>4</sub></td> 
   * 						       <td>no<sub>4</sub>
   * 							       </td></tr>
   * 
   *    <tr><td><b>get_server_policy</b></td>
   *    <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>set_slot</b></td>
   *    <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   * 
   *    <tr><td><b>target_is_a</b></td>
   *    <td>no </td> <td>yes</td> <td>no<sub>4</sub></td> 
   * 					  <td>no<sub>4</sub></td> 
   * 						       <td>no<sub>4</sub>
   * 							       </td></tr>
   * 
   *    <tr><td><b>add_reply_service_context</b></td>
   *    <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td> <td>yes</td></tr>
   *   </tbody>
   * </table>
   *
   * <ol>
   *   <li>When <code>ServerRequestInfo</code> is passed to 
   *       <code>receive_request</code>, there is an entry in the list for 
   *       every argument, whether in, inout, or out. But only the in and 
   *       inout arguments will be available.</li>
   *   <li>If the <code>reply_status</code> attribute is not 
   *       <code>LOCATION_FORWARD</code>, accessing this attribute will throw
   *       <code>BAD_INV_ORDER</code> with a standard minor code of 14.</li>
   *   <li>If the servant locator caused a location forward, or thrown an 
   *       exception, this attribute/operation may not be available in this 
   *       interception point. <code>NO_RESOURCES</code> with a standard minor 
   *       code of 1 will be thrown if it is not available.</li>
   *   <li>The operation is not available in this interception point because 
   *       the necessary information requires access to the target object's 
   *       servant, which may no longer be available to the ORB. For example, 
   *       if the object's adapter is a POA that uses a 
   *       <code>ServantLocator</code>, then the ORB invokes the interception 
   *       point after it calls <code>ServantLocator.postinvoke()</code>.</li>
   * </ol>
   *
   * @see ServerRequestInterceptor
   */
  local interface ServerRequestInfo : RequestInfo {

    /**
     * Returns an any which contains the exception to be returned to 
     * the client. 
     * <p>
     * If the exception is a user exception which cannot be inserted into 
     * an any (e.g., it is unknown or the bindings don't provide the 
     * <code>TypeCode</code>), then this attribute will be an any 
     * containing the system exception <code>UNKNOWN</code> with a 
     * standard minor code of 1.
     *
     * @see <a href="package-summary.html#unimpl">
     *     <code>PortableInterceptor</code> package comments for 
     *     limitations / unimplemented features</a>
     */
    readonly attribute any sending_exception;

    /**
     * Returns the opaque <code>object_id</code> describing the target of 
     * the operation invocation.
     */
    readonly attribute ObjectId object_id;

    /** 
     * Returns the opaque identifier for the object adapter.
     */
    readonly attribute CORBA::OctetSeq adapter_id;

    /**
     * Returns the server ID that was specified on ORB::init using the -ORBServerId
     * argument.
     */
    readonly attribute ServerId server_id ;

    /** 
     * Returns the ID that was used to create the ORB.
     */
    readonly attribute ORBId orb_id ;

    /** 
     * Returns the sequence of strings that identifies the object
     * adapter instance that is handling this request.
     */
    readonly attribute AdapterName adapter_name ;

    /**
     * Returns the repository id for the most derived interface of the 
     * servant.
     */
    readonly attribute CORBA::RepositoryId 
      target_most_derived_interface;

    /**
     * Returns the policy in effect for this operation for the given 
     * policy type. The returned <code>CORBA.Policy</code> object shall 
     * only be a policy whose type was registered via 
     * <code>register_policy_factory</code>. 
     * 
     * @param type The <code>CORBA.PolicyType</code> which specifies the 
     *     policy to be returned. 
     * @return The <code>CORBA.Policy</code> obtained with the given 
     *     policy type.
     * @exception INV_POLICY thrown, with a standard minor code of 2, if
     *     a policy for the given type was not registered via 
     *     <code>register_policy_factory</code>.
     * @see ORBInitInfo#register_policy_factory
     */
    CORBA::Policy get_server_policy 
      (in CORBA::PolicyType type);

    /**
     * Allows an Interceptor to set a slot in the 
     * <code>PortableInterceptor.Current</code> that is in the scope of 
     * the request. If data already exists in that slot, it will be 
     * overwritten. 
     * 
     * @param id The id of the slot. 
     * @param data The data, in the form of an any, to store in that slot.
     * @exception InvalidSlot thrown if the ID does not define an allocated 
     *     slot. 
     * @see Current
     */
    void set_slot (in SlotId id, in any data) raises (InvalidSlot);

    /**
     * Returns true if the servant is the given repository id, 
     * false if it is not. 
     *
     * @param id The caller wants to know if the servant is this 
     *     repository id. 
     * @return Is the servant the given RepositoryId?
     */
    boolean target_is_a (in CORBA::RepositoryId id);

    /**
     * Allows Interceptors to add service contexts to the request. 
     * <p>
     * There is no declaration of the order of the service contexts. 
     * They may or may not appear in the order that they are added. 
     *
     * @param service_context The <code>IOP.ServiceContext</code> to add to 
     *     the reply. 
     * @param replace Indicates the behavior of this operation when a 
     *     service context already exists with the given ID. If false, 
     *     then <code>BAD_INV_ORDER</code> with a standard minor code of 15 
     *     is thrown. If true, then the existing service context is 
     *     replaced by the new one.
     * @exception BAD_INV_ORDER thrown, with a standard minor code of 15, if
     *     replace is false and a service context already exists with the
     *     given ID.
     */
    void add_reply_service_context (
      in IOP::ServiceContext service_context,
      in boolean replace);
  };

  /**
   * Client-side request interceptor.
   * <p>
   * A request Interceptor is designed to intercept the flow of a 
   * request/reply sequence through the ORB at specific points so that 
   * services can query the request information and manipulate the service 
   * contexts which are propagated between clients and servers. The primary 
   * use of request Interceptors is to enable ORB services to transfer 
   * context information between clients and servers. There are two types 
   * of request Interceptors: client-side and server-side. 
   * <p>
   * To write a client-side Interceptor, implement the 
   * <code>ClientRequestInterceptor</code> interface. 
   *
   * @see ClientRequestInfo
   */
  local interface ClientRequestInterceptor : Interceptor {
    /**
     * Allows an Interceptor to query request information and modify the 
     * service context before the request is sent to the server.
     * <p>
     * This interception point may throw a system exception. If it does, 
     * no other Interceptors' <code>send_request</code> operations are called. 
     * Those Interceptors on the Flow Stack are popped and their 
     * <code>receive_exception</code> interception points are called. This 
     * interception point may also throw a <code>ForwardRequest</code> 
     * exception. If an Interceptor throws this exception, no other 
     * Interceptors' <code>send_request</code> operations are 
     * called. Those Interceptors on the Flow Stack are popped and their 
     * <code>receive_other</code> interception points are called. 
     * <p>
     * Compliant Interceptors shall properly follow completion_status 
     * semantics if they throw a system exception from this interception 
     * point. The <code>completion_status</code> shall be 
     * <code>COMPLETED_NO</code>.
     *
     * @param ri Information about the current request being intercepted.
     * @exception ForwardRequest If thrown, indicates to the ORB that a
     *     retry of the request should occur with the new object given in
     *     the exception.
     */
    void send_request  (in ClientRequestInfo ri) raises (ForwardRequest);

    /**
     * Allows an Interceptor to query information during a Time-Independent 
     * Invocation (TII) polling get reply sequence. 
     * <p>
     * With TII, an application may poll for a response to a request sent 
     * previously by the polling client or some other client. This poll is 
     * reported to Interceptors through the <code>send_poll</code> 
     * interception point and the response is returned through the 
     * <code>receive_reply</code> or <code>receive_exception</code> 
     * interception points.  If the response is not available before the
     * poll time-out expires, the system exception <code>TIMEOUT</code> is
     * thrown and <code>receive_exception</code> is called with this 
     * exception. 
     * <p>
     * This interception point may throw a system exception. If it does, 
     * no other Interceptors' <code>send_poll</code> operations are 
     * called. Those Interceptors on the Flow Stack are popped and their 
     * <code>receive_exception</code> interception points are called. 
     * <p>
     * Compliant Interceptors shall properly follow 
     * <code>completion_status</code> semantics if they throw a system 
     * exception from this interception point. The completion_status shall be 
     * <code>COMPLETED_NO</code>.
     * 
     * @param ri Information about the current request being intercepted.
     * @exception TIMEOUT thrown if the response is not available before 
     *     the poll time-out expires
     */
    void send_poll (in ClientRequestInfo ri);

    /**
     * Allows an Interceptor to query the information on a reply after it 
     * is returned from the server and before control is returned to the 
     * client. 
     * <p>
     * This interception point may throw a system exception. If it does, 
     * no other Interceptors' <code>receive_reply</code> operations are 
     * called. The remaining Interceptors in the Flow Stack shall have 
     * their <code>receive_exception</code> interception point called. 
     * <p>
     * Compliant Interceptors shall properly follow 
     * <code>completion_status</code> semantics if they throw a system 
     * exception from this interception point. The 
     * <code>completion_status</code> shall be <code>COMPLETED_YES</code>.
     *
     * @param ri Information about the current request being intercepted.
     */
    void receive_reply (in ClientRequestInfo ri);

    /**
     * Indicates to the interceptor that an exception occurred.  Allows
     * an Interceptor to query the exception's information before it is 
     * thrown to the client.
     * <p>
     * This interception point may throw a system exception. This has the 
     * effect of changing the exception which successive Interceptors 
     * popped from the Flow Stack receive on their calls to 
     * <code>receive_exception</code>. The exception thrown to the client 
     * will be the last exception thrown by an Interceptor, or the original 
     * exception if no Interceptor changes the exception. 
     * <p>
     * This interception point may also throw a <code>ForwardRequest</code> 
     * exception.  If an Interceptor throws this exception, no other 
     * Interceptors' <code>receive_exception</code> operations are called. 
     * The remaining Interceptors in the Flow Stack are popped and have their 
     * <code>receive_other</code> interception point called. 
     * <p>
     * If the <code>completion_status</code> of the exception is not 
     * <code>COMPLETED_NO</code>, then it is inappropriate for this 
     * interception point to throw a <code>ForwardRequest</code> exception. 
     * The request s at-most-once semantics would be lost. 
     * <p>
     * Compliant Interceptors shall properly follow 
     * <code>completion_status</code> semantics if they throw a system 
     * exception from this interception point. If the original exception is 
     * a system exception, the <code>completion_status</code> of the new 
     * exception shall be the same as on the original. If the original 
     * exception is a user exception, then the <code>completion_status</code> 
     * of the new exception shall be <code>COMPLETED_YES</code>. 
     * <p>
     * Under some conditions, depending on what policies are in effect, an 
     * exception (such as <code>COMM_FAILURE</code>) may result in a retry 
     * of the request. While this retry is a new request with respect to 
     * Interceptors, there is one point of correlation between the original 
     * request and the retry: because control has not returned to the 
     * client, the <code>PortableInterceptor.Current</code> for both the 
     * original request and the retrying request is the same.
     *
     * @param ri Information about the current request being intercepted.
     * @exception ForwardRequest If thrown, indicates to the ORB that a
     *     retry of the request should occur with the new object given in
     *     the exception.
     */
    void receive_exception (in ClientRequestInfo ri) raises (ForwardRequest);

    /**
     * Allows an Interceptor to query the information available when a 
     * request results in something other than a normal reply or an 
     * exception. For example, a request could result in a retry 
     * (e.g., a GIOP Reply with a <code>LOCATION_FORWARD</code> status was 
     * received); or on asynchronous calls, the reply does not immediately 
     * follow the request, but control shall return to the client and an 
     * ending interception point shall be called. 
     * <p>
     * For retries, depending on the policies in effect, a new request may or 
     * may not follow when a retry has been indicated. If a new request does 
     * follow, while this request is a new request, with respect to 
     * Interceptors, there is one point of correlation between the original 
     * request and the retry: because control has not returned to the client, 
     * the request scoped <code>PortableInterceptor.Current</code> for both 
     * the original request and the retrying request is the same.  
     * <p>
     * This interception point may throw a system exception. If it does, no 
     * other Interceptors' <code>receive_other</code> operations are called. 
     * The remaining Interceptors in the Flow Stack are popped and have 
     * their <code>receive_exception</code> interception point called.
     * <p>
     * This interception point may also throw a <code>ForwardRequest</code> 
     * exception.  If an Interceptor throws this exception, successive 
     * Interceptors' <code>receive_other</code> operations are called with 
     * the new information provided by the <code>ForwardRequest</code> 
     * exception. 
     * <p>
     * Compliant Interceptors shall properly follow 
     * <code>completion_status</code> semantics if they throw a system 
     * exception from this interception point. The 
     * <code>completion_status</code> shall be <code>COMPLETED_NO</code>. 
     * If the target invocation had completed, this interception point 
     * would not be called.
     * 
     * @param ri Information about the current request being intercepted.
     * @exception ForwardRequest If thrown, indicates to the ORB that a
     *     retry of the request should occur with the new object given in
     *     the exception.
     */
    void receive_other (in ClientRequestInfo ri) raises (ForwardRequest);
  };

  /**
   * Server-side request interceptor.
   * <p>
   * A request Interceptor is designed to intercept the flow of a 
   * request/reply sequence through the ORB at specific points so that 
   * services can query the request information and manipulate the service 
   * contexts which are propagated between clients and servers. The primary 
   * use of request Interceptors is to enable ORB services to transfer 
   * context information between clients and servers. There are two types 
   * of request Interceptors: client-side and server-side. 
   * <p>
   * To write a server-side Interceptor, implement the 
   * ServerRequestInterceptor interface.
   *
   * @see ServerRequestInfo
   */
  local interface ServerRequestInterceptor : Interceptor {
    /**
     * Allows the interceptor to process service context information.
     * <p>
     * At this interception point, Interceptors must get their service 
     * context information from the incoming request transfer it to 
     * <code>PortableInterceptor.Current</code>'s slots.  
     * <p>
     * This interception point is called before the servant manager is called. 
     * Operation parameters are not yet available at this point. This 
     * interception point may or may not execute in the same thread as 
     * the target invocation. 
     * <p>
     * This interception point may throw a system exception. If it does, 
     * no other Interceptors' <code>receive_request_service_contexts</code> 
     * operations are called. Those Interceptors on the Flow Stack are 
     * popped and their <code>send_exception</code> interception points are 
     * called. 
     * <p>
     * This interception point may also throw a <code>ForwardRequest</code> 
     * exception.  If an Interceptor throws this exception, no other 
     * Interceptors' <code>receive_request_service_contexts</code> operations 
     * are called. Those Interceptors on the Flow Stack are popped and 
     * their <code>send_other</code> interception points are called. 
     * <p>
     * Compliant Interceptors shall properly follow 
     * <code>completion_status</code> semantics if they throw a system 
     * exception from this interception point. The 
     * <code>completion_status</code> shall be COMPLETED_NO.
     *
     * @param ri Information about the current request being intercepted.
     * @exception ForwardRequest If thrown, indicates to the ORB that a
     *     retry of the request should occur with the new object given in
     *     the exception.
     */
    void receive_request_service_contexts (in ServerRequestInfo ri) 
      raises (ForwardRequest);

    /**
     * Allows an Interceptor to query request information after all the 
     * information, including operation parameters, are available. This 
     * interception point shall execute in the same thread as the target 
     * invocation.
     * <p>
     * In the DSI model, since the parameters are first available when 
     * the user code calls <code>arguments</code>, <code>receive_request</code>
     * is called from within <code>arguments</code>. It is possible that 
     * <code>arguments</code> is not called in the DSI model. The target 
     * may call <code>set_exception</code> before calling 
     * <code>arguments</code>. The ORB shall guarantee that 
     * <code>receive_request</code> is called once, either through 
     * <code>arguments</code> or through <code>set_exception</code>. If it 
     * is called through <code>set_exception</code>, requesting the 
     * arguments will result in <code>NO_RESOURCES</code> being thrown with 
     * a standard minor code of 1. 
     * <p>
     * This interception point may throw a system exception. If it does, no 
     * other Interceptors' <code>receive_request</code> operations are 
     * called. Those Interceptors on the Flow Stack are popped and their 
     * <code>send_exception</code> interception points are called. 
     * <p>
     * This interception point may also throw a <code>ForwardRequest</code> 
     * exception.  If an Interceptor throws this exception, no other 
     * Interceptors' <code>receive_request</code> operations are called. 
     * Those Interceptors on the Flow Stack are popped and their 
     * <code>send_other</code> interception points are called.
     * <p>
     * Compliant Interceptors shall properly follow 
     * <code>completion_status</code> semantics if they throw a system 
     * exception from this interception point. The 
     * <code>completion_status</code> shall be <code>COMPLETED_NO</code>.
     *
     * @param ri Information about the current request being intercepted.
     * @exception ForwardRequest If thrown, indicates to the ORB that a
     *     retry of the request should occur with the new object given in
     *     the exception.
     */
    void receive_request (in ServerRequestInfo ri) raises (ForwardRequest);

    /**
     * Allows an Interceptor to query reply information and modify the 
     * reply service context after the target operation has been invoked 
     * and before the reply is returned to the client. This interception 
     * point shall execute in the same thread as the target invocation. 
     * <p>
     * This interception point may throw a system exception. If it does, 
     * no other Interceptors' <code>send_reply</code> operations are called. 
     * The remaining Interceptors in the Flow Stack shall have their 
     * <code>send_exception</code> interception point called. 
     * <p>
     * Compliant Interceptors shall properly follow 
     * <code>completion_status</code> semantics if they throw a 
     * system exception from this interception point. The 
     * <code>completion_status</code> shall be <code>COMPLETED_YES</code>.
     *
     * @param ri Information about the current request being intercepted.
     */
    void send_reply (in ServerRequestInfo ri);

    /**
     * Allows an Interceptor to query the exception information and modify 
     * the reply service context before the exception is thrown to the client. 
     * When an exception occurs, this interception point is called. This 
     * interception point shall execute in the same thread as the target 
     * invocation. 
     * <p>
     * This interception point may throw a system exception. This has the 
     * effect of changing the exception which successive Interceptors 
     * popped from the Flow Stack receive on their calls to 
     * <code>send_exception</code>. The exception thrown to the client will 
     * be the last exception thrown by an Interceptor, or the original 
     * exception if no Interceptor changes the exception. 
     * <p>
     * This interception point may also throw a <code>ForwardRequest</code> 
     * exception.  If an Interceptor throws this exception, no other 
     * Interceptors' <code>send_exception</code> operations are called. The 
     * remaining Interceptors in the Flow Stack shall have their 
     * <code>send_other</code> interception points called. 
     * <p>
     * If the <code>completion_status</code> of the exception is not 
     * <code>COMPLETED_NO</code>, then it is inappropriate for this 
     * interception point to throw a <code>ForwardRequest</code> exception. 
     * The request's at-most-once semantics would be lost. 
     * <p>
     * Compliant Interceptors shall properly follow 
     * <code>completion_status</code> semantics if they throw a system 
     * exception from this interception point. If the original exception 
     * is a system exception, the <code>completion_status</code> of the new 
     * exception shall be the same as on the original. If the original 
     * exception is a user exception, then the <code>completion_status</code> 
     * of the new exception shall be <code>COMPLETED_YES</code>.
     *
     * @param ri Information about the current request being intercepted.
     * @exception ForwardRequest If thrown, indicates to the ORB that a
     *     retry of the request should occur with the new object given in
     *     the exception.
     */
    void send_exception (in ServerRequestInfo ri) raises (ForwardRequest);

    /**
     * Allows an Interceptor to query the information available when a 
     * request results in something other than a normal reply or an 
     * exception. For example, a request could result in a retry 
     * (e.g., a GIOP Reply with a <code>LOCATION_FORWARD</code> status was 
     * received). This interception point shall execute in the same thread 
     * as the target invocation. 
     * <p>
     * This interception point may throw a system exception. If it does, 
     * no other Interceptors' <code>send_other</code> operations are called. 
     * The remaining Interceptors in the Flow Stack shall have their 
     * <code>send_exception</code> interception points called. 
     * <p>
     * This interception point may also throw a <code>ForwardRequest</code> 
     * exception.  If an Interceptor throws this exception, successive 
     * Interceptors' <code>send_other</code> operations are called with 
     * the new information provided by the <code>ForwardRequest</code> 
     * exception. 
     * <p>
     * Compliant Interceptors shall properly follow 
     * <code>completion_status</code> semantics if they throw a system 
     * exception from this interception point. The 
     * <code>completion_status</code> shall be <code>COMPLETED_NO</code>.
     *
     * @param ri Information about the current request being intercepted.
     * @exception ForwardRequest If thrown, indicates to the ORB that a
     *     retry of the request should occur with the new object given in
     *     the exception.
     */
    void send_other (in ServerRequestInfo ri) raises (ForwardRequest);
  };

  /** The object reference factory.  This provides the capability of
  * creating an object reference.
  */
  abstract valuetype ObjectReferenceFactory {
    /** make_object creates a CORBA object reference according
    * to the data in this template, with the given repository ID and
    * object ID.
    */
    Object make_object( in string repositoryId, in ObjectId object_id ) ;
  } ;
    
  /** The object reference template.  An instance of this must
   * exist for each object adapter created in an ORB.  The server_id,
   * orb_id, and adapter_name attributes uniquely identify this template
   * within the scope of an IMR.  Note that adapter_id is similarly unique
   * within the same scope, but it is opaque, and less useful in many
   * cases.
   */
  abstract valuetype ObjectReferenceTemplate : ObjectReferenceFactory {

    readonly attribute ServerId server_id ;

    readonly attribute ORBId orb_id ;

    readonly attribute AdapterName adapter_name ;
  } ;

  /** Sequence of object reference templates is used for reporting state
   * changes that do not occur on the adapter manager.
   */
  typedef sequence<ObjectReferenceTemplate> ObjectReferenceTemplateSeq ;

  /** Adapter manager identifier.  Every object adapter has an adapter manager,
   * indicated in this API only through the ID.  A group of object adapter
   * instances may share the same adapter manager, in which case state transitions
   * reported for the adapter manager are observed by all object adapters with the
   * same adapter manager ID.
   */
  typedef long AdapterManagerId ;

  /** Type of object adapter state.  State changes are reported either to
   * the object adapter or to the adapter manager.
   */
  typedef short AdapterState ;

  /** Object adapter state that holds requests temporarily until the 
   * state is changed.
   */
  const AdapterState HOLDING	    = 0 ;

  /** Object adapter state that indicates normal request processing.
   */
  const AdapterState ACTIVE	    = 1 ;

  /** Object adapter state that causes all requests to be discarded.
   */
  const AdapterState DISCARDING   = 2 ;

  /** Object adapter state that causes all requests to be discarded.
   * This state indicates that the adapter is shutting down.
   */
  const AdapterState INACTIVE     = 3 ;

  /** Object adapter state indicating that the adapter has been destroyed.
   */
  const AdapterState NON_EXISTENT = 4 ;

  /**
   * Provides the server-side ORB service with access to the applicable 
   * policies during IOR construction and the ability to add components. 
   * The ORB passes an instance of its implementation of this interface as 
   * a parameter to <code>IORInterceptor.establish_components</code>.
   *
   * @see IORInterceptor
   */
  local interface IORInfo {

    /**
     * Allows an ORB service implementation to determine what server side 
     * policy of a particular type is in effect for an IOR being 
     * constructed.  When the IOR being constructed is for an object 
     * implemented using a POA, all Policy objects passed to the 
     * <code>PortableServer.POA.create_POA</code> call that created that 
     * POA are accessable via <code>get_effective_policy</code>. 
     * <p>
     * If a policy for the given type is not known to the ORB, then this 
     * operation will throw <code>INV_POLICY</code> with a standard minor 
     * code of 2. 
     * 
     * @param type an int specifying the type of policy to return. 
     * @return The effective <code>CORBA.Policy</code> object of the 
     *     requested type. If the given policy type is known, but no policy 
     *     of that type is in effect, then this operation will return a 
     *     nil object reference.
     */
    CORBA::Policy get_effective_policy 
      (in CORBA::PolicyType type);

    /**
     * A portable ORB service implementation calls 
     * <code>add_ior_component</code> from its implementation of 
     * <code>establish_components</code> to add a tagged component to the 
     * set which will be included when constructing IORs. The components in 
     * this set will be included in all profiles. 
     * <p>
     * Any number of components may exist with the same component ID. 
     * 
     * @param tagged_component The IOP.TaggedComponent to add.
     */
    void add_ior_component 
      (in IOP::TaggedComponent tagged_component);

    /**
     * A portable ORB service implementation calls 
     * <code>add_ior_component_to_profile</code> from its implementation of 
     * <code>establish_components</code> to add a tagged component to the 
     * set which will be included when constructing IORs. The components in 
     * this set will be included in the specified profile. 
     * <p>
     * Any number of components may exist with the same component ID. 
     * 
     * @param tagged_component The <code>IOP.TaggedComponent</code> to add. 
     * @param profile_id The profile id of the profile to 
     *     which this component will be added.
     * @exception BAD_PARAM thrown, with a standard minor code of 29, if the 
     *     given profile ID does not define a known profile or it is 
     *     impossible to add components to that profile.
     */
    void add_ior_component_to_profile (
      in IOP::TaggedComponent tagged_component,
      in IOP::ProfileId profile_id);

    /** Return the adapter manager id of the object adapter
     * that was just created and is running IOR interceptors.
     */
    readonly attribute AdapterManagerId manager_id ;

    /** Return the adapter state of the object adapter
     * that was just created and is running IOR interceptors.
     */
    readonly attribute AdapterState state ;

    /** Return the object reference template of the object adapter
     * that was just created and is running IOR interceptors.
     */
    readonly attribute ObjectReferenceTemplate adapter_template ;

    /** On read, returns the current factory that will be used to create
     * object references for the object adapter that was just created
     * and is running IOR interceptors.  By default, this factory is the same
     * as the value of the adapter_template attribute.  The current_factory 
     * may also be set to another object reference template inside an
     * IORInterceptor_3_0.
     */
    attribute ObjectReferenceFactory current_factory ;
  };

  /**
   * Interceptor used to establish tagged components in the profiles within 
   * an IOR.
   * <p>
   * In some cases, a portable ORB service implementation may need to add 
   * information describing the server's or object's ORB service related 
   * capabilities to object references in order to enable the ORB service 
   * implementation in the client to function properly. 
   * <p>
   * This is supported through the <code>IORInterceptor</code> and 
   * <code>IORInfo</code> interfaces. 
   *
   * @see IORInfo
   */
  local interface IORInterceptor : Interceptor {
    /**
     * A server side ORB calls the <code>establish_components</code> 
     * operation on all registered <code>IORInterceptor</code> instances 
     * when it is assembling the list of components that will be included 
     * in the profile or profiles of an object reference. This operation 
     * is not necessarily called for each individual object reference. 
     * In the case of the POA, this operation is called each time POA::create_POA
     * is called.  In any case, <code>establish_components</code> is 
     * guaranteed to be called at least once for each distinct set of 
     * server policies. 
     * <p>
     * An implementation of <code>establish_components</code> must not 
     * throw exceptions. If it does, the ORB shall ignore the exception 
     * and proceed to call the next IOR Interceptor's 
     * <code>establish_components</code> operation. 
     *
     * @param info The <code>IORInfo</code> instance used by the ORB 
     *     service to query applicable policies and add components to be 
     *     included in the generated IORs.
     */
    void establish_components (in IORInfo info);
  };

  local interface IORInterceptor_3_0 : IORInterceptor {
    /** The components_established method is invoked on all registered 
     * IORInterceptor_3_0 instances after establish_components
     * has been invoked on all registered IORInterceptor instances.
     * The adapter_template is available in info during this call.
     * The current_factory may be get or set in info during this call.
     * <p>
     * Any exception thrown from this method is handled by the Object 
     * Adapter that called this interceptor.  In the case of the POA,
     * an exception results in a OBJ_ADAPTER exception with an OMG
     * standard minor code of 6.
     * @param info The IORInfo for the object adapter being created.
     */
    void components_established( in IORInfo info ) ;

    /** Called whenever the state of an adapter manager changes.
     * For the POA, that is the POAManager.  If the state change
     * is reported through <code>adapter_manager_state_changed</code>,
     * it is not reported through <code>adapter_state_changed</code>.
     * @param id the adapter manager id of the adapter manager that 
     * changed state
     * @param state the new state of the adapter manager
     */
    void adapter_manager_state_changed( in AdapterManagerId id, 
	in AdapterState state ) ;

    /** Called whenever the state of an object adapter changes, and
     * the state change is not caused by an adapter manager.  Such
     * changes are reported to all registered <code>IORInterceptor_3_0</code> 
     * instances.
     * @param templates the sequence of <code>ObjectReferenceTemplate</code> instances
     *     on which this state change occurred.
     * @param state the new <code>AdapterState</code> shared by all of the templates.
     */
    void adapter_state_changed( in ObjectReferenceTemplateSeq templates, 
	in AdapterState state ) ;
  };

  /**
   * Enables policy types to be constructed using 
   * <code>CORBA.ORB.create_policy</code>.
   * <p>
   * A portable ORB service implementation registers an instance of the 
   * <code>PolicyFactory</code> interface during ORB initialization in order 
   * to enable its policy types to be constructed using 
   * <code>CORBA.ORB.create_policy</code>. The POA is required to preserve 
   * any policy which is registered with <code>ORBInitInfo</code> in this 
   * manner.
   *
   * @see ORBInitInfo#register_policy_factory
   */
  local interface PolicyFactory
  {
    /**
     * Returns an instance of the appropriate interface derived from 
     * <code>CORBA.Policy</code> whose value corresponds to the 
     * specified any. 
     * <p>
     * The ORB calls <code>create_policy</code> on a registered 
     * <code>PolicyFactory</code> instance when 
     * <code>CORBA.ORB.create_policy</code> is called for the 
     * <code>PolicyType</code> under which the <code>PolicyFactory</code> has 
     * been registered. The <code>create_policy</code> operation then 
     * returns an instance of the appropriate interface derived from 
     * <code>CORBA.Policy</code> whose value corresponds to the specified 
     * any. If it cannot, it shall throw an exception as described for 
     * <code>CORBA.ORB.create_policy</code>. 
     * 
     * @param type An int specifying the type of policy being created. 
     * @param value An any containing data with which to construct the 
     *     <code>CORBA.Policy</code>. 
     * @return A <code>CORBA.Policy</code> object of the specified type and
     *     value.
     */
    CORBA::Policy create_policy 
      (in CORBA::PolicyType type, in any value)
      raises (CORBA::PolicyError);
  };

  /** 
   * Passed to each <code>ORBInitializer</code>, allowing it to
   * to register interceptors and perform other duties while the ORB is 
   * initializing.
   * <p>
   * The <code>ORBInitInfo</code> object is only valid during 
   * <code>ORB.init</code>.  If a service keeps a reference to its 
   * <code>ORBInitInfo</code> object and tries to use it after 
   * <code>ORB.init</code> returns, the object no longer exists and an 
   * <code>OBJECT_NOT_EXIST</code> exception shall be thrown.
   *
   * @see ORBInitializer
   */
  local interface ORBInitInfo {

    /** Object id, represented as a String */
    typedef string ObjectId;

    /**
     * Only one Interceptor of a given name can be registered with the 
     * ORB for each Interceptor type. If an attempt is made to register a 
     * second Interceptor with the same name, DuplicateName is thrown. 
     * <p>
     * An Interceptor may be anonymous, i.e., have an empty string as the 
     * name attribute. Any number of anonymous Interceptors may be 
     * registered with the ORB so, if the Interceptor being registered 
     * is anonymous, the registration operation will not throw 
     * <code>DuplicateName</code>.
     */
    exception DuplicateName {
      /** 
       * The name for which there was already an interceptor registered.
       */
      string name;
    };

    /** 
     * This exception is thrown by 
     * <code>register_initial_reference</code> and 
     * <code>resolve_initial_references</code>. 
     * <code>register_initial_reference</code> throws <code>InvalidName</code>
     * if:
     * <ul>
     *   <li>this operation is called with an empty string id; or</li>
     *   <li>this operation is called with an id that is already registered,
     *       including the default names defined by OMG.</li>
     * </ul>
     * <code>resolve_initial_references</code> throws
     * <code>InvalidName</code> if the name to be resolved is invalid.
     */
    exception InvalidName {};

    /** 
     * Returns the arguments passed to <code>ORB.init</code>.  They may or
     * may not contain the ORB's arguments.
     */
    readonly attribute CORBA::StringSeq arguments;

    /** 
     * Returns the ID of the ORB being initialized.
     */
    readonly attribute string orb_id;

    /** 
     * Returns the <code>IOP.CodecFactory</code>. The 
     * <code>CodecFactory</code> is normally obtained via a call to 
     * <code>ORB.resolve_initial_references( "CodecFactory" )</code>, but 
     * since the ORB is not yet available and Interceptors, particularly when 
     * processing service contexts, will require a <code>Codec</code>, a 
     * means of obtaining a <code>Codec</code> is necessary during ORB 
     * initialization.
     */
    readonly attribute IOP::CodecFactory codec_factory;

    /** 
     * Identical to <code>ORB.register_initial_reference</code>. This same 
     * functionality exists here because the ORB, not yet fully initialized, 
     * is not yet available but initial references may need to be 
     * registered as part of Interceptor registration. The only difference 
     * is that the version of this operation on the ORB uses PIDL 
     * (<code>CORBA.ORB.ObjectId</code>) and 
     * (<code>CORBA.ORB.InvalidName</code>) whereas the version in this 
     * interface uses IDL defined in this interface; the semantics are 
     * identical.
     */
    void register_initial_reference (in ObjectId id, in Object obj)
      raises (InvalidName);

    // This was incorrectly returning void in orbos/99-12-02, correction
    // from errata in orbos/00-01-01
    /**
     * Identical to <code>ORB.resolve_initial_references</code>. This same 
     * functionality exists here because the ORB, not yet fully initialized, 
     * is not yet available but initial references may be required from the 
     * ORB as part of Interceptor registration. The only difference is that 
     * the version of this operation on the ORB uses PIDL 
     * (<code>CORBA::ORB::ObjectId</code> and 
     * <code>CORBA::ORB::InvalidName</code>) whereas the version in this 
     * interface uses IDL defined in this interface; the semantics 
     * are identical.
     * <p>
     * This operation is only valid during post_init.
     */
    Object resolve_initial_references (in ObjectId id) raises (InvalidName);

    /**
     * Used to add a client-side request Interceptor to the list of 
     * client-side request Interceptors.  
     *
     * @param interceptor The <code>ClientRequestInterceptor</code> to be 
     *     added.
     * @exception DuplicateName thrown if a client-side request Interceptor 
     *     has already been registered with this Interceptor's name.
     */
    void add_client_request_interceptor 
      (in ClientRequestInterceptor interceptor)
      raises (DuplicateName);

    /** 
     * Used to add a server-side request Interceptor to the list of 
     * server-side request Interceptors.
     *
     * @param interceptor The ServerRequestInterceptor to be added.
     * @exception DuplicateName thrown if a server-side request Interceptor 
     *     has already been registered with this Interceptor's name
     */
    void add_server_request_interceptor (
      in ServerRequestInterceptor interceptor)
      raises (DuplicateName);

    /**
     * Used to add an IOR Interceptor to the list of IOR Interceptors. 
     *
     * @param interceptor The IORInterceptor to be added.
     * @exception DuplicateName thrown if an IOR Interceptor has already 
     *     been registered with this Interceptor's name. 
     */
    void add_ior_interceptor (in IORInterceptor interceptor)
      raises (DuplicateName);

    /**
     * Called to allocate a slot on <code>PortableInterceptor.Current</code>. 
     * <p>
     * Note that while slot id's can be allocated within an ORB initializer, 
     * the slots themselves cannot be initialized. 
     *
     * @return The index to the slot which has been allocated.
     * @exception BAD_INV_ORDER thrown, with a standard minor code of 14, if 
     *     <code>set_slot</code> or <code>get_slot</code> is called on the 
     *     <code>PICurrent</code> within an ORB initializer. 
     * @see Current
     */
    SlotId allocate_slot_id ();

    /**
     * Registers a <code>PolicyFactory</code> for the given 
     * <code>PolicyType</code>. 
     * 
     * @param type The policy type that the given <code>PolicyFactory</code> 
     *     serves. 
     * @param policy_factory The factory for the given policy type.
     * @exception BAD_INV_ORDER thrown, with a standard minor code of 16, if 
     *     a <code>PolicyFactory</code> already exists for the given 
     *     <code>PolicyType</code>.
     */
    void register_policy_factory (
      in CORBA::PolicyType type,
      in PolicyFactory policy_factory);
  };

  /**
   * Facilitates interceptor registration and ORB initialization.
   * <p>
   * Interceptors are intended to be a means by which ORB services gain 
   * access to ORB processing, effectively becoming part of the ORB. 
   * Since Interceptors are part of the ORB, when <code>ORB.init</code> 
   * returns an ORB, the Interceptors shall have been registered. 
   * Interceptors cannot be registered on an ORB after it has been 
   * returned by a call to <code>ORB.init</code>.
   * <p>
   * An Interceptor is registered by registering an associated 
   * <code>ORBInitializer</code> object which implements the 
   * <code>ORBInitializer</code> interface. When an ORB is initializing, 
   * it shall call each registered <code>ORBInitializer</code>, passing it 
   * an <code>ORBInitInfo</code> object which is used to register its 
   * Interceptor.
   * <p>
   * <b>Registering ORB Initializers in Java</b>
   * <p>
   * ORBInitializers are registered via Java ORB properties.
   * <p>
   * The property names are of the form: 
   *   <blockquote><code>
   *     org.omg.PortableInterceptor.ORBInitializerClass.&lt;Service&gt;
   *   </code></blockquote>
   * where <code>&lt;Service&gt;</code> is the string name of a class 
   * which implements 
   *   <blockquote><code>
   *     org.omg.PortableInterceptor.ORBInitializer
   *   </code></blockquote>
   * To avoid name collisions, the reverse DNS name convention should be 
   * used. For example, if company X has three initializers, it could define 
   * the following properties: 
   * <ul>
   *   <li><code>
   *     org.omg.PortableInterceptor.ORBInitializerClass.com.x.Init1
   *   </code></li>
   *   <li><code>
   *     org.omg.PortableInterceptor.ORBInitializerClass.com.x.Init2
   *   </code></li>
   *   <li><code>
   *     org.omg.PortableInterceptor.ORBInitializerClass.com.x.Init3
   *   </code></li>
   * </ul>
   * During ORB.init, these ORB properties which begin with 
   * <code>org.omg.PortableInterceptor.ORBInitializerClass</code> shall be 
   * collected, the <code>&lt;Service&gt;</code> portion of each property 
   * shall be extracted, an object shall be instantiated with the 
   * <code>&lt;Service&gt;</code> string as its class name, and the 
   * <code>pre_init</code> and <code>post_init</code> methods shall be 
   * called on that object. If there are any exceptions, the ORB shall 
   * ignore them and proceed. 
   * <p>
   * <b><i>Example</i></b>
   * <p>
   * A client-side logging service written by company X, for example, may 
   * have the following ORBInitializer implementation: 
   * <pre><code>
   * package com.x.logging;
   * 
   * import org.omg.PortableInterceptor.Interceptor; 
   * import org.omg.PortableInterceptor.ORBInitializer; 
   * import org.omg.PortableInterceptor.ORBInitInfo; 
   * 
   * public class LoggingService implements ORBInitializer { 
   *     void pre_init( ORBInitInfo info ) { 
   *         // Instantiate the Logging Service s Interceptor. 
   *         Interceptor interceptor = new LoggingInterceptor(); 
   *
   *         // Register the Logging Service s Interceptor. 
   *         info.add_client_request_interceptor( interceptor ); 
   *     } 
   * 
   *     void post_init( ORBInitInfo info ) { 
   *         // This service does not need two init points. 
   *     } 
   * } 
   * </code></pre>
   * To run a program called <code>MyApp</code> using this logging 
   * service, the user could type: 
   *   <blockquote><code>
   *     java 
   *-Dorg.omg.PortableInterceptor.ORBInitializerClass.com.x.Logging.LoggingService 
   *     MyApp
   *   </code></blockquote>
   * <p>
   * <b>Notes about Registering Interceptors</b>
   * <p>
   * Request Interceptors are registered on a per-ORB basis. 
   * <p>
   * To achieve virtual per-object Interceptors, query the policies on the 
   * target from within the interception points to determine whether they 
   * should do any work. 
   * <p>
   * To achieve virtual per-POA Interceptors, instantiate each POA with a 
   * different ORB. While Interceptors may be ordered administratively, 
   * there is no concept of order with respect to the registration of 
   * Interceptors. Request Interceptors are concerned with service contexts. 
   * Service contexts have no order, so there is no purpose for request 
   * Interceptors to have an order. IOR Interceptors are concerned with 
   * tagged components. Tagged components also have no order, so there 
   * is no purpose for IOR Interceptors to have an order. 
   * <p>
   * Registration code should avoid using the ORB (i.e., calling 
   * <code>ORB.init</code> with the provided <code>orb_id</code>). Since 
   * registration occurs during ORB initialization, results of invocations 
   * on this ORB while it is in this state are undefined. 
   * 
   * @see ORBInitInfo
   */
  local interface ORBInitializer {

    /** 
     * Called during ORB initialization.  If it is expected that initial 
     * services registered by an interceptor will be used by other 
     * interceptors, then those initial services shall be registered at 
     * this point via calls to 
     * <code>ORBInitInfo.register_initial_reference</code>. 
     * 
     * @param info provides initialization attributes and operations by 
     *     which Interceptors can be registered.
     */
    void pre_init (in ORBInitInfo info);

    /**
     * Called during ORB initialization. If a service must resolve initial 
     * references as part of its initialization, it can assume that all 
     * initial references will be available at this point. 
     * <p>
     * Calling the <code>post_init</code> operations is not the final 
     * task of ORB initialization. The final task, following the 
     * <code>post_init</code> calls, is attaching the lists of registered 
     * interceptors to the ORB. Therefore, the ORB does not contain the 
     * interceptors during calls to <code>post_init</code>. If an 
     * ORB-mediated call is made from within <code>post_init</code>, no 
     * request interceptors will be invoked on that call. 
     * Likewise, if an operation is performed which causes an IOR to be 
     * created, no IOR interceptors will be invoked. 
     *
     * @param info provides initialization attributes and 
     *     operations by which Interceptors can be registered.
     */
    void post_init (in ORBInitInfo info);
  };
};
