/*
 * Copyright (c) 1998, 2012, 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.
 */
/*
 * Licensed Materials - Property of IBM
 * RMI-IIOP v1.0
 * Copyright IBM Corp. 1998 1999  All Rights Reserved
 *
 */

package com.sun.corba.se.impl.io;

import javax.rmi.CORBA.Util;

import java.util.Hashtable;
import java.io.IOException;

import com.sun.corba.se.impl.util.RepositoryId;
import com.sun.corba.se.impl.util.Utility;

import org.omg.CORBA.TCKind;

import org.omg.CORBA.portable.IndirectionException;
import com.sun.org.omg.SendingContext.CodeBase;
import com.sun.org.omg.SendingContext.CodeBaseHelper;

import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;

import com.sun.corba.se.spi.logging.CORBALogDomains;
import com.sun.corba.se.impl.logging.OMGSystemException;
import com.sun.corba.se.impl.logging.UtilSystemException;

public final class ValueHandlerImpl implements javax.rmi.CORBA.ValueHandlerMultiFormat {

    // Property to override our maximum stream format version
    public static final String FORMAT_VERSION_PROPERTY
        = "com.sun.CORBA.MaxStreamFormatVersion";

    private static final byte MAX_SUPPORTED_FORMAT_VERSION = (byte)2;
    private static final byte STREAM_FORMAT_VERSION_1 = (byte)1;

    // The ValueHandler's maximum stream format version to advertise,
    // set in a static initializer.
    private static final byte MAX_STREAM_FORMAT_VERSION;

    static {
        MAX_STREAM_FORMAT_VERSION = getMaxStreamFormatVersion();
    }

    // Looks for the FORMAT_VERSION_PROPERTY system property
    // to allow the user to override our default stream format
    // version.  Note that this still only allows them to pick
    // a supported version (1 through MAX_STREAM_FORMAT_VERSION).
    private static byte getMaxStreamFormatVersion() {

        try {

            String propValue = (String) AccessController.doPrivileged(
                                        new PrivilegedAction() {
                public java.lang.Object run() {
                    return System.getProperty(ValueHandlerImpl.FORMAT_VERSION_PROPERTY);
                }
            });

            // The property wasn't set
            if (propValue == null)
                return MAX_SUPPORTED_FORMAT_VERSION;

            byte result = Byte.parseByte(propValue);

            // REVISIT.  Just set to MAX_SUPPORTED_FORMAT_VERSION
            // or really let the system shutdown with this Error?
            if (result < 1 || result > MAX_SUPPORTED_FORMAT_VERSION)
                // XXX I18N, logging needed.
                throw new ExceptionInInitializerError("Invalid stream format version: "
                                                      + result
                                                      + ".  Valid range is 1 through "
                                                      + MAX_SUPPORTED_FORMAT_VERSION);

            return result;

        } catch (Exception ex) {
            // REVISIT.  Swallow this or really let
            // the system shutdown with this Error?

            Error err = new ExceptionInInitializerError(ex);
            err.initCause( ex ) ;
            throw err ;
        }
    }

    public static final short kRemoteType = 0;
    public static final short kAbstractType = 1;
    public static final short kValueType = 2;

    private Hashtable inputStreamPairs = null;
    private Hashtable outputStreamPairs = null;
    private CodeBase codeBase = null;
    private boolean useHashtables = true;
    private boolean isInputStream = true;
    private IIOPOutputStream outputStreamBridge = null;
    private IIOPInputStream inputStreamBridge = null;
    private OMGSystemException omgWrapper = OMGSystemException.get(
        CORBALogDomains.RPC_ENCODING ) ;
    private UtilSystemException utilWrapper = UtilSystemException.get(
        CORBALogDomains.RPC_ENCODING ) ;

    // See javax.rmi.CORBA.ValueHandlerMultiFormat
    public byte getMaximumStreamFormatVersion() {
        return MAX_STREAM_FORMAT_VERSION;
    }

    // See javax.rmi.CORBA.ValueHandlerMultiFormat
    public void writeValue(org.omg.CORBA.portable.OutputStream out,
                           java.io.Serializable value,
                           byte streamFormatVersion) {

        if (streamFormatVersion == 2) {
            if (!(out instanceof org.omg.CORBA.portable.ValueOutputStream)) {
                throw omgWrapper.notAValueoutputstream() ;
            }
        } else if (streamFormatVersion != 1) {
            throw omgWrapper.invalidStreamFormatVersion(
                new Integer(streamFormatVersion) ) ;
        }

        writeValueWithVersion(out, value, streamFormatVersion);
    }

    private ValueHandlerImpl(){}

    private ValueHandlerImpl(boolean isInputStream) {
        this();
        useHashtables = false;
        this.isInputStream = isInputStream;
    }

    static ValueHandlerImpl getInstance() {
        return new ValueHandlerImpl();
    }

    static ValueHandlerImpl getInstance(boolean isInputStream) {
        return new ValueHandlerImpl(isInputStream);
    }

    /**
     * Writes the value to the stream using java semantics.
     * @param out The stream to write the value to
     * @param value The value to be written to the stream
     **/
    public void writeValue(org.omg.CORBA.portable.OutputStream _out,
                           java.io.Serializable value) {
        writeValueWithVersion(_out, value, STREAM_FORMAT_VERSION_1);
    }

    private void writeValueWithVersion(org.omg.CORBA.portable.OutputStream _out,
                                       java.io.Serializable value,
                                       byte streamFormatVersion) {

        org.omg.CORBA_2_3.portable.OutputStream out =
            (org.omg.CORBA_2_3.portable.OutputStream) _out;

        if (!useHashtables) {
            if (outputStreamBridge == null) {
                outputStreamBridge = createOutputStream();
                outputStreamBridge.setOrbStream(out);
            }

            try {
                outputStreamBridge.increaseRecursionDepth();
                writeValueInternal(outputStreamBridge, out, value, streamFormatVersion);
            } finally {
                outputStreamBridge.decreaseRecursionDepth();
            }

            return;
        }

        IIOPOutputStream jdkToOrbOutputStreamBridge = null;

        if (outputStreamPairs == null)
            outputStreamPairs = new Hashtable();

        jdkToOrbOutputStreamBridge = (IIOPOutputStream)outputStreamPairs.get(_out);

        if (jdkToOrbOutputStreamBridge == null) {
            jdkToOrbOutputStreamBridge = createOutputStream();
            jdkToOrbOutputStreamBridge.setOrbStream(out);
            outputStreamPairs.put(_out, jdkToOrbOutputStreamBridge);
        }

        try {

            jdkToOrbOutputStreamBridge.increaseRecursionDepth();
            writeValueInternal(jdkToOrbOutputStreamBridge, out, value, streamFormatVersion);
        } finally {
            if (jdkToOrbOutputStreamBridge.decreaseRecursionDepth() == 0) {
                outputStreamPairs.remove(_out);
            }
        }
    }

    private void writeValueInternal(IIOPOutputStream bridge,
                                    org.omg.CORBA_2_3.portable.OutputStream out,
                                    java.io.Serializable value,
                                    byte streamFormatVersion)
    {
        Class clazz = value.getClass();

        if (clazz.isArray())
            write_Array(out, value, clazz.getComponentType());
        else
            bridge.simpleWriteObject(value, streamFormatVersion);
    }

    /**
     * Reads a value from the stream using java semantics.
     * @param in The stream to read the value from
     * @param clazz The type of the value to be read in
     * @param sender The sending context runtime
     **/
    public java.io.Serializable readValue(org.omg.CORBA.portable.InputStream _in,
                                          int offset,
                                          java.lang.Class clazz,
                                          String repositoryID,
                                          org.omg.SendingContext.RunTime _sender)
    {
        // Must use narrow rather than a direct cast to a com.sun
        // class.  Fix for bug 4379539.
        CodeBase sender = CodeBaseHelper.narrow(_sender);

        org.omg.CORBA_2_3.portable.InputStream in =
            (org.omg.CORBA_2_3.portable.InputStream) _in;

        if (!useHashtables) {
            if (inputStreamBridge == null) {
                inputStreamBridge = createInputStream();
                inputStreamBridge.setOrbStream(in);
                inputStreamBridge.setSender(sender); //d11638
                // backward compatability 4365188
                inputStreamBridge.setValueHandler(this);
            }

            java.io.Serializable result = null;

            try {

                inputStreamBridge.increaseRecursionDepth();
                result = (java.io.Serializable) readValueInternal(inputStreamBridge, in, offset, clazz, repositoryID, sender);

            } finally {

                if (inputStreamBridge.decreaseRecursionDepth() == 0) {
                    // Indirections are resolved immediately since
                    // the change to the active recursion manager,
                    // so this will never happen.
                }
            }

            return result;
        }

        IIOPInputStream jdkToOrbInputStreamBridge = null;
        if (inputStreamPairs == null)
            inputStreamPairs = new Hashtable();

        jdkToOrbInputStreamBridge = (IIOPInputStream)inputStreamPairs.get(_in);

        if (jdkToOrbInputStreamBridge == null) {

            jdkToOrbInputStreamBridge = createInputStream();
            jdkToOrbInputStreamBridge.setOrbStream(in);
            jdkToOrbInputStreamBridge.setSender(sender); //d11638
            // backward compatability 4365188
            jdkToOrbInputStreamBridge.setValueHandler(this);
            inputStreamPairs.put(_in, jdkToOrbInputStreamBridge);
        }

        java.io.Serializable result = null;

        try {

            jdkToOrbInputStreamBridge.increaseRecursionDepth();
            result = (java.io.Serializable) readValueInternal(jdkToOrbInputStreamBridge, in, offset, clazz, repositoryID, sender);

        } finally {

            if (jdkToOrbInputStreamBridge.decreaseRecursionDepth() == 0) {
                inputStreamPairs.remove(_in);
            }
        }

        return result;
    }

    private java.io.Serializable readValueInternal(IIOPInputStream bridge,
                                                  org.omg.CORBA_2_3.portable.InputStream in,
                                                  int offset,
                                                  java.lang.Class clazz,
                                                  String repositoryID,
                                                  com.sun.org.omg.SendingContext.CodeBase sender)
    {
        java.io.Serializable result = null;

        if (clazz == null) {
            // clazz == null indicates an FVD situation for a nonexistant class
            if (isArray(repositoryID)){
                read_Array(bridge, in, null, sender, offset);
            } else {
                bridge.simpleSkipObject(repositoryID, sender);
            }
            return result;
        }

        if (clazz.isArray()) {
            result = (java.io.Serializable)read_Array(bridge, in, clazz, sender, offset);
        } else {
            result = (java.io.Serializable)bridge.simpleReadObject(clazz, repositoryID, sender, offset);
        }

        return result;
    }

    /**
     * Returns the repository ID for the given RMI value Class.
     * @param clz The class to return a repository ID for.
     * @return the repository ID of the Class.
     **/
    public java.lang.String getRMIRepositoryID(java.lang.Class clz) {
        return RepositoryId.createForJavaType(clz);
    }

    /**
     * Indicates whether the given Class performs custom or
     * default marshaling.
     * @param clz The class to test for custom marshaling.
     * @return True if the class performs custom marshaling, false
     * if it does not.
     **/
    public boolean isCustomMarshaled(java.lang.Class clz) {
        return ObjectStreamClass.lookup(clz).isCustomMarshaled();
    }

    /**
     * Returns the CodeBase for this ValueHandler.  This is used by
     * the ORB runtime.  The server sends the service context containing
     * the IOR for this CodeBase on the first GIOP reply.  The clients
     * do the same on the first GIOP request.
     * @return the SendingContext.CodeBase of this ValueHandler.
     **/
    public org.omg.SendingContext.RunTime getRunTimeCodeBase() {
        if (codeBase != null)
            return codeBase;
        else {
            codeBase = new FVDCodeBaseImpl();

            // backward compatability 4365188
            // set the valueHandler so that correct/incorrect RepositoryID
            // calculations can be done based on the ORB version
            FVDCodeBaseImpl fvdImpl = (FVDCodeBaseImpl) codeBase;
            fvdImpl.setValueHandler(this);
            return codeBase;
        }
    }


    // methods supported for backward compatability so that the appropriate
    // Rep-id calculations take place based on the ORB version

    /**
     *  Returns a boolean of whether or not RepositoryId indicates
     *  FullValueDescriptor.
     *  used for backward compatability
     */

     public boolean useFullValueDescription(Class clazz, String repositoryID)
        throws IOException
     {
        return RepositoryId.useFullValueDescription(clazz, repositoryID);
     }

     public String getClassName(String id)
     {
        RepositoryId repID = RepositoryId.cache.getId(id);
        return repID.getClassName();
     }

     public Class getClassFromType(String id)
        throws ClassNotFoundException
     {
        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getClassFromType();
     }

     public Class getAnyClassFromType(String id)
        throws ClassNotFoundException
     {
        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getAnyClassFromType();
     }

     public String createForAnyType(Class cl)
     {
        return RepositoryId.createForAnyType(cl);
     }

     public String getDefinedInId(String id)
     {
        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getDefinedInId();
     }

     public String getUnqualifiedName(String id)
     {
        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getUnqualifiedName();
     }

     public String getSerialVersionUID(String id)
     {
        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.getSerialVersionUID();
     }


     public boolean isAbstractBase(Class clazz)
     {
        return RepositoryId.isAbstractBase(clazz);
     }

     public boolean isSequence(String id)
     {
        RepositoryId repId = RepositoryId.cache.getId(id);
        return repId.isSequence();
     }

    /**
     * If the value contains a writeReplace method then the result
     * is returned.  Otherwise, the value itself is returned.
     * @return the true value to marshal on the wire.
     **/
    public java.io.Serializable writeReplace(java.io.Serializable value) {
        return ObjectStreamClass.lookup(value.getClass()).writeReplace(value);
    }

    private void writeCharArray(org.omg.CORBA_2_3.portable.OutputStream out,
                                char[] array,
                                int offset,
                                int length)
    {
        out.write_wchar_array(array, offset, length);
    }

    private void write_Array(org.omg.CORBA_2_3.portable.OutputStream out, java.io.Serializable obj, Class type) {

        int i, length;

        if (type.isPrimitive()) {
            if (type == Integer.TYPE) {
                int[] array = (int[])((Object)obj);
                length = array.length;
                out.write_ulong(length);
                out.write_long_array(array, 0, length);
            } else if (type == Byte.TYPE) {
                byte[] array = (byte[])((Object)obj);
                length = array.length;
                out.write_ulong(length);
                out.write_octet_array(array, 0, length);
            } else if (type == Long.TYPE) {
                long[] array = (long[])((Object)obj);
                length = array.length;
                out.write_ulong(length);
                out.write_longlong_array(array, 0, length);
            } else if (type == Float.TYPE) {
                float[] array = (float[])((Object)obj);
                length = array.length;
                out.write_ulong(length);
                out.write_float_array(array, 0, length);
            } else if (type == Double.TYPE) {
                double[] array = (double[])((Object)obj);
                length = array.length;
                out.write_ulong(length);
                out.write_double_array(array, 0, length);
            } else if (type == Short.TYPE) {
                short[] array = (short[])((Object)obj);
                length = array.length;
                out.write_ulong(length);
                out.write_short_array(array, 0, length);
            } else if (type == Character.TYPE) {
                char[] array = (char[])((Object)obj);
                length = array.length;
                out.write_ulong(length);
                writeCharArray(out, array, 0, length);
            } else if (type == Boolean.TYPE) {
                boolean[] array = (boolean[])((Object)obj);
                length = array.length;
                out.write_ulong(length);
                out.write_boolean_array(array, 0, length);
            } else {
                // XXX I18N, logging needed.
                throw new Error("Invalid primitive type : " +
                    obj.getClass().getName());
            }
        } else if (type == java.lang.Object.class) {
            Object[] array = (Object[])((Object)obj);
            length = array.length;
            out.write_ulong(length);
            for (i = 0; i < length; i++) {
                Util.writeAny(out, array[i]);
            }
        } else {
            Object[] array = (Object[])((Object)obj);
            length = array.length;
            out.write_ulong(length);
            int callType = kValueType;

            if (type.isInterface()) {
                String className = type.getName();

                if (java.rmi.Remote.class.isAssignableFrom(type)) {
                    // RMI Object reference...
                    callType = kRemoteType;
                } else if (org.omg.CORBA.Object.class.isAssignableFrom(type)){
                    // IDL Object reference...
                    callType = kRemoteType;
                } else if (RepositoryId.isAbstractBase(type)) {
                    // IDL Abstract Object reference...
                    callType = kAbstractType;
                } else if (ObjectStreamClassCorbaExt.isAbstractInterface(type)) {
                    callType = kAbstractType;
                }
            }

            for (i = 0; i < length; i++) {
                switch (callType) {
                case kRemoteType:
                    Util.writeRemoteObject(out, array[i]);
                    break;
                case kAbstractType:
                    Util.writeAbstractObject(out,array[i]);
                    break;
                case kValueType:
                    try{
                        out.write_value((java.io.Serializable)array[i]);
                    } catch(ClassCastException cce){
                        if (array[i] instanceof java.io.Serializable)
                            throw cce;
                        else {
                            Utility.throwNotSerializableForCorba(
                                array[i].getClass().getName());
                        }
                    }
                    break;
                }
            }
        }
    }

    private void readCharArray(org.omg.CORBA_2_3.portable.InputStream in,
                                 char[] array,
                                 int offset,
                                 int length)
    {
        in.read_wchar_array(array, offset, length);
    }

    private java.lang.Object read_Array(IIOPInputStream bridge,
                                        org.omg.CORBA_2_3.portable.InputStream in,
                                        Class sequence,
                                        com.sun.org.omg.SendingContext.CodeBase sender,
                                        int offset)
    {
        try {
            // Read length of coming array
            int length = in.read_ulong();
            int i;

            if (sequence == null) {
                for (i = 0; i < length; i++)
                    in.read_value();

                return null;
            }

            Class componentType = sequence.getComponentType();
            Class actualType = componentType;


            if (componentType.isPrimitive()) {
                if (componentType == Integer.TYPE) {
                    int[] array = new int[length];
                    in.read_long_array(array, 0, length);
                    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Byte.TYPE) {
                    byte[] array = new byte[length];
                    in.read_octet_array(array, 0, length);
                    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Long.TYPE) {
                    long[] array = new long[length];
                    in.read_longlong_array(array, 0, length);
                    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Float.TYPE) {
                    float[] array = new float[length];
                    in.read_float_array(array, 0, length);
                    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Double.TYPE) {
                    double[] array = new double[length];
                    in.read_double_array(array, 0, length);
                    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Short.TYPE) {
                    short[] array = new short[length];
                    in.read_short_array(array, 0, length);
                    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Character.TYPE) {
                    char[] array = new char[length];
                    readCharArray(in, array, 0, length);
                    return ((java.io.Serializable)((Object)array));
                } else if (componentType == Boolean.TYPE) {
                    boolean[] array = new boolean[length];
                    in.read_boolean_array(array, 0, length);
                    return ((java.io.Serializable)((Object)array));
                } else {
                    // XXX I18N, logging needed.
                    throw new Error("Invalid primitive componentType : " + sequence.getName());
                }
            } else if (componentType == java.lang.Object.class) {
                Object[] array = (Object[])java.lang.reflect.Array.newInstance(
                    componentType, length);

                // Store this object and its beginning position
                // since there might be indirections to it while
                // it's been unmarshalled.
                bridge.activeRecursionMgr.addObject(offset, array);

                for (i = 0; i < length; i++) {
                    Object objectValue = null;
                    try {
                        objectValue = Util.readAny(in);
                    } catch(IndirectionException cdrie) {
                        try {
                            // The CDR stream had never seen the given offset
                            // before, so check the recursion manager (it will
                            // throw an IOException if it doesn't have a
                            // reference, either).
                            objectValue = bridge.activeRecursionMgr.getObject(
                                cdrie.offset);
                        } catch (IOException ie) {
                            // Translate to a MARSHAL exception since
                            // ValueHandlers aren't allowed to throw
                            // IOExceptions
                            throw utilWrapper.invalidIndirection( ie,
                                new Integer( cdrie.offset ) ) ;
                        }
                    }

                    array[i] = objectValue;
                }
                return ((java.io.Serializable)((Object)array));
            } else {
                Object[] array = (Object[])java.lang.reflect.Array.newInstance(
                    componentType, length);
                // Store this object and its beginning position
                // since there might be indirections to it while
                // it's been unmarshalled.
                bridge.activeRecursionMgr.addObject(offset, array);

                // Decide what method call to make based on the componentType.
                // If it is a componentType for which we need to load a stub,
                // convert the componentType to the correct stub type.

                int callType = kValueType;
                boolean narrow = false;

                if (componentType.isInterface()) {
                    boolean loadStubClass = false;
                    // String className = componentType.getName();

                    if (java.rmi.Remote.class.isAssignableFrom(componentType)) {

                        // RMI Object reference...
                        callType = kRemoteType;

                        // for better performance, load the stub class once
                        // instead of for each element of the array
                        loadStubClass = true;
                    } else if (org.omg.CORBA.Object.class.isAssignableFrom(componentType)){
                        // IDL Object reference...
                        callType = kRemoteType;
                        loadStubClass = true;
                    } else if (RepositoryId.isAbstractBase(componentType)) {
                        // IDL Abstract Object reference...
                        callType = kAbstractType;
                        loadStubClass = true;
                    } else if (ObjectStreamClassCorbaExt.isAbstractInterface(componentType)) {

                        // RMI Abstract Object reference...

                        // componentType = null;
                        callType = kAbstractType;
                    }

                    if (loadStubClass) {
                        try {
                            String codebase = Util.getCodebase(componentType);
                            String repID = RepositoryId.createForAnyType(componentType);
                            Class stubType =
                                Utility.loadStubClass(repID, codebase, componentType);
                            actualType = stubType;
                        } catch (ClassNotFoundException e) {
                            narrow = true;
                        }
                    } else {
                        narrow = true;
                    }
                }

                for (i = 0; i < length; i++) {

                    try {
                        switch (callType) {
                        case kRemoteType:
                            if (!narrow)
                                array[i] = (Object)in.read_Object(actualType);
                            else {
                                array[i] = Utility.readObjectAndNarrow(in, actualType);

                            }
                            break;
                        case kAbstractType:
                            if (!narrow)
                                array[i] = (Object)in.read_abstract_interface(actualType);
                            else {
                                array[i] = Utility.readAbstractAndNarrow(in, actualType);
                            }
                            break;
                        case kValueType:
                            array[i] = (Object)in.read_value(actualType);
                            break;
                        }
                    } catch(IndirectionException cdrie) {
                        // The CDR stream had never seen the given offset before,
                        // so check the recursion manager (it will throw an
                        // IOException if it doesn't have a reference, either).
                        try {
                            array[i] = bridge.activeRecursionMgr.getObject(
                                cdrie.offset);
                        } catch (IOException ioe) {
                            // Translate to a MARSHAL exception since
                            // ValueHandlers aren't allowed to throw
                            // IOExceptions
                            throw utilWrapper.invalidIndirection( ioe,
                                new Integer( cdrie.offset ) ) ;
                        }
                    }

                }

                return ((java.io.Serializable)((Object)array));
            }
        } finally {
            // We've completed deserializing this object.  Any
            // future indirections will be handled correctly at the
            // CDR level.  The ActiveRecursionManager only deals with
            // objects currently being deserialized.
            bridge.activeRecursionMgr.removeObject(offset);
        }
    }

    private boolean isArray(String repId){
        return RepositoryId.cache.getId(repId).isSequence();
    }

    private String getOutputStreamClassName() {
        return "com.sun.corba.se.impl.io.IIOPOutputStream";
    }

   private IIOPOutputStream createOutputStream() {
        final String name = getOutputStreamClassName();
        try {
             IIOPOutputStream stream = createOutputStreamBuiltIn(name);
             if (stream != null) {
                 return stream;
             }
             return createCustom(IIOPOutputStream.class, name);
        } catch (Throwable t) {
            // Throw exception under the carpet.
            InternalError ie = new InternalError(
                "Error loading " + name
            );
                ie.initCause(t);
                throw ie;
        }
    }

    /**
     * Construct a built in implementation with priveleges.
     * Returning null indicates a non-built is specified.
     */
    private IIOPOutputStream createOutputStreamBuiltIn(
        final String name
    ) throws Throwable {
        try {
            return AccessController.doPrivileged(
                new PrivilegedExceptionAction<IIOPOutputStream>() {
                    public IIOPOutputStream run() throws IOException {
                        return createOutputStreamBuiltInNoPriv(name);
                    }
                }
            );
        } catch (java.security.PrivilegedActionException exc) {
            throw exc.getCause();
        }
    }

    /**
     * Returning null indicates a non-built is specified.
     */
    private IIOPOutputStream createOutputStreamBuiltInNoPriv(
        final String name
    ) throws IOException {
        return name.equals(IIOPOutputStream.class.getName()) ?
                new IIOPOutputStream() : null;
    }

    private String getInputStreamClassName() {
        return "com.sun.corba.se.impl.io.IIOPInputStream";
    }

    private IIOPInputStream createInputStream() {
        final String name = getInputStreamClassName();
        try {
             IIOPInputStream stream = createInputStreamBuiltIn(name);
             if (stream != null) {
                 return stream;
             }
             return createCustom(IIOPInputStream.class, name);
        } catch (Throwable t) {
            // Throw exception under the carpet.
            InternalError ie = new InternalError(
                "Error loading " + name
            );
                ie.initCause(t);
                throw ie;
        }
    }

    /**
     * Construct a built in implementation with priveleges.
     * Returning null indicates a non-built is specified.
     */
     private IIOPInputStream createInputStreamBuiltIn(
         final String name
     ) throws Throwable {
         try {
             return AccessController.doPrivileged(
                 new PrivilegedExceptionAction<IIOPInputStream>() {
                     public IIOPInputStream run() throws IOException {
                         return createInputStreamBuiltInNoPriv(name);
                     }
                 }
             );
         } catch (java.security.PrivilegedActionException exc) {
             throw exc.getCause();
         }
     }

     /**
      * Returning null indicates a non-built is specified.
      */
     private IIOPInputStream createInputStreamBuiltInNoPriv(
         final String name
     ) throws IOException {
         return name.equals(IIOPInputStream.class.getName()) ?
                new IIOPInputStream() : null;
     }

     /**
      * Create a custom implementation without privileges.
      */
     private <T> T createCustom(
         final Class<T> type, final String className
     ) throws Throwable {
           // Note: We use the thread context or system ClassLoader here
           // since we want to load classes outside of the
           // core JDK when running J2EE Pure ORB and
           // talking to Kestrel.
                ClassLoader cl = Thread.currentThread().getContextClassLoader();
                if (cl == null)
                    cl = ClassLoader.getSystemClassLoader();

                Class<?> clazz = cl.loadClass(className);
                Class<? extends T> streamClass = clazz.asSubclass(type);

                // Since the ClassLoader should cache the class, this isn't
                // as expensive as it looks.
                return streamClass.newInstance();

    }

    TCKind getJavaCharTCKind() {
        return TCKind.tk_wchar;
    }
}
