/*
 * Copyright (c) 1998, 2013, 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 sun.rmi.rmic.iiop;

import java.io.File;
import java.io.IOException;
import java.io.SerializablePermission;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Vector;
import java.util.Hashtable;
import java.util.Enumeration;
import sun.tools.java.Identifier;
import sun.tools.java.ClassNotFound;
import sun.tools.java.ClassDefinition;
import sun.tools.java.ClassDeclaration;
import sun.tools.java.CompilerError;
import sun.rmi.rmic.IndentingWriter;
import java.util.HashSet;
import java.util.Arrays;
import com.sun.corba.se.impl.util.Utility;
import com.sun.corba.se.impl.util.PackagePrefixChecker;
import sun.rmi.rmic.Main;


/**
 * An IIOP stub/tie generator for rmic.
 *
 * @author      Bryan Atsatt
 * @author      Anil Vijendran
 * @author      M. Mortazavi
 */

public class StubGenerator extends sun.rmi.rmic.iiop.Generator {

    private static final String DEFAULT_STUB_CLASS = "javax.rmi.CORBA.Stub";
    private static final String DEFAULT_TIE_CLASS = "org.omg.CORBA_2_3.portable.ObjectImpl";
    private static final String DEFAULT_POA_TIE_CLASS = "org.omg.PortableServer.Servant";

    protected boolean reverseIDs = false;
    protected boolean localStubs = true;
    protected boolean standardPackage = false;
    protected boolean useHash = true;
    protected String stubBaseClass = DEFAULT_STUB_CLASS;
    protected String tieBaseClass = DEFAULT_TIE_CLASS;
    protected HashSet namesInUse = new HashSet();
    protected Hashtable classesInUse = new Hashtable();
    protected Hashtable imports = new Hashtable();
    protected int importCount = 0;
    protected String currentPackage = null;
    protected String currentClass = null;
    protected boolean castArray = false;
    protected Hashtable transactionalObjects = new Hashtable() ;
    protected boolean POATie = false ;
    protected boolean emitPermissionCheck = false;

    /**
     * Default constructor for Main to use.
     */
    public StubGenerator() {
    }

    /**
     * Overridden in order to set the standardPackage flag.
     */
    public void generate(
            sun.rmi.rmic.BatchEnvironment env,
            ClassDefinition cdef, File destDir) {
        ((sun.rmi.rmic.iiop.BatchEnvironment)env).
                setStandardPackage(standardPackage);
        super.generate(env, cdef, destDir);
    }

    /**
     * Return true if a new instance should be created for each
     * class on the command line. Subclasses which return true
     * should override newInstance() to return an appropriately
     * constructed instance.
     */
    protected boolean requireNewInstance() {
        return false;
    }

    /**
     * Return true if non-conforming types should be parsed.
     * @param stack The context stack.
     */
    protected boolean parseNonConforming(ContextStack stack) {

        // We let the environment setting decide so that
        // another generator (e.g. IDLGenerator) can change
        // it and we will just go with the flow...

        return stack.getEnv().getParseNonConforming();
    }

    /**
     * Create and return a top-level type.
     * @param cdef The top-level class definition.
     * @param stack The context stack.
     * @return The compound type or null if is non-conforming.
     */
    protected CompoundType getTopType(ClassDefinition cdef, ContextStack stack) {

        CompoundType result = null;

        // Do we have an interface?

        if (cdef.isInterface()) {

            // Yes, so first try Abstract...

            result = AbstractType.forAbstract(cdef,stack,true);

            if (result == null) {

                // Then try Remote...

                result = RemoteType.forRemote(cdef,stack,false);
            }
        } else {

            // Not an interface, so try Implementation...

            result = ImplementationType.forImplementation(cdef,stack,false);
        }

        return result;
    }

    /**
     * Examine and consume command line arguments.
     * @param argv The command line arguments. Ignore null
     * and unknown arguments. Set each consumed argument to null.
     * @param error Report any errors using the main.error() methods.
     * @return true if no errors, false otherwise.
     */
    public boolean parseArgs(String argv[], Main main) {
        Object marker = new Object() ;

        // Reset any cached options...

        reverseIDs = false;
        localStubs = true;
        useHash = true;
        stubBaseClass = DEFAULT_STUB_CLASS;
        //       tieBaseClass = DEFAULT_TIE_CLASS;
        transactionalObjects = new Hashtable() ;

        // Parse options...

        boolean result = super.parseArgs(argv,main);
        if (result) {
            for (int i = 0; i < argv.length; i++) {
                if (argv[i] != null) {
                    String arg = argv[i].toLowerCase();
                    if (arg.equals("-iiop")) {
                        argv[i] = null;
                    } else if (arg.equals("-xreverseids")) {
                        reverseIDs = true;
                        argv[i] = null;
                    } else if (arg.equals("-nolocalstubs")) {
                        localStubs = false;
                        argv[i] = null;
                    } else if (arg.equals("-xnohash")) {
                        useHash = false;
                        argv[i] = null;
                    } else if (argv[i].equals("-standardPackage")) {
                        standardPackage = true;
                        argv[i] = null;
                    } else if (argv[i].equals("-emitPermissionCheck")) {
                        emitPermissionCheck = true;
                        argv[i] = null;
                    } else if (arg.equals("-xstubbase")) {
                        argv[i] = null;
                        if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) {
                            stubBaseClass = argv[i];
                            argv[i] = null;
                        } else {
                            main.error("rmic.option.requires.argument", "-Xstubbase");
                            result = false;
                        }
                    } else if (arg.equals("-xtiebase")) {
                        argv[i] = null;
                        if (++i < argv.length && argv[i] != null && !argv[i].startsWith("-")) {
                            tieBaseClass = argv[i];
                            argv[i] = null;
                        } else {
                            main.error("rmic.option.requires.argument", "-Xtiebase");
                            result = false;
                        }
                    } else if (arg.equals("-transactional" )) {
                        // Scan for the next non-flag argument.
                        // Assume that it is a class name and add it
                        // to the list of transactional classes.
                        for ( int ctr=i+1; ctr<argv.length; ctr++ ) {
                            if (argv[ctr].charAt(1) != '-') {
                                transactionalObjects.put( argv[ctr], marker ) ;
                                break ;
                            }
                        }
                        argv[i] = null;
                    } else if (arg.equals( "-poa" )) {
                        POATie = true ;
                        argv[i] = null;
                    }
                }
            }
        }
        if(POATie){
            tieBaseClass = DEFAULT_POA_TIE_CLASS;
        } else {
            tieBaseClass = DEFAULT_TIE_CLASS;
        }
        return result;
    }

    /**
     * Return an array containing all the file names and types that need to be
     * generated for the given top-level type.  The file names must NOT have an
     * extension (e.g. ".java").
     * @param topType The type returned by getTopType().
     * @param alreadyChecked A set of Types which have already been checked.
     *  Intended to be passed to topType.collectMatching(filter,alreadyChecked).
     */
    protected OutputType[] getOutputTypesFor(CompoundType topType,
                                             HashSet alreadyChecked) {

        // We want to generate stubs for all remote and implementation types,
        // so collect them up.
        //
        // We use the form of collectMatching which allows us to pass in a set of
        // types which have previously been checked. By doing so, we ensure that if
        // the command line contains Hello and HelloImpl, we will only generate
        // output for Hello once...

        int filter = TYPE_REMOTE | TYPE_IMPLEMENTATION;
        Type[] genTypes = topType.collectMatching(filter,alreadyChecked);
        int count = genTypes.length;
        Vector list = new Vector(count+5);
        BatchEnvironment theEnv = topType.getEnv();

        // Now walk all types...

        for (int i = 0; i < genTypes.length; i++) {

            Type type = genTypes[i];
            String typeName = type.getName();
            boolean createStub = true;

            // Is it an implementation type?

            if (type instanceof ImplementationType) {

                // Yes, so add a tie for it...

                list.addElement(new OutputType(Utility.tieNameForCompiler(typeName), type));

                // Does it have more than 1 remote interface?  If so, we
                // want to create a stub for it...

                int remoteInterfaceCount = 0;
                InterfaceType[] interfaces = ((CompoundType)type).getInterfaces();
                for (int j = 0; j < interfaces.length; j++) {
                    if (interfaces[j].isType(TYPE_REMOTE) &&
                        !interfaces[j].isType(TYPE_ABSTRACT)) {
                        remoteInterfaceCount++;
                    }
                }

                if (remoteInterfaceCount <= 1) {

                    // No, so do not create a stub for this type...

                    createStub = false;
                }
            }

            // Is it an abstract interface type?

            if (type instanceof AbstractType) {

                // Do not create a stub for this type...

                createStub = false;  // d11141
            }

            if (createStub) {

                // Add a stub for the type...

                list.addElement(new OutputType(Utility.stubNameForCompiler(typeName), type));
            }
        }

        // Copy list into array..

        OutputType[] outputTypes = new OutputType[list.size()];
        list.copyInto(outputTypes);
        return outputTypes;
    }

    /**
     * Return the file name extension for the given file name (e.g. ".java").
     * All files generated with the ".java" extension will be compiled. To
     * change this behavior for ".java" files, override the compileJavaSourceFile
     * method to return false.
     * @param outputType One of the items returned by getOutputTypesFor(...)
     */
    protected String getFileNameExtensionFor(OutputType outputType) {
        return SOURCE_FILE_EXTENSION;
    }

    /**
     * Write the output for the given OutputFileName into the output stream.
     * @param name One of the items returned by getOutputTypesFor(...)
     * @param alreadyChecked A set of Types which have already been checked.
     *  Intended to be passed to Type.collectMatching(filter,alreadyChecked).
     * @param writer The output stream.
     */
    protected void writeOutputFor(      OutputType outputType,
                                        HashSet alreadyChecked,
                                        IndentingWriter writer) throws IOException {

        String fileName = outputType.getName();
        CompoundType theType = (CompoundType) outputType.getType();

        // Are we doing a Stub or Tie?

        if (fileName.endsWith(Utility.RMI_STUB_SUFFIX)) {

            // Stub.

            writeStub(outputType,writer);

        } else {

            // Tie

            writeTie(outputType,writer);
        }
    }

    /**
     * Write a stub for the specified type.
     */
    protected void writeStub(OutputType outputType,
                             IndentingWriter p) throws IOException {

        CompoundType theType = (CompoundType) outputType.getType();
        RemoteType[] remoteInterfaces = getDirectRemoteInterfaces(theType);

        // Write comment.

        p.pln("// Stub class generated by rmic, do not edit.");
        p.pln("// Contents subject to change without notice.");
        p.pln();

        // Set our standard classes...

        setStandardClassesInUse(theType,true);

        // Add classes for this type...

        addClassesInUse(theType,remoteInterfaces);

        // Write package and import statements...

        writePackageAndImports(p);

//        generate
//        import java.security.AccessController;
//        import java.security.PrivilegedAction;
//        import java.io.SerializablePermission;
        if (emitPermissionCheck) {
            p.pln("import java.security.AccessController;");
            p.pln("import java.security.PrivilegedAction;");
            p.pln("import java.io.SerializablePermission;");
            p.pln();
            p.pln();
        }

        // Declare the stub class; implement all remote interfaces.

        p.p("public class " + currentClass);

        p.p(" extends " + getName(stubBaseClass));
        p.p(" implements ");
        if (remoteInterfaces.length > 0) {
            for(int i = 0; i < remoteInterfaces.length; i++) {
                if (i > 0) {
                    p.pln(",");
                }
                String objName = testUtil(getName(remoteInterfaces[i]), theType);
                p.p(objName);
            }
        }

        // Add java.rmi.Remote if this type does not implement it.
        // This allows stubs for Abstract interfaces to be treated
        // uniformly...

        if (!implementsRemote(theType)) {
            p.pln(",");
            p.p(getName("java.rmi.Remote"));
        }

        p.plnI(" {");
        p.pln();

        // Write the ids...

        writeIds( p, theType, false );
        p.pln();

        if (emitPermissionCheck) {

            // produce the following generated code for example
            //
            // private transient boolean _instantiated = false;
            //
            // private static Void checkPermission() {
            // SecurityManager sm = System.getSecurityManager();
            // if (sm != null) {
            //     sm.checkPermission(new SerializablePermission(
            // "enableSubclassImplementation")); // testing
            // }
            // return null;
            // }
            //
            // private _XXXXX_Stub(Void ignore) {
            // }
            //
            // public _XXXXX_Stub() {
            // this(checkPermission());
            // _instantiated = true;
            // }
            //
            // private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
            //    checkPermission();
            //    s.defaultReadObject();
            //    _instantiated = true;
            // }
            //
            // where XXXXX is the name of the remote interface

                p.pln();
                p.plnI("private transient boolean _instantiated = false;");
                p.pln();
                p.pO();
                p.plnI("private static Void checkPermission() {");
                p.plnI("SecurityManager sm = System.getSecurityManager();");
                p.pln("if (sm != null) {");
                p.pI();
                p.plnI("sm.checkPermission(new SerializablePermission(");
                p.plnI("\"enableSubclassImplementation\"));");
                p.pO();
                p.pO();
                p.pOln("}");
                p.pln("return null;");
                p.pO();
                p.pOln("}");
                p.pln();
                p.pO();

                p.pI();
                p.plnI("private " + currentClass + "(Void ignore) {  }");
                p.pln();
                p.pO();

                p.plnI("public " + currentClass + "() {");
                p.pln("this(checkPermission());");
                p.pln("_instantiated = true;");
                p.pOln("}");
                p.pln();
                p.plnI("private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {");
                p.plnI("checkPermission();");
                p.pO();
                p.pln("s.defaultReadObject();");
                p.pln("_instantiated = true;");
                p.pOln("}");
                p.pln();
                //p.pO();
        }

       if (!emitPermissionCheck) {
            p.pI();
       }

        // Write the _ids() method...

        p.plnI("public String[] _ids() { ");
        p.pln("return (String[]) _type_ids.clone();");
        p.pOln("}");

        // Get all the methods and write each stub method...

        CompoundType.Method[] remoteMethods = theType.getMethods();
        int methodCount = remoteMethods.length;
        if (methodCount > 0) {
            boolean writeHeader = true;
            for(int i = 0; i < methodCount; i++) {
                if (!remoteMethods[i].isConstructor()) {
                    if (writeHeader) {
                        writeHeader = false;
                    }
                    p.pln();
                    writeStubMethod(p, remoteMethods[i], theType);
                }
            }
        }

        // Write the cast array hack...

        writeCastArray(p);

        p.pOln("}");            // end stub class
    }

    void addClassInUse(String qualifiedName) {
        String unqualifiedName = qualifiedName;
        String packageName = null;
        int index = qualifiedName.lastIndexOf('.');
        if (index > 0) {
            unqualifiedName = qualifiedName.substring(index+1);
            packageName = qualifiedName.substring(0,index);
        }
        addClassInUse(unqualifiedName,qualifiedName,packageName);
    }

    void addClassInUse(Type type) {
        if (!type.isPrimitive()) {
            Identifier id = type.getIdentifier();
            String name = IDLNames.replace(id.getName().toString(),". ",".");
            String packageName = type.getPackageName();
            String qualifiedName;
            if (packageName != null) {
                qualifiedName = packageName+"."+name;
            } else {
                qualifiedName = name;
            }
            addClassInUse(name,qualifiedName,packageName);
        }
    }

    void addClassInUse(Type[] types) {
        for (int i = 0; i < types.length; i++) {
            addClassInUse(types[i]);
        }
    }

    void addStubInUse(Type type) {
        if (type.getIdentifier() != idCorbaObject &&
            type.isType(TYPE_CORBA_OBJECT)) {
            String stubName = getStubNameFor(type,false);
            String packageName = type.getPackageName();
            String fullName;
            if (packageName == null) {
                fullName = stubName;
            } else {
                fullName = packageName + "." + stubName;
            }
            addClassInUse(stubName,fullName,packageName);
        }
        if (type.isType(TYPE_REMOTE) ||
            type.isType(TYPE_JAVA_RMI_REMOTE)) {
            addClassInUse("javax.rmi.PortableRemoteObject");
        }
    }

    String getStubNameFor(Type type, boolean qualified) {
        String stubName;
        String className;
        if (qualified) {
            className = type.getQualifiedName();
        } else {
            className = type.getName();
        }
        if (((CompoundType)type).isCORBAObject()) {
            stubName = Utility.idlStubName(className);
        } else {
            stubName = Utility.stubNameForCompiler(className);
        }
        return stubName;
    }

    void addStubInUse(Type[] types) {
        for (int i = 0; i < types.length; i++) {
            addStubInUse(types[i]);
        }
    }

    private static final String NO_IMPORT = new String();

    void addClassInUse(String unqualifiedName, String qualifiedName, String packageName) {

        // Have we already got an entry for this qualifiedName?

        String currentName = (String)classesInUse.get(qualifiedName);

        if (currentName == null) {

            // No, never seen it before. Grab any existing import
            // name and then decide what to do...

            String importName = (String) imports.get(unqualifiedName);
            String nameToUse = null;

            if (packageName == null) {

                // Default package, so doesn't matter which name to use...

                nameToUse = unqualifiedName;

            } else if (packageName.equals("java.lang")) {

                // java.lang.*, so use unqualified name...

                nameToUse = unqualifiedName;

                // unless you want to be able to import things from the right place :--)

                if(nameToUse.endsWith("_Stub")) nameToUse = Util.packagePrefix()+qualifiedName;

            } else if (currentPackage != null && packageName.equals(currentPackage)) {

                // Class in currentPackage, so use unqualified name...

                nameToUse = unqualifiedName;

                // Do we already have a previous import under this
                // unqualified name?

                if (importName != null) {

                    // Yes, so we use qualifiedName...

                    nameToUse = qualifiedName;

                }

            } else if (importName != null) {

                // It is in some package for which we normally
                // would import, but we have a previous import
                // under this unqualified name. We must use
                // the qualified name...

                nameToUse = qualifiedName;

                /*
                  // Is the currentPackage the default package?

                  if (currentPackage == null) {

                  // Yes, so undo the import so that all
                  // uses for this name will be qualified...

                  String old = (String)imports.remove(unqualifiedName);
                  classesInUse.put(old,old);
                  importCount--;

                  // Note that this name is in use but should
                  // not be imported...

                  imports.put(nameToUse,NO_IMPORT);
                  }
                */
            } else if (qualifiedName.equals("org.omg.CORBA.Object")) {

                // Always qualify this quy to avoid confusion...

                nameToUse = qualifiedName;

            } else {

                // Default to using unqualified name, and add
                // this guy to the imports...

                // Check for nested class in which case we use
                // the fully qualified name instead of imports
                if (unqualifiedName.indexOf('.') != -1) {
                    nameToUse = qualifiedName;
                } else {
                    nameToUse = unqualifiedName;
                    imports.put(unqualifiedName,qualifiedName);
                    importCount++;
                }
            }

            // Now add the name...

            classesInUse.put(qualifiedName,nameToUse);
        }
    }

    String getName(Type type) {
        if (type.isPrimitive()) {
            return type.getName() + type.getArrayBrackets();
        }
        Identifier id = type.getIdentifier();
        String name = IDLNames.replace(id.toString(),". ",".");
        return getName(name) + type.getArrayBrackets();
    }

    // Added for Bug 4818753
    String getExceptionName(Type type) {
        Identifier id = type.getIdentifier();
        return IDLNames.replace(id.toString(),". ",".");
    }

    String getName(String qualifiedName) {
        return (String)classesInUse.get(qualifiedName);
    }

    String getName(Identifier id) {
        return getName(id.toString());
    }

    String getStubName(Type type) {
        String stubName = getStubNameFor(type,true);
        return getName(stubName);
    }

    void setStandardClassesInUse(CompoundType type,
                                 boolean stub) throws IOException {

        // Reset our state...

        currentPackage = type.getPackageName();
        imports.clear();
        classesInUse.clear();
        namesInUse.clear();
        importCount = 0;
        castArray = false;

        // Add the top-level type...

        addClassInUse(type);

        // Set current class name...

        if (stub) {
            currentClass = Utility.stubNameForCompiler(type.getName());
        } else {
            currentClass = Utility.tieNameForCompiler(type.getName());
        }

        // Add current class...

        if (currentPackage == null) {
            addClassInUse(currentClass,currentClass,currentPackage);
        } else {
            addClassInUse(currentClass,(currentPackage+"."+currentClass),currentPackage);
        }

        // Add standard classes...

        addClassInUse("javax.rmi.CORBA.Util");
        addClassInUse(idRemote.toString());
        addClassInUse(idRemoteException.toString());
        addClassInUse(idOutputStream.toString());
        addClassInUse(idInputStream.toString());
        addClassInUse(idSystemException.toString());
        addClassInUse(idJavaIoSerializable.toString());
        addClassInUse(idCorbaORB.toString());
        addClassInUse(idReplyHandler.toString());

        // Add stub/tie specific imports...

        if (stub) {
            addClassInUse(stubBaseClass);
            addClassInUse("java.rmi.UnexpectedException");
            addClassInUse(idRemarshalException.toString());
            addClassInUse(idApplicationException.toString());
            if (localStubs) {
                addClassInUse("org.omg.CORBA.portable.ServantObject");
            }
        } else {
            addClassInUse(type);
            addClassInUse(tieBaseClass);
            addClassInUse(idTieInterface.toString());
            addClassInUse(idBadMethodException.toString());
            addClassInUse(idPortableUnknownException.toString());
            addClassInUse(idJavaLangThrowable.toString());
        }
    }

    void addClassesInUse(CompoundType type, RemoteType[] interfaces) {

        // Walk all methods and add types in use...

        CompoundType.Method[] methods = type.getMethods();
        for (int i = 0; i < methods.length; i++) {
            addClassInUse(methods[i].getReturnType());
            addStubInUse(methods[i].getReturnType());
            addClassInUse(methods[i].getArguments());
            addStubInUse(methods[i].getArguments());
            addClassInUse(methods[i].getExceptions());
            // bug 4473859: Also include narrower subtypes for use
            addClassInUse(methods[i].getImplExceptions());
        }

        // If this is a stub, add all interfaces...

        if (interfaces != null) {
            addClassInUse(interfaces);
        }
    }

    void writePackageAndImports(IndentingWriter p) throws IOException {

        // Write package declaration...

        if (currentPackage != null) {
            p.pln("package " +
                     Util.correctPackageName(
                          currentPackage, false, standardPackage)
                   + ";");
            p.pln();
        }

        // Get imports into an array and sort them...

        String[] names = new String[importCount];
        int index = 0;
        for (Enumeration e = imports.elements() ; e.hasMoreElements() ;) {
            String it = (String) e.nextElement();
            if (it != NO_IMPORT) {
                names[index++] = it;
            }
        }

        Arrays.sort(names,new StringComparator());

        // Now dump them out...

        for (int i = 0; i < importCount; i++) {
            if(
               Util.isOffendingPackage(names[i])
               && names[i].endsWith("_Stub")
               && String.valueOf(names[i].charAt(names[i].lastIndexOf(".")+1)).equals("_")
               ){
                p.pln("import " + PackagePrefixChecker.packagePrefix()+names[i]+";");
            } else{
                p.pln("import " + names[i] + ";");
            }
        }
        p.pln();

        // Include offending packages . . .
        if ( currentPackage!=null && Util.isOffendingPackage(currentPackage) ){
            p.pln("import " + currentPackage +".*  ;");
        }
        p.pln();

    }

    boolean implementsRemote(CompoundType theType) {
        boolean result = theType.isType(TYPE_REMOTE) && !theType.isType(TYPE_ABSTRACT);

        // If theType is not remote, look at all the interfaces
        // until we find one that is...

        if (!result) {
            InterfaceType[] interfaces = theType.getInterfaces();
            for (int i = 0; i < interfaces.length; i++) {
                result = implementsRemote(interfaces[i]);
                if (result) {
                    break;
                }
            }
        }

        return result;
    }

    void writeStubMethod (  IndentingWriter p,
                            CompoundType.Method method,
                            CompoundType theType) throws IOException {

        // Wtite the method declaration and opening brace...
        String methodName = method.getName();
        String methodIDLName = method.getIDLName();

        Type paramTypes[] = method.getArguments();
        String paramNames[] = method.getArgumentNames();
        Type returnType = method.getReturnType();
        ValueType[] exceptions = getStubExceptions(method,false);
        boolean hasIOException = false;

        addNamesInUse(method);
        addNameInUse("_type_ids");

        String objName = testUtil(getName(returnType), returnType);
        p.p("public " + objName + " " + methodName + "(");
        for(int i = 0; i < paramTypes.length; i++) {
            if (i > 0)
                p.p(", ");
            p.p(getName(paramTypes[i]) + " " + paramNames[i]);
        }

        p.p(")");
        if (exceptions.length > 0) {
            p.p(" throws ");
            for(int i = 0; i < exceptions.length; i++) {
                if (i > 0) {
                    p.p(", ");
                }
                // Added for Bug 4818753
                p.p(getExceptionName(exceptions[i]));
            }
        }

        p.plnI(" {");

        // Now create the method body...
        if (emitPermissionCheck) {
            p.pln("if ((System.getSecurityManager() != null) && (!_instantiated)) {");
            p.plnI("    throw new java.io.IOError(new java.io.IOException(\"InvalidObject \"));");
            p.pOln("}");
            p.pln();
        }


        if (localStubs) {
            writeLocalStubMethodBody(p,method,theType);
        } else {
            writeNonLocalStubMethodBody(p,method,theType);
        }

        // Close out the method...

        p.pOln("}");
    }


    void writeLocalStubMethodBody (IndentingWriter p,
                                   CompoundType.Method method,
                                   CompoundType theType) throws IOException {

        String objName;
        String paramNames[] = method.getArgumentNames();
        Type returnType = method.getReturnType();
        ValueType[] exceptions = getStubExceptions(method,false);
        String methodName = method.getName();
        String methodIDLName = method.getIDLName();

        p.plnI("if (!Util.isLocal(this)) {");
        writeNonLocalStubMethodBody(p,method,theType);
        p.pOlnI("} else {");
        String so = getVariableName("so");

        p.pln("ServantObject "+so+" = _servant_preinvoke(\""+methodIDLName+"\","+getName(theType)+".class);");
        p.plnI("if ("+so+" == null) {");
        if (!returnType.isType(TYPE_VOID)) {
            p.p("return ");
        }
        p.p(methodName+"(");
        for (int i = 0; i < paramNames.length; i++) {
            if (i > 0)
                p.p(", ");
            p.p(paramNames[i]);
        }
        p.pln(");");
        if (returnType.isType(TYPE_VOID)) {
            p.pln( "return ;" ) ;
        }

        p.pOln("}");
        p.plnI("try {");

        // Generate code to copy required arguments, and
        // get back the names by which all arguments are known...

        String[] argNames = writeCopyArguments(method,p);

        // Now write the method...

        boolean copyReturn = mustCopy(returnType);
        String resultName = null;
        if (!returnType.isType(TYPE_VOID)) {
            if (copyReturn) {
                resultName = getVariableName("result");
                objName = testUtil(getName(returnType), returnType);
                p.p(objName+" "+resultName + " = ");
            } else {
                p.p("return ");
            }
        }
        objName = testUtil(getName(theType), theType);
        p.p("(("+objName+")"+so+".servant)."+methodName+"(");

        for (int i = 0; i < argNames.length; i++) {
            if (i > 0)
                p.p(", ");
            p.p(argNames[i]);
        }

        if (copyReturn) {
            p.pln(");");
            objName = testUtil(getName(returnType), returnType);
            p.pln("return ("+objName+")Util.copyObject("+resultName+",_orb());");
        } else {
            p.pln(");");
        }

        String e1 = getVariableName("ex");
        String e2 = getVariableName("exCopy");
        p.pOlnI("} catch (Throwable "+e1+") {");

        p.pln("Throwable "+e2+" = (Throwable)Util.copyObject("+e1+",_orb());");
        for(int i = 0; i < exceptions.length; i++) {
            if (exceptions[i].getIdentifier() != idRemoteException &&
                exceptions[i].isType(TYPE_VALUE)) {
                // Added for Bug 4818753
                p.plnI("if ("+e2+" instanceof "+getExceptionName(exceptions[i])+") {");
                p.pln("throw ("+getExceptionName(exceptions[i])+")"+e2+";");
                p.pOln("}");
            }
        }

        p.pln("throw Util.wrapException("+e2+");");
        p.pOlnI("} finally {");
        p.pln("_servant_postinvoke("+so+");");
        p.pOln("}");
        p.pOln("}");
    }


    void writeNonLocalStubMethodBody (  IndentingWriter p,
                                        CompoundType.Method method,
                                        CompoundType theType) throws IOException {

        String methodName = method.getName();
        String methodIDLName = method.getIDLName();

        Type paramTypes[] = method.getArguments();
        String paramNames[] = method.getArgumentNames();
        Type returnType = method.getReturnType();
        ValueType[] exceptions = getStubExceptions(method,true);

        String in = getVariableName("in");
        String out = getVariableName("out");
        String ex = getVariableName("ex");

        // Decide if we need to use the new streams for
        // any of the read calls...

        boolean needNewReadStreamClass = false;
        for (int i = 0; i < exceptions.length; i++) {
            if (exceptions[i].getIdentifier() != idRemoteException &&
                exceptions[i].isType(TYPE_VALUE) &&
                needNewReadStreamClass(exceptions[i])) {
                needNewReadStreamClass = true;
                break;
            }
        }
        if (!needNewReadStreamClass) {
            for (int i = 0; i < paramTypes.length; i++) {
                if (needNewReadStreamClass(paramTypes[i])) {
                    needNewReadStreamClass = true;
                    break;
                }
            }
        }
        if (!needNewReadStreamClass) {
            needNewReadStreamClass = needNewReadStreamClass(returnType);
        }

        // Decide if we need to use the new streams for
        // any of the write calls...

        boolean needNewWriteStreamClass = false;
        for (int i = 0; i < paramTypes.length; i++) {
            if (needNewWriteStreamClass(paramTypes[i])) {
                needNewWriteStreamClass = true;
                break;
            }
        }

        // Now write the method, inserting casts where needed...

        p.plnI("try {");
        if (needNewReadStreamClass) {
            p.pln(idExtInputStream + " "+in+" = null;");
        } else {
            p.pln(idInputStream + " "+in+" = null;");
        }
        p.plnI("try {");

        String argStream = "null";

        if (needNewWriteStreamClass) {
            p.plnI(idExtOutputStream + " "+out+" = ");
            p.pln("(" + idExtOutputStream + ")");
            p.pln("_request(\"" + methodIDLName + "\", true);");
            p.pO();
        } else {
            p.pln("OutputStream "+out+" = _request(\"" + methodIDLName + "\", true);");
        }

        if (paramTypes.length > 0) {
            writeMarshalArguments(p, out, paramTypes, paramNames);
            p.pln();
        }
        argStream = out;

        if (returnType.isType(TYPE_VOID)) {
            p.pln("_invoke(" + argStream + ");" );
        } else {
            if (needNewReadStreamClass) {
                p.plnI(in+" = (" + idExtInputStream + ")_invoke(" + argStream + ");");
                p.pO();
            } else {
                p.pln(in+" = _invoke(" + argStream + ");");
            }
            p.p("return ");
            writeUnmarshalArgument(p, in, returnType, null);
            p.pln();
        }

        // Handle ApplicationException...

        p.pOlnI("} catch ("+getName(idApplicationException)+" "+ex+") {");
        if (needNewReadStreamClass) {
            p.pln(in + " = (" + idExtInputStream + ") "+ex+".getInputStream();");
        } else {
            p.pln(in + " = "+ex+".getInputStream();");
        }

        boolean idRead = false;
        boolean idAllocated = false;
        for(int i = 0; i < exceptions.length; i++) {
            if (exceptions[i].getIdentifier() != idRemoteException) {

                // Is this our special-case IDLEntity exception?

                if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) {

                    // Yes.

                    if (!idAllocated && !idRead) {
                        p.pln("String $_id = "+ex+".getId();");
                        idAllocated = true;
                    }

                    String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::",".");
                    helperName += "Helper";
                    p.plnI("if ($_id.equals("+helperName+".id())) {");
                    p.pln("throw "+helperName+".read("+in+");");

                } else {

                    // No.

                    if (!idAllocated && !idRead) {
        p.pln("String $_id = "+in+".read_string();");
                        idAllocated = true;
                        idRead = true;
                    } else if (idAllocated && !idRead) {
                        p.pln("$_id = "+in+".read_string();");
                        idRead = true;
                    }
                    p.plnI("if ($_id.equals(\""+getExceptionRepositoryID(exceptions[i])+"\")) {");
                    // Added for Bug 4818753
                    p.pln("throw ("+getExceptionName(exceptions[i])+") "+in+".read_value(" + getExceptionName(exceptions[i]) + ".class);");
                }
                p.pOln("}");
            }
        }
        if (!idAllocated && !idRead) {
            p.pln("String $_id = "+in+".read_string();");
            idAllocated = true;
            idRead = true;
        } else if (idAllocated && !idRead) {
            p.pln("$_id = "+in+".read_string();");
            idRead = true;
        }
        p.pln("throw new UnexpectedException($_id);");

        // Handle RemarshalException...

        p.pOlnI("} catch ("+getName(idRemarshalException)+" "+ex+") {");
        if (!returnType.isType(TYPE_VOID)) {
            p.p("return ");
        }
        p.p(methodName + "(");
        for(int i = 0; i < paramTypes.length; i++) {
            if (i > 0) {
                p.p(",");
            }
            p.p(paramNames[i]);
        }
        p.pln(");");

        // Ensure that we release the reply...

        p.pOlnI("} finally {");
        p.pln("_releaseReply("+in+");");

        p.pOln("}");

        // Handle SystemException...

        p.pOlnI("} catch (SystemException "+ex+") {");
        p.pln("throw Util.mapSystemException("+ex+");");
        p.pOln("}");

        // returnResult(p,returnType);
    }

    void allocateResult (IndentingWriter p,
                         Type returnType) throws IOException {
        if (!returnType.isType(TYPE_VOID)) {
            String objName = testUtil(getName(returnType), returnType);
            p.p(objName + " result = ");
        }
    }

    int getTypeCode(Type type) {

        int typeCode = type.getTypeCode();

        // Handle late-breaking special case for
        // abstract IDL entities...

        if ((type instanceof CompoundType) &&
            ((CompoundType)type).isAbstractBase()) {
            typeCode = TYPE_ABSTRACT;
        }

        return typeCode;
    }


    /**
     * Write a snippet of Java code to marshal a value named "name" of
     * type "type" to the java.io.ObjectOutput stream named "stream".
     */
    void writeMarshalArgument(IndentingWriter p,
                              String streamName,
                              Type type, String name) throws IOException {

        int typeCode = getTypeCode(type);

        switch (typeCode) {
        case TYPE_BOOLEAN:
            p.p(streamName + ".write_boolean(" + name + ");");
            break;
        case TYPE_BYTE:
            p.p(streamName + ".write_octet(" + name + ");");
            break;
        case TYPE_CHAR:
            p.p(streamName + ".write_wchar(" + name + ");");
            break;
        case TYPE_SHORT:
            p.p(streamName + ".write_short(" + name + ");");
            break;
        case TYPE_INT:
            p.p(streamName + ".write_long(" + name + ");");
            break;
        case TYPE_LONG:
            p.p(streamName + ".write_longlong(" + name + ");");
            break;
        case TYPE_FLOAT:
            p.p(streamName + ".write_float(" + name + ");");
            break;
        case TYPE_DOUBLE:
            p.p(streamName + ".write_double(" + name + ");");
            break;
        case TYPE_STRING:
            p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);");
            break;
        case TYPE_ANY:
            p.p("Util.writeAny("+ streamName + "," + name + ");");
            break;
        case TYPE_CORBA_OBJECT:
            p.p(streamName + ".write_Object(" + name + ");");
            break;
        case TYPE_REMOTE:
            p.p("Util.writeRemoteObject("+ streamName + "," + name + ");");
            break;
        case TYPE_ABSTRACT:
            p.p("Util.writeAbstractObject("+ streamName + "," + name + ");");
            break;
        case TYPE_NC_INTERFACE:
            p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);");
            break;
        case TYPE_VALUE:
            p.p(streamName + ".write_value(" + name + "," + getName(type) + ".class);");
            break;
        case TYPE_IMPLEMENTATION:
            p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);");
            break;
        case TYPE_NC_CLASS:
            p.p(streamName + ".write_value((Serializable)" + name + "," + getName(type) + ".class);");
            break;
        case TYPE_ARRAY:
            castArray = true;
            p.p(streamName + ".write_value(cast_array(" + name + ")," + getName(type) + ".class);");
            break;
        case TYPE_JAVA_RMI_REMOTE:
            p.p("Util.writeRemoteObject("+ streamName + "," + name + ");");
            break;
        default:
            throw new Error("unexpected type code: " + typeCode);
        }
    }

    /**
     * Write a snippet of Java code to unmarshal a value of type "type"
     * from the java.io.ObjectInput stream named "stream" into a variable
     * named "name" (if "name" is null, the value in unmarshalled and
     * discarded).
     */
    void writeUnmarshalArgument(IndentingWriter p,
                                String streamName,
                                Type type,
                                String name) throws IOException {

        int typeCode = getTypeCode(type);

        if (name != null) {
            p.p(name + " = ");
        }

        switch (typeCode) {
        case TYPE_BOOLEAN:
            p.p(streamName + ".read_boolean();");
            break;
        case TYPE_BYTE:
            p.p(streamName + ".read_octet();");
            break;
        case TYPE_CHAR:
            p.p(streamName + ".read_wchar();");
            break;
        case TYPE_SHORT:
            p.p(streamName + ".read_short();");
            break;
        case TYPE_INT:
            p.p(streamName + ".read_long();");
            break;
        case TYPE_LONG:
            p.p(streamName + ".read_longlong();");
            break;
        case TYPE_FLOAT:
            p.p(streamName + ".read_float();");
            break;
        case TYPE_DOUBLE:
            p.p(streamName + ".read_double();");
            break;
        case TYPE_STRING:
            p.p("(String) " + streamName + ".read_value(" + getName(type) + ".class);");
            break;
        case TYPE_ANY:
            if (type.getIdentifier() != idJavaLangObject) {
                p.p("(" + getName(type) + ") ");
            }
            p.p("Util.readAny(" + streamName + ");");
            break;
        case TYPE_CORBA_OBJECT:
            if (type.getIdentifier() == idCorbaObject) {
                p.p("(" + getName(type) + ") " + streamName + ".read_Object();");
            } else {
                p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);");
            }
            break;
        case TYPE_REMOTE:
            String objName = testUtil(getName(type), type);
            p.p("(" + objName + ") " +
                "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + objName + ".class);");
            break;
        case TYPE_ABSTRACT:
            p.p("(" + getName(type) + ") " + streamName + ".read_abstract_interface();");
            break;
        case TYPE_NC_INTERFACE:
            p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
            break;
        case TYPE_VALUE:
            p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
            break;
        case TYPE_IMPLEMENTATION:
            p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
            break;
        case TYPE_NC_CLASS:
            p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
            break;
        case TYPE_ARRAY:
            p.p("(" + getName(type) + ") " + streamName + ".read_value(" + getName(type) + ".class);");
            break;
        case TYPE_JAVA_RMI_REMOTE:
            p.p("(" + getName(type) + ") " +
                "PortableRemoteObject.narrow(" + streamName + ".read_Object(), " + getName(type) + ".class);");
            //      p.p("(" + getName(type) + ") " + streamName + ".read_Object(" + getStubName(type) + ".class);");
            break;
        default:
            throw new Error("unexpected type code: " + typeCode);
        }
    }

    /**
     * Get a list of all the RepositoryIDs for interfaces
     * implemented directly or indirectly by theType. In the
     * case of an  ImplementationType which implements 2 or
     * more remote interfaces, this list will begin with the
     * Identifier for the implementation (see section 5.9 in
     * the Java -> IDL mapping). Ensures that the most derived
     * type is first in the list because the IOR is generated
     * using that entry in the _ids array.
     */
    String[] getAllRemoteRepIDs (CompoundType theType) {

        String[] result;

        // Collect up all the (inherited) remote interfaces
        // (ignores all the 'special' interfaces: Remote,
        // Serializable, Externalizable)...

        Type[] types = collectAllRemoteInterfaces(theType);

        int length = types.length;
        boolean haveImpl = theType instanceof ImplementationType;
        InterfaceType[] interfaces = theType.getInterfaces();
        int remoteCount = countRemote(interfaces,false);
        int offset = 0;

        // Do we have an implementation type that implements
        // more than one remote interface?

        if (haveImpl && remoteCount > 1) {

            // Yes, so we need to insert it at the beginning...

            result = new String[length + 1];
            result[0] = getRepositoryID(theType);
            offset = 1;

        } else {

            // No.

            result = new String[length];

            // Here we need to ensure that the most derived
            // interface ends up being first in the list. If
            // there is only one, we're done.

            if (length > 1) {

                // First, decide what the most derived type is...

                String mostDerived = null;

                if (haveImpl) {

                    // If we get here, we know that there is only one
                    // direct remote interface, so just find it...

                    for (int i = 0; i < interfaces.length; i++) {
                        if (interfaces[i].isType(TYPE_REMOTE)) {
                            mostDerived = interfaces[i].getRepositoryID();
                            break;
                        }
                    }
                } else {

                    // If we get here we know that theType is a RemoteType
                    // so just use its id...

                    mostDerived = theType.getRepositoryID();
                }

                // Now search types list and make sure mostDerived is
                // at index zero...

                for (int i = 0; i < length; i++) {
                    if (types[i].getRepositoryID() == mostDerived) {

                        // Found it. Swap it if we need to...

                        if (i > 0) {
                            Type temp = types[0];
                            types[0] = types[i];
                            types[i] = temp;
                        }

                        break;
                    }
                }
            }
        }

        // Now copy contents of the types array...

        for (int i = 0; i < types.length; i++) {
            result[offset++] = getRepositoryID(types[i]);
        }

        // If we're supposed to, reverse the array. This
        // is only done when the -testReverseIDs flag is
        // passed, and that should ONLY be done for test
        // cases. This is an undocumented feature.

        if (reverseIDs) {
            int start = 0;
            int end = result.length -1;
            while (start < end) {
                String temp = result[start];
                result[start++] = result[end];
                result[end--] = temp;
            }
        }

        return result;
    }

    /**
     * Collect all the inherited remote interfaces.
     */
    Type[] collectAllRemoteInterfaces (CompoundType theType) {
        Vector list = new Vector();

        // Collect up all the Remote interfaces, and get an instance
        // for java.rmi.Remote...

        addRemoteInterfaces(list,theType);

        // Create and return our results...

        Type[] result = new Type[list.size()];
        list.copyInto(result);

        return result;
    }

    /**
     * Add all the inherited remote interfaces to list.
     */
    void addRemoteInterfaces(Vector list, CompoundType theType) {

        if (theType != null) {
            if (theType.isInterface() && !list.contains(theType)) {
                list.addElement(theType);
            }

            InterfaceType[] interfaces = theType.getInterfaces();
            for (int i = 0; i < interfaces.length; i++) {

                if (interfaces[i].isType(TYPE_REMOTE)) {
                    addRemoteInterfaces(list,interfaces[i]);
                }
            }

            addRemoteInterfaces(list,theType.getSuperclass());
        }
    }

    /**
     * Get a list of all the remote interfaces which this stub
     * should declare.
     */
    RemoteType[] getDirectRemoteInterfaces (CompoundType theType) {

        RemoteType[] result;
        InterfaceType[] interfaces = theType.getInterfaces();

        // First, get a list of all the interfaces...

        InterfaceType[] list;

        // Because we can be passed either an ImplementationType
        // (which has interfaces) or a RemoteType (which is an
        // interface and may have interfaces) we must handle each
        // separately...

        // Do we have an implementation type?

        if (theType instanceof ImplementationType) {

            // Yes, so list is exactly what this type
            // implements and is correct already.

            list = interfaces;

        } else {

            // No, so list is just theType...

            list = new InterfaceType[1];
            list[0] = (InterfaceType) theType;
        }

        // Ok, now count up the remote interfaces, allocate
        // our result and fill it in...

        int remoteCount = countRemote(list,false);

        if (remoteCount == 0) {
            throw new CompilerError("iiop.StubGenerator: No remote interfaces!");
        }

        result = new RemoteType[remoteCount];
        int offset = 0;
        for (int i = 0; i < list.length; i++) {
            if (list[i].isType(TYPE_REMOTE)) {
                result[offset++] = (RemoteType)list[i];
            }
        }

        return result;
    }

    int countRemote (Type[] list, boolean includeAbstract) {
        int remoteCount = 0;
        for (int i = 0; i < list.length; i++) {
            if (list[i].isType(TYPE_REMOTE) &&
                (includeAbstract || !list[i].isType(TYPE_ABSTRACT))) {
                remoteCount++;
            }
        }

        return remoteCount;
    }

    void writeCastArray(IndentingWriter p) throws IOException {
        if (castArray) {
            p.pln();
            p.pln("// This method is required as a work-around for");
            p.pln("// a bug in the JDK 1.1.6 verifier.");
            p.pln();
            p.plnI("private "+getName(idJavaIoSerializable)+" cast_array(Object obj) {");
            p.pln("return ("+getName(idJavaIoSerializable)+")obj;");
            p.pOln("}");
        }
    }
    void writeIds(IndentingWriter p, CompoundType theType, boolean isTie
                  ) throws IOException {
        p.plnI("private static final String[] _type_ids = {");

        String[] ids = getAllRemoteRepIDs(theType);

        if (ids.length >0 ) {
            for(int i = 0; i < ids.length; i++) {
                if (i > 0)
                    p.pln(", ");
                p.p("\"" + ids[i] + "\"");
            }
        } else {
           // Must be an implementation which only implements Remote...
           p.pln("\"\"");
        }
        String qname = theType.getQualifiedName() ;
        boolean isTransactional = isTie && transactionalObjects.containsKey( qname ) ;
        // Add TransactionalObject if needed.
        if (isTransactional) {
            // Have already written an id.
            p.pln( ", " ) ;
            p.pln( "\"IDL:omg.org/CosTransactions/TransactionalObject:1.0\"" ) ;
        } else if (ids.length > 0) {
            p.pln();
        }
        p.pOln("};");
    }


    /**
     * Write the Tie for the remote class to a stream.
     */
    protected void writeTie(OutputType outputType,
                            IndentingWriter p) throws IOException
    {
        CompoundType theType = (CompoundType) outputType.getType();
        RemoteType[] remoteInterfaces = null;

        // Write comment...
        p.pln("// Tie class generated by rmic, do not edit.");
        p.pln("// Contents subject to change without notice.");
        p.pln();

        // Set our standard classes...
        setStandardClassesInUse(theType,false);

        // Add classes for this type...
        addClassesInUse(theType,remoteInterfaces);

        // Write package and import statements...
        writePackageAndImports(p);

        // Declare the tie class.
        p.p("public class " + currentClass + " extends " +
            getName(tieBaseClass) + " implements Tie");

        // Add java.rmi.Remote if this type does not implement it.
        // This allows stubs for Abstract interfaces to be treated
        // uniformly...
        if (!implementsRemote(theType)) {
            p.pln(",");
            p.p(getName("java.rmi.Remote"));
        }

        p.plnI(" {");

        // Write data members...
        p.pln();
        p.pln("volatile private " + getName(theType) + " target = null;");
        p.pln();

        // Write the ids...
        writeIds( p, theType, true ) ;

        // Write setTarget method...
        p.pln();
        p.plnI("public void setTarget(Remote target) {");
        p.pln("this.target = (" + getName(theType) + ") target;");
        p.pOln("}");

        // Write getTarget method...
        p.pln();
        p.plnI("public Remote getTarget() {");
        p.pln("return target;");
        p.pOln("}");

        // Write thisObject method...
        p.pln();
        write_tie_thisObject_method(p,idCorbaObject);

        // Write deactivate method...
        p.pln();
        write_tie_deactivate_method(p);

        // Write get orb method...
        p.pln();
        p.plnI("public ORB orb() {");
        p.pln("return _orb();");
        p.pOln("}");

        // Write set orb method...
        p.pln();
        write_tie_orb_method(p);

        // Write the _ids() method...
        p.pln();
        write_tie__ids_method(p);

        // Get all the methods...
        CompoundType.Method[] remoteMethods = theType.getMethods();

        // Register all the argument names used, plus our
        // data member names...

        addNamesInUse(remoteMethods);
        addNameInUse("target");
        addNameInUse("_type_ids");

        // Write the _invoke method...
        p.pln();

        String in = getVariableName("in");
        String _in = getVariableName("_in");
        String ex = getVariableName("ex");
        String method = getVariableName("method");
        String reply = getVariableName("reply");

        p.plnI("public OutputStream  _invoke(String "+method+", InputStream "+_in+", " +
               "ResponseHandler "+reply+") throws SystemException {");

        if (remoteMethods.length > 0) {
            p.plnI("try {");
            p.pln(getName(theType) + " target = this.target;");
            p.plnI("if (target == null) {");
            p.pln("throw new java.io.IOException();");
            p.pOln("}");
            p.plnI(idExtInputStream + " "+in+" = ");
            p.pln("(" + idExtInputStream + ") "+_in+";");
            p.pO();

            // See if we should use a hash table style
            // comparison...

            StaticStringsHash hash = getStringsHash(remoteMethods);

            if (hash != null) {
                p.plnI("switch ("+method+"."+hash.method+") {");
                for (int i = 0; i < hash.buckets.length; i++) {
                    p.plnI("case "+hash.keys[i]+": ");
                    for (int j = 0; j < hash.buckets[i].length; j++) {
                        CompoundType.Method current = remoteMethods[hash.buckets[i][j]];
                        if (j > 0) {
                            p.pO("} else ");
                        }
                        p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {");
                        writeTieMethod(p, theType,current);
                    }
                    p.pOln("}");
                    p.pO();
                }
            } else {
                for(int i = 0; i < remoteMethods.length; i++) {
                CompoundType.Method current = remoteMethods[i];
                if (i > 0) {
                    p.pO("} else ");
                }

                p.plnI("if ("+method+".equals(\""+ current.getIDLName() +"\")) {");
                writeTieMethod(p, theType, current);
            }
            }

            if (hash != null) {
                p.pI();
                //        p.plnI("default:");
            } else {
                //   p.pOlnI("} else {");
            }
            //              p.pln("throw new "+getName(idBadMethodException)+"();");

            if (hash != null) {
                p.pO();
            }
            p.pOln("}");
            p.pln("throw new "+getName(idBadMethodException)+"();");

            p.pOlnI("} catch ("+getName(idSystemException)+" "+ex+") {");
            p.pln("throw "+ex+";");

            p.pOlnI("} catch ("+getName(idJavaLangThrowable)+" "+ex+") {");
            p.pln("throw new " + getName(idPortableUnknownException) + "("+ex+");");
            p.pOln("}");
        } else {
            // No methods...

            p.pln("throw new " + getName(idBadMethodException) + "();");
        }

        p.pOln("}");            // end invoke

        // Write the cast array hack...

        writeCastArray(p);

        // End tie class...
        p.pOln("}");
    }
    public void catchWrongPolicy(IndentingWriter p) throws IOException {
        p.pln("");
    }
    public void catchServantNotActive(IndentingWriter p) throws IOException {
        p.pln("");
    }
    public void catchObjectNotActive(IndentingWriter p) throws IOException {
        p.pln("");
    }

    public void write_tie_thisObject_method(IndentingWriter p,
                                            Identifier idCorbaObject)
        throws IOException
    {
        if(POATie){
            p.plnI("public " + idCorbaObject + " thisObject() {");
            /*
            p.pln("org.omg.CORBA.Object objref = null;");
            p.pln("try{");
            p.pln("objref = _poa().servant_to_reference(this);");
            p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){");
            catchWrongPolicy(p);
            p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){");
            catchServantNotActive(p);
            p.pln("}");
            p.pln("return objref;");
            */
            p.pln("return _this_object();");
            p.pOln("}");
        } else {
            p.plnI("public " + idCorbaObject + " thisObject() {");
            p.pln("return this;");
            p.pOln("}");
        }
    }

    public void write_tie_deactivate_method(IndentingWriter p)
        throws IOException
    {
        if(POATie){
            p.plnI("public void deactivate() {");
            p.pln("try{");
            p.pln("_poa().deactivate_object(_poa().servant_to_id(this));");
            p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){");
            catchWrongPolicy(p);
            p.pln("}catch (org.omg.PortableServer.POAPackage.ObjectNotActive exception){");
            catchObjectNotActive(p);
            p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){");
            catchServantNotActive(p);
            p.pln("}");
            p.pOln("}");
        } else {
            p.plnI("public void deactivate() {");
            p.pln("_orb().disconnect(this);");
            p.pln("_set_delegate(null);");
            p.pln("target = null;");
            p.pOln("}");
        }
    }

    public void write_tie_orb_method(IndentingWriter p)
        throws IOException
    {
        if(POATie){
        p.plnI("public void orb(ORB orb) {");
        /*
        p.pln("try{");
        p.pln("orb.connect(_poa().servant_to_reference(this));");
        p.pln("}catch (org.omg.PortableServer.POAPackage.WrongPolicy exception){");
        catchWrongPolicy(p);
        p.pln("}catch (org.omg.PortableServer.POAPackage.ServantNotActive exception){");
        catchServantNotActive(p);
        p.pln("}");
        */
        p.pln("try {");
        p.pln("    ((org.omg.CORBA_2_3.ORB)orb).set_delegate(this);");
        p.pln("}");
        p.pln("catch(ClassCastException e) {");
        p.pln("    throw new org.omg.CORBA.BAD_PARAM");
        p.pln("        (\"POA Servant requires an instance of org.omg.CORBA_2_3.ORB\");");
        p.pln("}");
        p.pOln("}");
        } else {
        p.plnI("public void orb(ORB orb) {");
        p.pln("orb.connect(this);");
        p.pOln("}");
        }
    }

    public void write_tie__ids_method(IndentingWriter p)
        throws IOException
    {
        if(POATie){
        p.plnI("public String[] _all_interfaces(org.omg.PortableServer.POA poa, byte[] objectId){");
        p.pln("return (String[]) _type_ids.clone();");
        p.pOln("}");
        } else {
        p.plnI("public String[] _ids() { ");
        p.pln("return (String[]) _type_ids.clone();");
        p.pOln("}");
        }
    }


    StaticStringsHash getStringsHash (CompoundType.Method[] methods) {
        if (useHash && methods.length > 1) {
            String[] methodNames = new String[methods.length];
            for (int i = 0; i < methodNames.length; i++) {
                methodNames[i] = methods[i].getIDLName();
            }
            return new StaticStringsHash(methodNames);
        }
        return null;
    }

    static boolean needNewReadStreamClass(Type type) {
        if (type.isType(TYPE_ABSTRACT)) {
            return true;
        }
        // Handle late-breaking special case for
        // abstract IDL entities...
        if ((type instanceof CompoundType) &&
            ((CompoundType)type).isAbstractBase()) {
            return true;
        }
        return needNewWriteStreamClass(type);
    }

    static boolean needNewWriteStreamClass(Type type) {
        switch (type.getTypeCode()) {
        case TYPE_VOID:
        case TYPE_BOOLEAN:
        case TYPE_BYTE:
        case TYPE_CHAR:
        case TYPE_SHORT:
        case TYPE_INT:
        case TYPE_LONG:
        case TYPE_FLOAT:
        case TYPE_DOUBLE:           return false;

        case TYPE_STRING:           return true;
        case TYPE_ANY:              return false;
        case TYPE_CORBA_OBJECT:     return false;
        case TYPE_REMOTE:           return false;
        case TYPE_ABSTRACT:         return false;
        case TYPE_NC_INTERFACE:     return true;
        case TYPE_VALUE:            return true;
        case TYPE_IMPLEMENTATION:   return true;
        case TYPE_NC_CLASS:         return true;
        case TYPE_ARRAY:            return true;
        case TYPE_JAVA_RMI_REMOTE:  return false;

        default: throw new Error("unexpected type code: " + type.getTypeCode());
        }
    }

    /*
     * Decide which arguments need to be copied and write
     * the copy code. Returns an array of argument names to
     * use to refer to either the copy or the original.
     */
    String[] writeCopyArguments(CompoundType.Method method,
                                IndentingWriter p) throws IOException {

        Type[] args = method.getArguments();
        String[] origNames = method.getArgumentNames();

        // Copy the current parameter names to a result array...

        String[] result = new String[origNames.length];
        for (int i = 0; i < result.length; i++) {
            result[i] = origNames[i];
        }

        // Decide which arguments must be copied, if any. If
        // any of the arguments are types for which a 'real' copy
        // will be done, rather than just an autoConnect, set
        // realCopy = true. Note that abstract types may only
        // need autoConnect, but we cannot know that at compile
        // time...

        boolean realCopy = false;
        boolean[] copyArg = new boolean[args.length];
        int copyCount = 0;
        int firstCopiedArg = 0; // Only used in single copy case.  It is only the first arg that
                                // needs copying IF copyCount == 1.

        for (int i = 0; i < args.length; i++) {
            if (mustCopy(args[i])) {
                copyArg[i] = true;
                copyCount++;
                firstCopiedArg = i;
                if (args[i].getTypeCode() != TYPE_REMOTE &&
                    args[i].getTypeCode() != TYPE_IMPLEMENTATION) {
                    realCopy = true;
                }
            } else {
                copyArg[i] = false;
            }
        }

        // Do we have any types which must be copied?
        if (copyCount > 0) {
            // Yes. Are we only doing the copy to ensure
            // that autoConnect occurs?
            if (realCopy) {
                // Nope. We need to go back thru the list and
                // mark any strings so that they will be copied
                // to preserve any shared references...
                for (int i = 0; i < args.length; i++) {
                    if (args[i].getTypeCode() == TYPE_STRING) {
                        copyArg[i] = true;
                        copyCount++;
                    }
                }
            }

            // We're ready to generate code. Do we have more than
            // one to copy?
            if (copyCount > 1) {
                // Generate a call to copyObjects...
                String arrayName = getVariableName("copies");
                p.p("Object[] " + arrayName + " = Util.copyObjects(new Object[]{");
                boolean first = true;
                for (int i = 0; i < args.length; i++) {
                    if (copyArg[i]) {
                        if (!first) {
                            p.p(",");
                        }
                        first = false;
                        p.p(origNames[i]);
                    }
                }
                p.pln("},_orb());");

                // For each of the types which was copied, create
                // a local temporary for it, updating the result
                // array with the new local parameter name...
                int copyIndex = 0 ;
                for (int i = 0; i < args.length; i++) {
                    if (copyArg[i]) {
                        result[i] = getVariableName(result[i]+"Copy");
                        p.pln( getName(args[i]) + " " + result[i] + " = (" + getName(args[i]) + ") " +
                               arrayName + "[" + copyIndex++ +"];");
                    }
                }
            } else {
                // Generate a call to copyObject, updating the result
                // with the new local parameter name...
                result[firstCopiedArg] = getVariableName(result[firstCopiedArg]+"Copy");
                p.pln( getName(args[firstCopiedArg]) + " " + result[firstCopiedArg] + " = (" +
                       getName(args[firstCopiedArg]) + ") Util.copyObject(" +
                       origNames[firstCopiedArg] + ",_orb());");
            }
        }

        return result;
    }

    static final String SINGLE_SLASH = "\\";
    static final String DOUBLE_SLASH = SINGLE_SLASH + SINGLE_SLASH;

    String getRepositoryID(Type type) {
        return IDLNames.replace(type.getRepositoryID(), SINGLE_SLASH, DOUBLE_SLASH);
    }

    String getExceptionRepositoryID(Type type) {
        ClassType theType = (ClassType) type;
        return IDLNames.getIDLRepositoryID(theType.getQualifiedIDLExceptionName(false));
    }

    String getVariableName(String proposed) {
        while (namesInUse.contains(proposed)) {
            proposed = "$" + proposed;
        }

        return proposed;
    }

    void addNamesInUse(CompoundType.Method[] methods) {
        for (int i = 0; i < methods.length; i++) {
            addNamesInUse(methods[i]);
        }
    }

    void addNamesInUse(CompoundType.Method method) {
        String paramNames[] = method.getArgumentNames();
        for (int i = 0; i < paramNames.length; i++) {
            addNameInUse(paramNames[i]);
        }
    }

    void addNameInUse(String name) {
        namesInUse.add(name);
    }

    static boolean mustCopy(Type type) {
        switch (type.getTypeCode()) {
        case TYPE_VOID:
        case TYPE_BOOLEAN:
        case TYPE_BYTE:
        case TYPE_CHAR:
        case TYPE_SHORT:
        case TYPE_INT:
        case TYPE_LONG:
        case TYPE_FLOAT:
        case TYPE_DOUBLE:
        case TYPE_STRING:           return false;

        case TYPE_ANY:              return true;

        case TYPE_CORBA_OBJECT:     return false;

        case TYPE_REMOTE:
        case TYPE_ABSTRACT:
        case TYPE_NC_INTERFACE:
        case TYPE_VALUE:
        case TYPE_IMPLEMENTATION:
        case TYPE_NC_CLASS:
        case TYPE_ARRAY:
        case TYPE_JAVA_RMI_REMOTE:  return true;

        default: throw new Error("unexpected type code: " + type.getTypeCode());
        }
    }

    ValueType[] getStubExceptions (CompoundType.Method method, boolean sort) {

        ValueType[] list = method.getFilteredStubExceptions(method.getExceptions());

        // Sort the list so that all org.omg.CORBA.UserException
        // subtypes are at the beginning of the list.  This ensures
        // that the stub will not call read_string() before calling
        // XXHelper.read().

        if (sort) {
            Arrays.sort(list,new UserExceptionComparator());
            }

        return list;
                }

    ValueType[] getTieExceptions (CompoundType.Method method) {
        return method.getUniqueCatchList(method.getImplExceptions());
    }

    void writeTieMethod(IndentingWriter p, CompoundType type,
                        CompoundType.Method method) throws IOException {
        String methodName = method.getName();
        Type paramTypes[] = method.getArguments();
        String paramNames[] = method.getArgumentNames();
        Type returnType = method.getReturnType();
        ValueType[] exceptions = getTieExceptions(method);
        String in = getVariableName("in");
        String ex = getVariableName("ex");
        String out = getVariableName("out");
        String reply = getVariableName("reply");

        for (int i = 0; i < paramTypes.length; i++) {
            p.p(getName(paramTypes[i])+" "+paramNames[i]+" = ");
            writeUnmarshalArgument(p, in, paramTypes[i], null);
            p.pln();
        }

        boolean handleExceptions = exceptions != null;
        boolean doReturn = !returnType.isType(TYPE_VOID);

        if (handleExceptions && doReturn) {
            String objName = testUtil(getName(returnType), returnType);
            p.pln(objName+" result;");
        }

        if (handleExceptions)
            p.plnI("try {");

        if (doReturn) {
            if (handleExceptions) {
                p.p("result = ");
            } else {
                p.p(getName(returnType)+" result = ");
            }
        }

        p.p("target."+methodName+"(");
        for(int i = 0; i < paramNames.length; i++) {
            if (i > 0)
                p.p(", ");
            p.p(paramNames[i]);
        }
        p.pln(");");

        if (handleExceptions) {
            for(int i = 0; i < exceptions.length; i++) {
                p.pOlnI("} catch ("+getName(exceptions[i])+" "+ex+") {");

                // Is this our IDLEntity Exception special case?

                if (exceptions[i].isIDLEntityException() && !exceptions[i].isCORBAUserException()) {

                                // Yes...

                    String helperName = IDLNames.replace(exceptions[i].getQualifiedIDLName(false),"::",".");
                    helperName += "Helper";
                    p.pln(idOutputStream+" "+out +" = "+reply+".createExceptionReply();");
                    p.pln(helperName+".write("+out+","+ex+");");

                } else {

                                // No...

                    p.pln("String id = \"" + getExceptionRepositoryID(exceptions[i]) + "\";");
                p.plnI(idExtOutputStream + " "+out+" = ");
                p.pln("(" + idExtOutputStream + ") "+reply+".createExceptionReply();");
                p.pOln(out+".write_string(id);");
                    p.pln(out+".write_value("+ex+"," + getName(exceptions[i]) + ".class);");
                }

                p.pln("return "+out+";");
            }
            p.pOln("}");
        }

        if (needNewWriteStreamClass(returnType)) {
            p.plnI(idExtOutputStream + " "+out+" = ");
            p.pln("(" + idExtOutputStream + ") "+reply+".createReply();");
            p.pO();
        } else {
            p.pln("OutputStream "+out+" = "+reply+".createReply();");
        }

        if (doReturn) {
            writeMarshalArgument(p, out, returnType, "result");
            p.pln();
        }

        p.pln("return "+out+";");
    }


    /**
     * Write Java statements to marshal a series of values in order as
     * named in the "names" array, with types as specified in the "types"
     * array", to the java.io.ObjectOutput stream named "stream".
     */
    void writeMarshalArguments(IndentingWriter p,
                               String streamName,
                               Type[] types, String[] names)
        throws IOException
    {
        if (types.length != names.length) {
            throw new Error("paramter type and name arrays different sizes");
        }

        for (int i = 0; i < types.length; i++) {
            writeMarshalArgument(p, streamName, types[i], names[i]);
            if (i != types.length -1) {
                p.pln();
            }
        }
    }

    /**
     * Added for IASRI 4987274. Remote classes named "Util" were
     * getting confused with javax.rmi.CORBA.Util and the
     * unqualifiedName "Util".
     */
    String testUtil(String objectName, Type ttype) {
        if (objectName.equals("Util")) {
                String correctedName = (String)ttype.getPackageName() + "." + objectName;
                return correctedName;
        } else {
                return objectName;
        }
    }
}

class StringComparator implements java.util.Comparator {
    public int compare(Object o1, Object o2) {
        String s1 = (String)o1;
        String s2 = (String)o2;
        return s1.compareTo(s2);
    }
}


class UserExceptionComparator implements java.util.Comparator {
    public int compare(Object o1, Object o2) {
        ValueType v1 = (ValueType)o1;
        ValueType v2 = (ValueType)o2;
        int result = 0;
        if (isUserException(v1)) {
            if (!isUserException(v2)) {
                result = -1;
            }
        } else if (isUserException(v2)) {
            if (!isUserException(v1)) {
                result = 1;
            }
        }
        return result;
    }

    final boolean isUserException(ValueType it) {
        return it.isIDLEntityException() && !it.isCORBAUserException();
    }
}
