// Tie class generated by rmic, do not edit.
// Contents subject to change without notice.

import java.io.Serializable;
import java.net.InetAddress;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
import javax.rmi.CORBA.Tie;
import javax.rmi.CORBA.Util;
import org.omg.CORBA.BAD_OPERATION;
import org.omg.CORBA.ORB;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.InputStream;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.ResponseHandler;
import org.omg.CORBA.portable.UnknownException;
import org.omg.CORBA_2_3.portable.ObjectImpl;


public class _HelloImpl_Tie extends ObjectImpl implements Tie {

    private HelloImpl target = null;

    private static final String[] _type_ids = {
        "RMI:HelloInterface:0000000000000000"
    };

    public void setTarget(Remote target) {
        this.target = (HelloImpl) target;
    }

    public Remote getTarget() {
        return target;
    }

    public org.omg.CORBA.Object thisObject() {
        return this;
    }

    public void deactivate() {
        _orb().disconnect(this);
        _set_delegate(null);
        target = null;
    }

    public ORB orb() {
        return _orb();
    }

    public void orb(ORB orb) {
        orb.connect(this);
    }

    public String[] _ids() {
        return (String[]) _type_ids.clone();
    }

    public OutputStream  _invoke(String method, InputStream _in, ResponseHandler reply) throws SystemException {
        try {
            org.omg.CORBA_2_3.portable.InputStream in =
                (org.omg.CORBA_2_3.portable.InputStream) _in;
            switch (method.length()) {
                case 8:
                    if (method.equals("sayHello")) {
                        String arg0 = (String) in.read_value(String.class);
                        String result = target.sayHello(arg0);
                        org.omg.CORBA_2_3.portable.OutputStream out =
                            (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply();
                        out.write_value(result,String.class);
                        return out;
                    }
                case 14:
                    if (method.equals("sayHelloToTest")) {
                        Test arg0 = (Test) in.read_value(Test.class);
                        String result = target.sayHelloToTest(arg0);
                        org.omg.CORBA_2_3.portable.OutputStream out =
                            (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply();
                        out.write_value(result,String.class);
                        return out;
                    }
                case 19:
                    if (method.equals("sayHelloWithHashMap")) {
                        ConcurrentHashMap arg0 = (ConcurrentHashMap) in.read_value(ConcurrentHashMap.class);
                        String result = target.sayHelloWithHashMap(arg0);
                        org.omg.CORBA_2_3.portable.OutputStream out =
                            (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply();
                        out.write_value(result,String.class);
                        return out;
                    }
                case 20:
                    if (method.equals("sayHelloWithHashMap2")) {
                        HashMap arg0 = (HashMap) in.read_value(HashMap.class);
                        String result = target.sayHelloWithHashMap2(arg0);
                        org.omg.CORBA_2_3.portable.OutputStream out =
                            (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply();
                        out.write_value(result,String.class);
                        return out;
                    }
                case 23:
                    if (method.equals("sayHelloWithInetAddress")) {
                        InetAddress arg0 = (InetAddress) in.read_value(InetAddress.class);
                        String result = target.sayHelloWithInetAddress(arg0);
                        org.omg.CORBA_2_3.portable.OutputStream out =
                            (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply();
                        out.write_value(result,String.class);
                        return out;
                    }
                case 25:
                    if (method.equals("sayHelloWithReentrantLock")) {
                        ReentrantLock arg0 = (ReentrantLock) in.read_value(ReentrantLock.class);
                        String result = target.sayHelloWithReentrantLock(arg0);
                        org.omg.CORBA_2_3.portable.OutputStream out =
                            (org.omg.CORBA_2_3.portable.OutputStream) reply.createReply();
                        out.write_value(result,String.class);
                        return out;
                    }
            }
            throw new BAD_OPERATION();
        } catch (SystemException ex) {
            throw ex;
        } catch (Throwable ex) {
            throw new UnknownException(ex);
        }
    }
}
