/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.sessions.remote.rmi.iiop;


// Stub class generated by rmic, do not edit.
// Contents subject to change without notice.
import org.eclipse.persistence.internal.sessions.remote.Transporter;
import java.rmi.RemoteException;
import java.rmi.UnexpectedException;
import javax.rmi.CORBA.Stub;
import javax.rmi.CORBA.Util;
import org.omg.CORBA.SystemException;
import org.omg.CORBA.portable.ApplicationException;
import org.omg.CORBA.portable.OutputStream;
import org.omg.CORBA.portable.RemarshalException;
import org.omg.CORBA.portable.ServantObject;

/**
 * INTERNAL:
 */
public class _RMIRemoteSessionController_Stub extends Stub implements RMIRemoteSessionController {
    private static final String[] _type_ids = { "RMI:org.eclipse.persistence.sessions.remote.rmi.iiop.RMIRemoteSessionController:0000000000000000" };

    /**
     * Default constructor.
     */
    public _RMIRemoteSessionController_Stub() {
    }

    @Override
    public String[] _ids() {
        return _type_ids;
    }

    @Override
    public Transporter processCommand(Transporter remoteTransporter) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("processCommand", true);
                    out.write_value(remoteTransporter, Transporter.class);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return (Transporter)in.read_value(Transporter.class);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return processCommand(remoteTransporter);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("processCommand", RMIRemoteSessionController.class);
            if (so == null) {
                return processCommand(remoteTransporter);
            }
            try {
                Transporter remoteTransporterCopy = (Transporter)Util.copyObject(remoteTransporter, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).processCommand(remoteTransporterCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter beginTransaction() throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    OutputStream out = _request("beginTransaction", true);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return beginTransaction();
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("beginTransaction", RMIRemoteSessionController.class);
            if (so == null) {
                return beginTransaction();
            }
            try {
                Transporter result = ((RMIRemoteSessionController)so.servant).beginTransaction();
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter beginEarlyTransaction() throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    OutputStream out = _request("beginEarlyTransaction", true);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return beginTransaction();
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("beginEarlyTransaction", RMIRemoteSessionController.class);
            if (so == null) {
                return beginEarlyTransaction();
            }
            try {
                Transporter result = ((RMIRemoteSessionController)so.servant).beginTransaction();
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter commitRootUnitOfWork(Transporter remoteUnitOfWork) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("commitRootUnitOfWork", true);
                    writeTransporter(remoteUnitOfWork, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return commitRootUnitOfWork(remoteUnitOfWork);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("commitRootUnitOfWork", RMIRemoteSessionController.class);
            if (so == null) {
                return commitRootUnitOfWork(remoteUnitOfWork);
            }
            try {
                Transporter remoteUnitOfWorkCopy = (Transporter)Util.copyObject(remoteUnitOfWork, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).commitRootUnitOfWork(remoteUnitOfWorkCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter commitTransaction() throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    OutputStream out = _request("commitTransaction", true);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return commitTransaction();
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("commitTransaction", RMIRemoteSessionController.class);
            if (so == null) {
                return commitTransaction();
            }
            try {
                Transporter result = ((RMIRemoteSessionController)so.servant).commitTransaction();
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter cursoredStreamClose(Transporter remoetCursoredStreamID) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("cursoredStreamClose", true);
                    writeTransporter(remoetCursoredStreamID, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return cursoredStreamClose(remoetCursoredStreamID);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("cursoredStreamClose", RMIRemoteSessionController.class);
            if (so == null) {
                return cursoredStreamClose(remoetCursoredStreamID);
            }
            try {
                Transporter remoetCursoredStreamIDCopy = (Transporter)Util.copyObject(remoetCursoredStreamID, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).cursoredStreamClose(remoetCursoredStreamIDCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter cursoredStreamNextPage(Transporter remoteCursoredStream, int pageSize) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("cursoredStreamNextPage", true);
                    writeTransporter(remoteCursoredStream, out);
                    out.write_long(pageSize);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return cursoredStreamNextPage(remoteCursoredStream, pageSize);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("cursoredStreamNextPage", RMIRemoteSessionController.class);
            if (so == null) {
                return cursoredStreamNextPage(remoteCursoredStream, pageSize);
            }
            try {
                Transporter remoteCursoredStreamCopy = (Transporter)Util.copyObject(remoteCursoredStream, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).cursoredStreamNextPage(remoteCursoredStreamCopy, pageSize);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter cursoredStreamSize(Transporter cursoredStream) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("cursoredStreamSize", true);
                    writeTransporter(cursoredStream, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return cursoredStreamSize(cursoredStream);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("cursoredStreamSize", RMIRemoteSessionController.class);
            if (so == null) {
                return cursoredStreamSize(cursoredStream);
            }
            try {
                Transporter cursoredStreamCopy = (Transporter)Util.copyObject(cursoredStream, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).cursoredStreamSize(cursoredStreamCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter cursorSelectObjects(Transporter policy) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("cursorSelectObjects", true);
                    writeTransporter(policy, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return cursorSelectObjects(policy);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("cursorSelectObjects", RMIRemoteSessionController.class);
            if (so == null) {
                return cursorSelectObjects(policy);
            }
            try {
                Transporter policyCopy = (Transporter)Util.copyObject(policy, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).cursorSelectObjects(policyCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter executeNamedQuery(Transporter name, Transporter theClass, Transporter arguments) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("executeNamedQuery", true);
                    writeTransporter(name, out);
                    writeTransporter(theClass, out);
                    writeTransporter(arguments, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return executeNamedQuery(name, theClass, arguments);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("executeNamedQuery", RMIRemoteSessionController.class);
            if (so == null) {
                return executeNamedQuery(name, theClass, arguments);
            }
            try {
                Object[] copies = Util.copyObjects(new Object[] { name, theClass, arguments }, _orb());
                Transporter nameCopy = (Transporter)copies[0];
                Transporter theClassCopy = (Transporter)copies[1];
                Transporter argumentsCopy = (Transporter)copies[2];
                Transporter result = ((RMIRemoteSessionController)so.servant).executeNamedQuery(nameCopy, theClassCopy, argumentsCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter executeQuery(Transporter query) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("executeQuery", true);
                    writeTransporter(query, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return executeQuery(query);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("executeQuery", RMIRemoteSessionController.class);
            if (so == null) {
                return executeQuery(query);
            }
            try {
                Transporter queryCopy = (Transporter)Util.copyObject(query, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).executeQuery(queryCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter getDescriptor(Transporter domainClass) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("getDescriptor", true);
                    writeTransporter(domainClass, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);

                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return getDescriptor(domainClass);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("getDescriptor", RMIRemoteSessionController.class);
            if (so == null) {
                return getDescriptor(domainClass);
            }
            try {
                Transporter domainClassCopy = (Transporter)Util.copyObject(domainClass, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).getDescriptor(domainClassCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter getDescriptorForAlias(Transporter alias) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("getDescriptorForAlias", true);
                    writeTransporter(alias, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);

                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return getDescriptorForAlias(alias);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("getDescriptorForAlias", RMIRemoteSessionController.class);
            if (so == null) {
                return getDescriptorForAlias(alias);
            }
            try {
                Transporter domainClassCopy = (Transporter)Util.copyObject(alias, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).getDescriptorForAlias(domainClassCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter getDefaultReadOnlyClasses() throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    OutputStream out = _request("getDefaultReadOnlyClasses", true);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return getLogin();
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("getDefaultReadOnlyClasses", RMIRemoteSessionController.class);
            if (so == null) {
                return getDefaultReadOnlyClasses();
            }
            try {
                Transporter result = ((RMIRemoteSessionController)so.servant).getDefaultReadOnlyClasses();
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter getLogin() throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    OutputStream out = _request("_get_login", true);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return getLogin();
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("_get_login", RMIRemoteSessionController.class);
            if (so == null) {
                return getLogin();
            }
            try {
                Transporter result = ((RMIRemoteSessionController)so.servant).getLogin();
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter getSequenceNumberNamed(Transporter remoteFunctionCall) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("getSequenceNumberNamed", true);
                    writeTransporter(remoteFunctionCall, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return getSequenceNumberNamed(remoteFunctionCall);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("getSequenceNumberNamed", RMIRemoteSessionController.class);
            if (so == null) {
                return getSequenceNumberNamed(remoteFunctionCall);
            }
            try {
                Transporter remoteFunctionCallCopy = (Transporter)Util.copyObject(remoteFunctionCall, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).getSequenceNumberNamed(remoteFunctionCallCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter initializeIdentityMapsOnServerSession() throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    OutputStream out = _request("initializeIdentityMapsOnServerSession", true);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return initializeIdentityMapsOnServerSession();
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("initializeIdentityMapsOnServerSession", RMIRemoteSessionController.class);
            if (so == null) {
                return initializeIdentityMapsOnServerSession();
            }
            try {
                Transporter result = ((RMIRemoteSessionController)so.servant).initializeIdentityMapsOnServerSession();
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter instantiateRemoteValueHolderOnServer(Transporter remoteValueHolder) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("instantiateRemoteValueHolderOnServer", true);
                    writeTransporter(remoteValueHolder, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return instantiateRemoteValueHolderOnServer(remoteValueHolder);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("instantiateRemoteValueHolderOnServer", RMIRemoteSessionController.class);
            if (so == null) {
                return instantiateRemoteValueHolderOnServer(remoteValueHolder);
            }
            try {
                Transporter remoteValueHolderCopy = (Transporter)Util.copyObject(remoteValueHolder, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).instantiateRemoteValueHolderOnServer(remoteValueHolderCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    /**
     * Insert the method's description here.
     * Creation date: (8/15/00 9:07:19 AM)
     * @return org.eclipse.persistence.internal.sessions.remote.Transporter
     * @param stream org.omg.CORBA_2_3.portable.InputStream
     */
    public static org.eclipse.persistence.internal.sessions.remote.Transporter readTransporter(org.omg.CORBA.portable.InputStream stream) {
        int length = stream.read_ulong();

        byte[] bytes = new byte[length];
        stream.read_octet_array(bytes, 0, length);

        java.io.ByteArrayInputStream byteIn = new java.io.ByteArrayInputStream(bytes);
        org.eclipse.persistence.internal.sessions.remote.Transporter transporter = null;
        if (bytes.length == 0) {
            return null;
        }
        try {
            java.io.ObjectInputStream objectIn = new java.io.ObjectInputStream(byteIn);
            transporter = (org.eclipse.persistence.internal.sessions.remote.Transporter)objectIn.readObject();
        } catch (Exception exception) {
            exception.printStackTrace();
            return null;
        }

        return transporter;
    }

    @Override
    public Transporter rollbackTransaction() throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    OutputStream out = _request("rollbackTransaction", true);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return rollbackTransaction();
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("rollbackTransaction", RMIRemoteSessionController.class);
            if (so == null) {
                return rollbackTransaction();
            }
            try {
                Transporter result = ((RMIRemoteSessionController)so.servant).rollbackTransaction();
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorAbsolute(Transporter remoteScrollableCursorOid, int rows) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorAbsolute", true);
                    writeTransporter(remoteScrollableCursorOid, out);
                    out.write_long(rows);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorAbsolute(remoteScrollableCursorOid, rows);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorAbsolute", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorAbsolute(remoteScrollableCursorOid, rows);
            }
            try {
                Transporter remoteScrollableCursorOidCopy = (Transporter)Util.copyObject(remoteScrollableCursorOid, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorAbsolute(remoteScrollableCursorOidCopy, rows);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorAfterLast(Transporter remoteScrollableCursorOid) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorAfterLast", true);
                    writeTransporter(remoteScrollableCursorOid, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorAfterLast(remoteScrollableCursorOid);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorAfterLast", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorAfterLast(remoteScrollableCursorOid);
            }
            try {
                Transporter remoteScrollableCursorOidCopy = (Transporter)Util.copyObject(remoteScrollableCursorOid, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorAfterLast(remoteScrollableCursorOidCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorBeforeFirst(Transporter remoteScrollableCursor) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorBeforeFirst", true);
                    writeTransporter(remoteScrollableCursor, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorBeforeFirst(remoteScrollableCursor);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorBeforeFirst", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorBeforeFirst(remoteScrollableCursor);
            }
            try {
                Transporter remoteScrollableCursorCopy = (Transporter)Util.copyObject(remoteScrollableCursor, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorBeforeFirst(remoteScrollableCursorCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorClose(Transporter remoteScrollableCursorOid) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorClose", true);
                    writeTransporter(remoteScrollableCursorOid, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorClose(remoteScrollableCursorOid);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorClose", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorClose(remoteScrollableCursorOid);
            }
            try {
                Transporter remoteScrollableCursorOidCopy = (Transporter)Util.copyObject(remoteScrollableCursorOid, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorClose(remoteScrollableCursorOidCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorCurrentIndex(Transporter remoteScrollableCursor) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorCurrentIndex", true);
                    writeTransporter(remoteScrollableCursor, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorCurrentIndex(remoteScrollableCursor);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorCurrentIndex", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorCurrentIndex(remoteScrollableCursor);
            }
            try {
                Transporter remoteScrollableCursorCopy = (Transporter)Util.copyObject(remoteScrollableCursor, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorCurrentIndex(remoteScrollableCursorCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorFirst(Transporter remoteScrollableCursor) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorFirst", true);
                    writeTransporter(remoteScrollableCursor, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorFirst(remoteScrollableCursor);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorFirst", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorFirst(remoteScrollableCursor);
            }
            try {
                Transporter remoteScrollableCursorCopy = (Transporter)Util.copyObject(remoteScrollableCursor, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorFirst(remoteScrollableCursorCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorIsAfterLast(Transporter remoteScrollableCursor) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorIsAfterLast", true);
                    writeTransporter(remoteScrollableCursor, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorIsAfterLast(remoteScrollableCursor);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorIsAfterLast", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorIsAfterLast(remoteScrollableCursor);
            }
            try {
                Transporter remoteScrollableCursorCopy = (Transporter)Util.copyObject(remoteScrollableCursor, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorIsAfterLast(remoteScrollableCursorCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorIsBeforeFirst(Transporter remoteScrollableCursor) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorIsBeforeFirst", true);
                    writeTransporter(remoteScrollableCursor, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorIsBeforeFirst(remoteScrollableCursor);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorIsBeforeFirst", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorIsBeforeFirst(remoteScrollableCursor);
            }
            try {
                Transporter remoteScrollableCursorCopy = (Transporter)Util.copyObject(remoteScrollableCursor, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorIsBeforeFirst(remoteScrollableCursorCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorIsFirst(Transporter remoteScrollableCursor) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorIsFirst", true);
                    writeTransporter(remoteScrollableCursor, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorIsFirst(remoteScrollableCursor);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorIsFirst", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorIsFirst(remoteScrollableCursor);
            }
            try {
                Transporter remoteScrollableCursorCopy = (Transporter)Util.copyObject(remoteScrollableCursor, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorIsFirst(remoteScrollableCursorCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorIsLast(Transporter remoteScrollableCursor) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorIsLast", true);
                    writeTransporter(remoteScrollableCursor, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorIsLast(remoteScrollableCursor);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorIsLast", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorIsLast(remoteScrollableCursor);
            }
            try {
                Transporter remoteScrollableCursorCopy = (Transporter)Util.copyObject(remoteScrollableCursor, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorIsLast(remoteScrollableCursorCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorLast(Transporter remoteScrollableCursor) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorLast", true);
                    writeTransporter(remoteScrollableCursor, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorLast(remoteScrollableCursor);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorLast", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorLast(remoteScrollableCursor);
            }
            try {
                Transporter remoteScrollableCursorCopy = (Transporter)Util.copyObject(remoteScrollableCursor, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorLast(remoteScrollableCursorCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorNextObject(Transporter scrollableCursorOid) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorNextObject", true);
                    writeTransporter(scrollableCursorOid, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorNextObject(scrollableCursorOid);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorNextObject", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorNextObject(scrollableCursorOid);
            }
            try {
                Transporter scrollableCursorOidCopy = (Transporter)Util.copyObject(scrollableCursorOid, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorNextObject(scrollableCursorOidCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorPreviousObject(Transporter scrollableCursorOid) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorPreviousObject", true);
                    writeTransporter(scrollableCursorOid, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorPreviousObject(scrollableCursorOid);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorPreviousObject", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorPreviousObject(scrollableCursorOid);
            }
            try {
                Transporter scrollableCursorOidCopy = (Transporter)Util.copyObject(scrollableCursorOid, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorPreviousObject(scrollableCursorOidCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorRelative(Transporter remoteScrollableCursor, int rows) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorRelative", true);
                    writeTransporter(remoteScrollableCursor, out);
                    out.write_long(rows);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorRelative(remoteScrollableCursor, rows);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorRelative", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorRelative(remoteScrollableCursor, rows);
            }
            try {
                Transporter remoteScrollableCursorCopy = (Transporter)Util.copyObject(remoteScrollableCursor, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorRelative(remoteScrollableCursorCopy, rows);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    @Override
    public Transporter scrollableCursorSize(Transporter cursoredStream) throws RemoteException {
        if (!Util.isLocal(this)) {
            try {
                org.omg.CORBA_2_3.portable.InputStream in = null;
                try {
                    org.omg.CORBA_2_3.portable.OutputStream out = (org.omg.CORBA_2_3.portable.OutputStream)_request("scrollableCursorSize", true);
                    writeTransporter(cursoredStream, out);
                    in = (org.omg.CORBA_2_3.portable.InputStream)_invoke(out);
                    return readTransporter(in);
                } catch (ApplicationException ex) {
                    in = (org.omg.CORBA_2_3.portable.InputStream)ex.getInputStream();
                    String id = in.read_string();
                    throw new UnexpectedException(id);
                } catch (RemarshalException ex) {
                    return scrollableCursorSize(cursoredStream);
                } finally {
                    _releaseReply(in);
                }
            } catch (SystemException ex) {
                throw Util.mapSystemException(ex);
            }
        } else {
            ServantObject so = _servant_preinvoke("scrollableCursorSize", RMIRemoteSessionController.class);
            if (so == null) {
                return scrollableCursorSize(cursoredStream);
            }
            try {
                Transporter cursoredStreamCopy = (Transporter)Util.copyObject(cursoredStream, _orb());
                Transporter result = ((RMIRemoteSessionController)so.servant).scrollableCursorSize(cursoredStreamCopy);
                return (Transporter)Util.copyObject(result, _orb());
            } catch (Throwable ex) {
                Throwable exCopy = (Throwable)Util.copyObject(ex, _orb());
                throw Util.wrapException(exCopy);
            } finally {
                _servant_postinvoke(so);
            }
        }
    }

    /**
     * Insert the method's description here.
     * Creation date: (8/15/00 9:05:39 AM)
     * @param stream org.omg.CORBA_2_3.portable.OutputStream
     * @param transporter org.eclipse.persistence.internal.sessions.remote.Transporter
     */
    public static void writeTransporter(org.eclipse.persistence.internal.sessions.remote.Transporter transporter, org.omg.CORBA.portable.OutputStream stream) {
        java.io.ByteArrayOutputStream byteOut = new java.io.ByteArrayOutputStream();
        try {
            java.io.ObjectOutputStream objectOut = new java.io.ObjectOutputStream(byteOut);
            objectOut.writeObject(transporter);
            objectOut.flush();
            stream.write_ulong(byteOut.size());
            stream.write_octet_array(byteOut.toByteArray(), 0, byteOut.size());
        } catch (java.io.IOException exception) {
        }
    }
}
