[jboss-remoting-commits] JBoss Remoting SVN: r5804 - in remoting3/trunk: jboss-remoting and 10 other directories.

jboss-remoting-commits at lists.jboss.org jboss-remoting-commits at lists.jboss.org
Mon Mar 8 18:18:31 EST 2010


Author: david.lloyd at jboss.com
Date: 2010-03-08 18:18:30 -0500 (Mon, 08 Mar 2010)
New Revision: 5804

Added:
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRemoteReplyHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRemoteRequestHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandlerConnector.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/TerminatingLocalRequestHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/LocalReplyHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/LocalRequestHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemoteReplyHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemoteRequestHandler.java
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalValueTestCase.java
Removed:
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ReplyHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandler.java
Modified:
   remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingReplyHandler.java
   remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingRequestHandler.java
   remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingReplyHandler.java
   remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingRequestHandler.java
   remoting3/trunk/jboss-remoting/pom.xml
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnector.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnectorImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientListener.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Connection.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ConnectionImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureReplyImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalConnectionHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalConnectionProvider.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemoteClassTable.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestContextImpl.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestHandlerFactory.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientAuthenticationHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundClient.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyExceptionTask.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyTask.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundClient.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequest.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/PrimaryExternalizerFactory.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ReceivedRequestHandlerConnector.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteMessageHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerAuthenticationHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/UnsentRequestHandlerConnector.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/SimpleClientCallbackHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandlerContext.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ProtocolServiceType.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemotingServiceDescriptor.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandlerConnector.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/SpiUtils.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/InputStreamHandlerFactory.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/ObjectPipe.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/OutputStreamHandlerFactory.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/ReaderInputStream.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamContext.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamHandler.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamHandlerFactory.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/Streams.java
   remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/WriterOutputStream.java
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/AbstractRemoteTestCase.java
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/CloseableTestCase.java
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/EndpointTestCase.java
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalTestCase.java
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteSslTestCase.java
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/StreamsTestCase.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/LocalBasicExampleMain.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StringRot13ClientListener.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/RequestHandlerFuture.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketClientConnectionHandler.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketClientRequestHandler.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketRequestHandlerConnector.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketClientListener.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerConnectionHandler.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerReplyHandler.java
   remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerRequestHandler.java
Log:
JBREM-1207 - Pass by value; JBREM-1203 - Streams; JBREM-1205 - Class loader specification; JBREM-1206 - SPI Asymmetry problem

Modified: remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingReplyHandler.java
===================================================================
--- remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingReplyHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingReplyHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,18 +22,18 @@
 
 package org.jboss.remoting3.compat;
 
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
 import org.jboss.remoting3.RemoteExecutionException;
 import java.io.IOException;
 
 /**
  * A reply handler which unwraps a Remoting 2-style invocation response to a Remoting 3-style plain object.
  */
-public final class UnwrappingReplyHandler implements ReplyHandler {
+public final class UnwrappingReplyHandler implements RemoteReplyHandler {
 
-    private final ReplyHandler replyHandler;
+    private final RemoteReplyHandler replyHandler;
 
-    public UnwrappingReplyHandler(final ReplyHandler replyHandler) {
+    public UnwrappingReplyHandler(final RemoteReplyHandler replyHandler) {
         this.replyHandler = replyHandler;
     }
 

Modified: remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingRequestHandler.java
===================================================================
--- remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingRequestHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/UnwrappingRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,8 +22,8 @@
 
 package org.jboss.remoting3.compat;
 
-import org.jboss.remoting3.spi.RequestHandler;
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
 import org.jboss.remoting3.RemoteRequestException;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoUtils;
@@ -36,11 +36,11 @@
  * A request handler which unwraps a Remoting 2-style invocation request to a Remoting 3-style plain object
  * or {@link org.jboss.remoting3.compat.Request} instance.
  */
-public final class UnwrappingRequestHandler extends AbstractAutoCloseable<RequestHandler> implements RequestHandler {
+public final class UnwrappingRequestHandler extends AbstractAutoCloseable<RemoteRequestHandler> implements RemoteRequestHandler {
 
     private static final Logger log = Logger.getLogger("org.jboss.remoting.compat");
 
-    private final RequestHandler next;
+    private final RemoteRequestHandler next;
 
     /**
      * Basic constructor.
@@ -48,12 +48,12 @@
      * @param executor the executor used to execute the close notification handlers
      * @param next
      */
-    protected UnwrappingRequestHandler(final Executor executor, final RequestHandler next) {
+    protected UnwrappingRequestHandler(final Executor executor, final RemoteRequestHandler next) {
         super(executor);
         this.next = next;
     }
 
-    public Cancellable receiveRequest(final Object request, final ReplyHandler replyHandler) {
+    public Cancellable receiveRequest(final Object request, final RemoteReplyHandler replyHandler) {
         if (request instanceof CompatabilityInvocationRequest) {
             final CompatabilityInvocationRequest invocationRequest = (CompatabilityInvocationRequest) request;
             final Map<Object,Object> map = invocationRequest.getRequestPayload();

Modified: remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingReplyHandler.java
===================================================================
--- remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingReplyHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingReplyHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,17 +22,17 @@
 
 package org.jboss.remoting3.compat;
 
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
 import java.io.IOException;
 
 /**
  * A request handler which wraps a Remoting 3-style reply with a Remoting 2-style invocation response.
  */
-public final class WrappingReplyHandler implements ReplyHandler {
+public final class WrappingReplyHandler implements RemoteReplyHandler {
 
-    private final ReplyHandler replyHandler;
+    private final RemoteReplyHandler replyHandler;
 
-    public WrappingReplyHandler(final ReplyHandler replyHandler) {
+    public WrappingReplyHandler(final RemoteReplyHandler replyHandler) {
         this.replyHandler = replyHandler;
     }
 

Modified: remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingRequestHandler.java
===================================================================
--- remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingRequestHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/compat/src/main/java/org/jboss/remoting3/compat/WrappingRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,8 +22,8 @@
 
 package org.jboss.remoting3.compat;
 
-import org.jboss.remoting3.spi.RequestHandler;
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
 import java.util.concurrent.Executor;
 import org.jboss.xnio.Cancellable;
 
@@ -31,16 +31,16 @@
  * A request handler which wraps a Remoting 3-style plain request (or an instance of {@link org.jboss.remoting3.compat.Request Request}
  * with a Remoting 2-style invocation request.
  */
-public final class WrappingRequestHandler extends AbstractAutoCloseable<RequestHandler> implements RequestHandler {
+public final class WrappingRequestHandler extends AbstractAutoCloseable<RemoteRequestHandler> implements RemoteRequestHandler {
 
-    private final RequestHandler next;
+    private final RemoteRequestHandler next;
 
-    public WrappingRequestHandler(final RequestHandler next, final Executor executor) {
+    public WrappingRequestHandler(final RemoteRequestHandler next, final Executor executor) {
         super(executor);
         this.next = next;
     }
 
-    public Cancellable receiveRequest(final Object obj, final ReplyHandler replyHandler) {
+    public Cancellable receiveRequest(final Object obj, final RemoteReplyHandler replyHandler) {
         final CompatabilityInvocationRequest cir = new CompatabilityInvocationRequest();
         if (obj instanceof Request) {
             final Request request = (Request) obj;

Modified: remoting3/trunk/jboss-remoting/pom.xml
===================================================================
--- remoting3/trunk/jboss-remoting/pom.xml	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/pom.xml	2010-03-08 23:18:30 UTC (rev 5804)
@@ -95,6 +95,8 @@
                             <value>false</value>
                         </property>
                     </systemProperties>
+                    <printSummary>true</printSummary>
+                    <reportFormat>plain</reportFormat>
                 </configuration>
             </plugin>
             <plugin>

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnector.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnector.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnector.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -41,6 +41,16 @@
     IoFuture<? extends Client<I, O>> getFutureClient() throws SecurityException;
 
     /**
+     * Get the future client associated with this connector.  This method may only be called after this connector
+     * has passed over its associated connection.
+     *
+     * @param classloader the explicit classloader to use for unmarshalling replies
+     * @return the future client
+     * @throws SecurityException if this client is being accessed from the wrong peer
+     */
+    IoFuture<? extends Client<I, O>> getFutureClient(ClassLoader classloader) throws SecurityException;
+
+    /**
      * Get the client context associated with this connector.  This method may only be called from the originating
      * side of the connection.
      *

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnectorImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnectorImpl.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientConnectorImpl.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,13 +22,13 @@
 
 package org.jboss.remoting3;
 
+import java.io.IOException;
+import java.io.Serializable;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
-import org.jboss.remoting3.spi.RequestHandler;
 import org.jboss.xnio.FutureResult;
 import org.jboss.xnio.IoFuture;
 import org.jboss.xnio.TranslatingResult;
-import java.io.Serializable;
-import java.io.IOException;
 
 final class ClientConnectorImpl<I, O> implements ClientConnector<I, O>, Serializable {
 
@@ -37,11 +37,11 @@
     private transient final ClientContext clientContext;
 
     private final RequestHandlerConnector requestHandlerConnector;
-    private final Endpoint endpoint;
+    private final EndpointImpl endpoint;
     private final Class<I> requestClass;
     private final Class<O> replyClass;
 
-    ClientConnectorImpl(final RequestHandlerConnector requestHandlerConnector, final Endpoint endpoint, final Class<I> requestClass, final Class<O> replyClass, final ClientContext clientContext) {
+    ClientConnectorImpl(final RequestHandlerConnector requestHandlerConnector, final EndpointImpl endpoint, final Class<I> requestClass, final Class<O> replyClass, final ClientContext clientContext) {
         this.requestHandlerConnector = requestHandlerConnector;
         this.endpoint = endpoint;
         this.requestClass = requestClass;
@@ -50,10 +50,14 @@
     }
 
     public IoFuture<? extends Client<I, O>> getFutureClient() throws SecurityException {
+        return getFutureClient(Thread.currentThread().getContextClassLoader());
+    }
+
+    public IoFuture<? extends Client<I, O>> getFutureClient(final ClassLoader classloader) throws SecurityException {
         final FutureResult<Client<I, O>> futureResult = new FutureResult<Client<I, O>>();
-        requestHandlerConnector.createRequestHandler(new TranslatingResult<RequestHandler, Client<I, O>>(futureResult) {
-            protected Client<I, O> translate(final RequestHandler input) throws IOException {
-                return endpoint.createClient(input, requestClass, replyClass);
+        requestHandlerConnector.createRequestHandler(new TranslatingResult<RemoteRequestHandler, Client<I, O>>(futureResult) {
+            protected Client<I, O> translate(final RemoteRequestHandler input) throws IOException {
+                return endpoint.createClient(input, requestClass, replyClass, classloader);
             }
         });
         return futureResult.getIoFuture();

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientImpl.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientImpl.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -23,11 +23,12 @@
 package org.jboss.remoting3;
 
 import java.io.IOException;
-import java.util.concurrent.Executor;
 import java.util.concurrent.CancellationException;
-import org.jboss.remoting3.spi.ReplyHandler;
-import org.jboss.remoting3.spi.RequestHandler;
+import java.util.concurrent.Executor;
 import org.jboss.remoting3.spi.AbstractHandleableCloseable;
+import org.jboss.remoting3.spi.LocalReplyHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
+import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoFuture;
 import org.jboss.xnio.IoUtils;
@@ -40,25 +41,23 @@
 
     private static final Logger log = Logger.getLogger("org.jboss.remoting.client");
 
-    private final RequestHandler handler;
+    private final RemoteRequestHandler handler;
     private final Class<I> requestClass;
     private final Class<O> replyClass;
+    private final ClassLoader clientClassLoader;
     private final Attachments attachments = new AttachmentsImpl();
 
-    private ClientImpl(final RequestHandler handler, final Executor executor, final Class<I> requestClass, final Class<O> replyClass) {
+    private ClientImpl(final RemoteRequestHandler handler, final Executor executor, final Class<I> requestClass, final Class<O> replyClass, final ClassLoader clientClassLoader) {
         super(executor);
         this.handler = handler;
         this.requestClass = requestClass;
         this.replyClass = replyClass;
+        this.clientClassLoader = clientClassLoader;
     }
 
-    static <I, O> ClientImpl<I, O> create(final RequestHandler handler, final Executor executor, final Class<I> requestClass, final Class<O> replyClass) {
-        final ClientImpl<I, O> ci = new ClientImpl<I, O>(handler, executor, requestClass, replyClass);
-        handler.addCloseHandler(new CloseHandler<RequestHandler>() {
-            public void handleClose(final RequestHandler closed) {
-                IoUtils.safeClose(ci);
-            }
-        });
+    static <I, O> ClientImpl<I, O> create(final RemoteRequestHandler handler, final Executor executor, final Class<I> requestClass, final Class<O> replyClass, final ClassLoader clientClassLoader) {
+        final ClientImpl<I, O> ci = new ClientImpl<I, O>(handler, executor, requestClass, replyClass, clientClassLoader);
+        handler.addCloseHandler(SpiUtils.closingCloseHandler(ci));
         return ci;
     }
 
@@ -81,8 +80,8 @@
        log.trace("Client.invoke() sending request \"%s\"", request);
        final I actualRequest = castRequest(request);
        final QueueExecutor executor = new QueueExecutor();
-       final FutureReplyImpl<T> futureReply = new FutureReplyImpl<T>(executor, replyClass);
-       final ReplyHandler replyHandler = futureReply.getReplyHandler();
+       final FutureReplyImpl<T> futureReply = new FutureReplyImpl<T>(executor, replyClass, clientClassLoader);
+       final LocalReplyHandler replyHandler = futureReply.getReplyHandler();
        final Cancellable requestContext = handler.receiveRequest(actualRequest, replyHandler);
        futureReply.setRemoteRequestContext(requestContext);
        futureReply.addNotifier(IoUtils.attachmentClosingNotifier(), executor);
@@ -108,8 +107,8 @@
         log.trace("Client.invoke() sending request \"%s\"", typedRequest);
         final I actualRequest = castRequest(typedRequest);
         final QueueExecutor executor = new QueueExecutor();
-        final FutureReplyImpl<T> futureReply = new FutureReplyImpl<T>(executor, typedRequest);
-        final ReplyHandler replyHandler = futureReply.getReplyHandler();
+        final FutureReplyImpl<T> futureReply = new FutureReplyImpl<T>(executor, typedRequest, clientClassLoader);
+        final LocalReplyHandler replyHandler = futureReply.getReplyHandler();
         final Cancellable requestContext = handler.receiveRequest(actualRequest, replyHandler);
         futureReply.setRemoteRequestContext(requestContext);
         futureReply.addNotifier(IoUtils.attachmentClosingNotifier(), executor);
@@ -138,8 +137,8 @@
         }
         log.trace("Client.send() sending request \"%s\"", request);
         final I actualRequest = castRequest(request);
-        final FutureReplyImpl<T> futureReply = new FutureReplyImpl<T>(getExecutor(), replyClass);
-        final ReplyHandler replyHandler = futureReply.getReplyHandler();
+        final FutureReplyImpl<T> futureReply = new FutureReplyImpl<T>(getExecutor(), replyClass, clientClassLoader);
+        final LocalReplyHandler replyHandler = futureReply.getReplyHandler();
         final Cancellable requestContext = handler.receiveRequest(actualRequest, replyHandler);
         futureReply.setRemoteRequestContext(requestContext);
         return futureReply;
@@ -151,18 +150,15 @@
         }
         log.trace("Client.send() sending request \"%s\"", typedRequest);
         final I actualRequest = castRequest(typedRequest);
-        final FutureReplyImpl<T> futureReply = new FutureReplyImpl<T>(getExecutor(), typedRequest);
-        final ReplyHandler replyHandler = futureReply.getReplyHandler();
+        final FutureReplyImpl<T> futureReply = new FutureReplyImpl<T>(getExecutor(), typedRequest, clientClassLoader);
+        final LocalReplyHandler replyHandler = futureReply.getReplyHandler();
         final Cancellable requestContext = handler.receiveRequest(actualRequest, replyHandler);
         futureReply.setRemoteRequestContext(requestContext);
         return futureReply;
     }
 
-    /**
+    /*
      * Since type is erased, it's possible that the wrong type was passed.
-     * @param request
-     * @return
-     * @throws RemoteRequestException
      */
     private I castRequest(final Object request) throws RemoteRequestException {
         try {
@@ -176,7 +172,7 @@
         return "client instance <" + Integer.toHexString(hashCode()) + ">";
     }
 
-    RequestHandler getRequestHandler() {
+    RemoteRequestHandler getRequestHandler() {
         return handler;
     }
 

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientListener.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientListener.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ClientListener.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -23,6 +23,7 @@
 package org.jboss.remoting3;
 
 import java.util.EventListener;
+import org.jboss.xnio.OptionMap;
 
 /**
  * A client listener associated with a service.  When a client is opened for this service, a new request listener
@@ -42,7 +43,8 @@
      * If {@code null} is returned, the client is closed with an error.
      *
      * @param clientContext the client context
+     * @param optionMap the service open options
      * @return the request listener
      */
-    RequestListener<I, O> handleClientOpen(ClientContext clientContext);
+    RequestListener<I, O> handleClientOpen(ClientContext clientContext, OptionMap optionMap);
 }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Connection.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Connection.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Connection.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,8 +22,8 @@
 
 package org.jboss.remoting3;
 
+import java.io.IOException;
 import org.jboss.xnio.IoFuture;
-import java.io.IOException;
 import org.jboss.xnio.OptionMap;
 
 /**
@@ -61,6 +61,21 @@
     <I, O> IoFuture<? extends Client<I, O>> openClient(String serviceType, String groupName, Class<I> requestClass, Class<O> replyClass, OptionMap optionMap);
 
     /**
+     * Locate and open a client on the remote side of this connection.
+     *
+     * @param serviceType the service type
+     * @param groupName the group name
+     * @param requestClass the request class
+     * @param replyClass the reply class
+     * @param classLoader the class loader to use to unmarshall incoming messages
+     * @param optionMap the option map
+     * @param <I> the request type
+     * @param <O> the reply type
+     * @return the future client
+     */
+    <I, O> IoFuture<? extends Client<I, O>> openClient(String serviceType, String groupName, Class<I> requestClass, Class<O> replyClass, ClassLoader classLoader, OptionMap optionMap);
+
+    /**
      * Create a client connector which may <b>only</b> transmitted to the remote side of this connection, allowing
      * it to use the included service.
      *

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ConnectionImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ConnectionImpl.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/ConnectionImpl.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -23,15 +23,18 @@
 package org.jboss.remoting3;
 
 import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import org.jboss.remoting3.spi.AbstractHandleableCloseable;
 import org.jboss.remoting3.spi.ConnectionHandler;
 import org.jboss.remoting3.spi.ConnectionHandlerFactory;
 import org.jboss.remoting3.spi.ConnectionProviderContext;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
+import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.FutureResult;
 import org.jboss.xnio.IoFuture;
-import org.jboss.xnio.IoUtils;
 import org.jboss.xnio.OptionMap;
 import org.jboss.xnio.TranslatingResult;
 
@@ -59,8 +62,23 @@
     }
 
     public <I, O> IoFuture<? extends Client<I, O>> openClient(final String serviceType, final String groupName, final Class<I> requestClass, final Class<O> replyClass, final OptionMap optionMap) {
+        ClassLoader classLoader;
+        final SecurityManager sm = System.getSecurityManager();
+        if (sm == null) {
+            classLoader = Thread.currentThread().getContextClassLoader();
+        } else {
+            classLoader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
+                public ClassLoader run() {
+                    return Thread.currentThread().getContextClassLoader();
+                }
+            });
+        }
+        return openClient(serviceType, groupName, requestClass, replyClass, classLoader, optionMap);
+    }
+
+    public <I, O> IoFuture<? extends Client<I, O>> openClient(final String serviceType, final String groupName, final Class<I> requestClass, final Class<O> replyClass, final ClassLoader classLoader, final OptionMap optionMap) {
         final FutureResult<Client<I, O>> futureResult = new FutureResult<Client<I, O>>();
-        futureResult.addCancelHandler(connectionHandler.open(serviceType, groupName, new ClientWrapper<I, O>(endpoint, futureResult, requestClass, replyClass)));
+        futureResult.addCancelHandler(connectionHandler.open(serviceType, groupName, new ClientWrapper<I, O>(endpoint, futureResult, requestClass, replyClass, classLoader), classLoader, optionMap));
         return futureResult.getIoFuture();
     }
 
@@ -69,14 +87,10 @@
     }
 
     public <I, O> ClientConnector<I, O> createClientConnector(final RequestListener<I, O> listener, final Class<I> requestClass, final Class<O> replyClass, final OptionMap optionMap) throws IOException {
-        final RequestHandler localRequestHandler = endpoint.createLocalRequestHandler(listener, requestClass, replyClass);
+        final ClientContextImpl context = new ClientContextImpl(getExecutor(), this);
+        final LocalRequestHandler localRequestHandler = endpoint.createLocalRequestHandler(listener, context, requestClass, replyClass, optionMap);
         final RequestHandlerConnector connector = connectionHandler.createConnector(localRequestHandler);
-        final ClientContextImpl context = new ClientContextImpl(getExecutor(), this);
-        context.addCloseHandler(new CloseHandler<ClientContext>() {
-            public void handleClose(final ClientContext closed) {
-                IoUtils.safeClose(localRequestHandler);
-            }
-        });
+        context.addCloseHandler(SpiUtils.closingCloseHandler(localRequestHandler));
         return new ClientConnectorImpl<I, O>(connector, endpoint, requestClass, replyClass, context);
     }
 
@@ -88,21 +102,23 @@
         return "Connection to " + name;
     }
 
-    private static class ClientWrapper<I, O> extends TranslatingResult<RequestHandler, Client<I, O>> {
+    private static class ClientWrapper<I, O> extends TranslatingResult<RemoteRequestHandler, Client<I, O>> {
 
         private final Class<I> requestClass;
         private final Class<O> replyClass;
         private final EndpointImpl endpoint;
+        private final ClassLoader classLoader;
 
-        public ClientWrapper(final EndpointImpl endpoint, final FutureResult<Client<I, O>> futureResult, final Class<I> requestClass, final Class<O> replyClass) {
+        public ClientWrapper(final EndpointImpl endpoint, final FutureResult<Client<I, O>> futureResult, final Class<I> requestClass, final Class<O> replyClass, final ClassLoader classLoader) {
             super(futureResult);
             this.requestClass = requestClass;
             this.replyClass = replyClass;
             this.endpoint = endpoint;
+            this.classLoader = classLoader;
         }
 
-        protected Client<I, O> translate(final RequestHandler input) throws IOException {
-            return endpoint.createClient(input, requestClass, replyClass);
+        protected Client<I, O> translate(final RemoteRequestHandler input) throws IOException {
+            return endpoint.createClient(input, requestClass, replyClass, classLoader);
         }
     }
 }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CopyOnWriteHashMap.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,17 +22,18 @@
 
 package org.jboss.remoting3;
 
-import java.util.Map;
-import java.util.Set;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
 import static java.util.Collections.emptyMap;
 import static java.util.Collections.singletonMap;
+import static java.util.Collections.unmodifiableCollection;
 import static java.util.Collections.unmodifiableMap;
-import static java.util.Collections.unmodifiableCollection;
 import static java.util.Collections.unmodifiableSet;
-import java.util.concurrent.ConcurrentMap;
 
 final class CopyOnWriteHashMap<K, V> implements ConcurrentMap<K, V> {
     private final boolean identity;

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Endpoint.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -26,7 +26,6 @@
 import java.net.URI;
 import java.util.Set;
 import org.jboss.remoting3.spi.ConnectionProviderFactory;
-import org.jboss.remoting3.spi.RequestHandler;
 import org.jboss.remoting3.spi.ProtocolServiceType;
 import org.jboss.xnio.IoFuture;
 import org.jboss.xnio.OptionMap;
@@ -178,35 +177,29 @@
     Registration addServiceRegistrationListener(ServiceRegistrationListener listener, Set<ListenerFlag> flags);
 
     /**
-     * Create a request handler that can be used to receive incoming requests on this endpoint.  The client may be passed to a
-     * remote endpoint as part of a request or a reply, or it may be used locally.
-     * <p/>
-     * You must have the {@link org.jboss.remoting3.security.RemotingPermission createRequestHandler EndpointPermission} to invoke this method.
+     * Create a local client for a client listener.
      *
-     * @param requestListener the request listener
-     * @param requestClass the class of requests sent to this request listener
-     * @param replyClass the class of replies received back from this request listener
-     * @param <I> the request type
-     * @param <O> the reply type
-     * @return the request handler
+     * @param clientListener the client listener
+     * @param requestClass the request class
+     * @param replyClass the reply class
+     * @param clientClassLoader the class loader to use for replies
+     * @param optionMap the options
+     * @return a new client
      * @throws IOException if an error occurs
      */
-    <I, O> RequestHandler createLocalRequestHandler(RequestListener<? super I, ? extends O> requestListener, Class<I> requestClass, Class<O> replyClass) throws IOException;
+    <I, O> Client<I, O> createLocalClient(ClientListener<I, O> clientListener, Class<I> requestClass, Class<O> replyClass, ClassLoader clientClassLoader, OptionMap optionMap) throws IOException;
 
     /**
-     * Create a client that uses the given request handler to handle its requests.
-     * <p/>
-     * You must have the {@link org.jboss.remoting3.security.RemotingPermission createClient EndpointPermission} to invoke this method.
+     * Create a local client for a client listener.
      *
-     * @param <I> the request type
-     * @param <O> the reply type
-     * @param handler the request handler
-     * @param requestClass the class of requests sent through this client
-     * @param replyClass the class of replies received back through this client
-     * @return the client
+     * @param clientListener
+     * @param requestClass the request class
+     * @param replyClass the reply class
+     * @param optionMap the options
+     * @return a new client
      * @throws IOException if an error occurs
      */
-    <I, O> Client<I, O> createClient(RequestHandler handler, Class<I> requestClass, Class<O> replyClass) throws IOException;
+    <I, O> Client<I, O> createLocalClient(ClientListener<I, O> clientListener, Class<I> requestClass, Class<O> replyClass, OptionMap optionMap) throws IOException;
 
     /**
      * Open a connection with a peer.  Returns a future connection which may be used to cancel the connection attempt.

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -49,8 +49,10 @@
 import org.jboss.remoting3.spi.ConnectionProvider;
 import org.jboss.remoting3.spi.ConnectionProviderContext;
 import org.jboss.remoting3.spi.ConnectionProviderFactory;
+import org.jboss.remoting3.spi.LocalRequestHandler;
 import org.jboss.remoting3.spi.ProtocolServiceType;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
+import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.FutureResult;
 import org.jboss.xnio.IoFuture;
 import org.jboss.xnio.IoUtils;
@@ -138,7 +140,6 @@
      */
     private final ConnectionProviderContext connectionProviderContext;
 
-    private static final RemotingPermission CREATE_REQUEST_HANDLER_PERM = new RemotingPermission("createRequestHandler");
     private static final RemotingPermission REGISTER_SERVICE_PERM = new RemotingPermission("registerService");
     private static final RemotingPermission CREATE_CLIENT_PERM = new RemotingPermission("createClient");
     private static final RemotingPermission ADD_SERVICE_LISTENER_PERM = new RemotingPermission("addServiceListener");
@@ -193,7 +194,7 @@
         }
     }
 
-    public <I, O> RequestHandler createLocalRequestHandler(final RequestListener<? super I, ? extends O> requestListener, final Class<I> requestClass, final Class<O> replyClass) throws IOException {
+    <I, O> LocalRequestHandler createLocalRequestHandler(final RequestListener<? super I, ? extends O> requestListener, final ClientContextImpl clientContext, final Class<I> requestClass, final Class<O> replyClass, final OptionMap optionMap) throws IOException {
         if (requestListener == null) {
             throw new IllegalArgumentException("requestListener is null");
         }
@@ -203,13 +204,8 @@
         if (replyClass == null) {
             throw new IllegalArgumentException("replyClass is null");
         }
-        SecurityManager sm = System.getSecurityManager();
-        if (sm != null) {
-            sm.checkPermission(CREATE_REQUEST_HANDLER_PERM);
-        }
         checkOpen();
-        final ClientContextImpl clientContext = new ClientContextImpl(executor, null);
-        final LocalRequestHandler<I, O> localRequestHandler = new LocalRequestHandler<I, O>(executor, requestListener, clientContext, requestClass, replyClass, requestListener.getClass().getClassLoader());
+        final TerminatingLocalRequestHandler<I, O> localRequestHandler = new TerminatingLocalRequestHandler<I, O>(executor, requestListener, clientContext, requestClass, replyClass, requestListener.getClass().getClassLoader());
         final WeakCloseable lrhCloseable = new WeakCloseable(localRequestHandler);
         clientContext.addCloseHandler(new CloseHandler<ClientContext>() {
             public void handleClose(final ClientContext closed) {
@@ -221,8 +217,8 @@
                 IoUtils.safeClose(lrhCloseable);
             }
         });
-        localRequestHandler.addCloseHandler(new CloseHandler<RequestHandler>() {
-            public void handleClose(final RequestHandler closed) {
+        localRequestHandler.addCloseHandler(new CloseHandler<LocalRequestHandler>() {
+            public void handleClose(final LocalRequestHandler closed) {
                 key.remove();
             }
         });
@@ -333,6 +329,7 @@
                 final String canonServiceType = serviceType.toLowerCase();
                 final String canonGroupName = groupName.toLowerCase();
                 final Executor executor = EndpointImpl.this.executor;
+                final ClassLoader classLoader = this.classLoader == null ? clientListener.getClass().getClassLoader() : this.classLoader;
                 final Map<String, Map<String, ServiceRegistrationInfo>> registeredLocalServices = localServiceIndex;
                 final RequestHandlerFactory<I, O> handlerFactory = RequestHandlerFactory.create(executor, clientListener, requestType, replyType, classLoader);
                 final ServiceRegistrationInfo registration = new ServiceRegistrationInfo(serviceType, groupName, name, optionMap, handlerFactory);
@@ -402,8 +399,7 @@
                 serviceInfo.setRegistrationHandle(handle);
                 serviceInfo.setRequestClass(requestType);
                 serviceInfo.setReplyClass(replyType);
-                final ClassLoader classLoader = this.classLoader;
-                serviceInfo.setServiceClassLoader(classLoader == null ? clientListener.getClass().getClassLoader() : classLoader);
+                serviceInfo.setServiceClassLoader(classLoader);
                 executor.execute(new Runnable() {
                     public void run() {
                         final Iterator<Map.Entry<Registration,ServiceRegistrationListener>> iter = serviceListenerRegistrations;
@@ -428,7 +424,7 @@
         log.error(t, "Service listener threw an exception");
     }
 
-    public <I, O> Client<I, O> createClient(final RequestHandler requestHandler, final Class<I> requestType, final Class<O> replyType) throws IOException {
+    <I, O> Client<I, O> createClient(final RemoteRequestHandler requestHandler, final Class<I> requestType, final Class<O> replyType, final ClassLoader clientClassLoader) throws IOException {
         SecurityManager sm = System.getSecurityManager();
         if (sm != null) {
             sm.checkPermission(CREATE_CLIENT_PERM);
@@ -443,14 +439,10 @@
             throw new NullPointerException("replyType is null");
         }
         checkOpen();
-        final ClientImpl<I, O> client = ClientImpl.create(requestHandler, executor, requestType, replyType);
+        final ClientImpl<I, O> client = ClientImpl.create(requestHandler, executor, requestType, replyType, clientClassLoader);
         final WeakCloseable lrhCloseable = new WeakCloseable(client);
         // this registration closes the client when the endpoint is closed
-        final Key key = addCloseHandler(new CloseHandler<Endpoint>() {
-            public void handleClose(final Endpoint closed) {
-                IoUtils.safeClose(lrhCloseable);
-            }
-        });
+        final Key key = addCloseHandler(SpiUtils.closingCloseHandler(lrhCloseable));
         // this registration removes the prior registration if the client is closed
         client.addCloseHandler(new CloseHandler<Client>() {
             public void handleClose(final Client closed) {
@@ -535,6 +527,18 @@
         return registration;
     }
 
+    public <I, O> Client<I, O> createLocalClient(final ClientListener<I, O> clientListener, final Class<I> requestClass, final Class<O> replyClass, final OptionMap optionMap) throws IOException {
+        return createLocalClient(clientListener, requestClass, replyClass, Thread.currentThread().getContextClassLoader(), optionMap);
+    }
+
+    public <I, O> Client<I, O> createLocalClient(final ClientListener<I, O> clientListener, final Class<I> requestClass, final Class<O> replyClass, final ClassLoader clientClassLoader, final OptionMap optionMap) throws IOException {
+        final ClientContextImpl context = new ClientContextImpl(executor, null);
+        final RequestListener<I, O> requestListener = clientListener.handleClientOpen(context, optionMap);
+        final LocalRequestHandler localRequestHandler = createLocalRequestHandler(requestListener, context, requestClass, replyClass, optionMap);
+        final LocalRemoteRequestHandler remoteRequestHandler = new LocalRemoteRequestHandler(localRequestHandler, clientClassLoader, optionMap, this.optionMap, executor);
+        return ClientImpl.create(remoteRequestHandler, executor, requestClass, replyClass, clientClassLoader);
+    }
+
     public IoFuture<? extends Connection> connect(final URI destination) throws IOException {
         final Pair<String, String> userRealm = getUserAndRealm(destination);
         final String uriUserName = userRealm.getA();
@@ -578,7 +582,7 @@
             }
 
             public boolean setException(final IOException exception) {
-                glueStackTraces(exception, mark, 1);
+                glueStackTraces(exception, mark, 1, "asynchronous invocation");
                 return futureResult.setException(exception);
             }
 
@@ -589,11 +593,11 @@
         return futureResult.getIoFuture();
     }
 
-    static void glueStackTraces(final Throwable exception, final Throwable markerThrowable, final int trimCount) {
+    static void glueStackTraces(final Throwable exception, final Throwable markerThrowable, final int trimCount, final String msg) {
         final StackTraceElement[] est = exception.getStackTrace();
         final StackTraceElement[] ust = markerThrowable.getStackTrace();
         final StackTraceElement[] fst = Arrays.copyOf(est, est.length + ust.length);
-        fst[est.length] = new StackTraceElement("...asynchronous invocation..", "", null, -1);
+        fst[est.length] = new StackTraceElement("..." + msg + "..", "", null, -1);
         System.arraycopy(ust, trimCount, fst, est.length + 1, ust.length - trimCount);
         exception.setStackTrace(fst);
     }
@@ -751,7 +755,7 @@
             return connectionProviderContext;
         }
 
-        public RequestHandler openService(final String serviceType, final String groupName, final OptionMap optionMap) {
+        public LocalRequestHandler openService(final String serviceType, final String groupName, final OptionMap optionMap) {
             final Lock lock = serviceReadLock;
             lock.lock();
             try {
@@ -766,7 +770,7 @@
                 if (info == null) {
                     return null;
                 }
-                return info.getRequestHandlerFactory().createRequestHandler(connection);
+                return info.getRequestHandlerFactory().createRequestHandler(connection, optionMap);
             } finally {
                 lock.unlock();
             }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureReplyImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureReplyImpl.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/FutureReplyImpl.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -24,7 +24,7 @@
 
 import java.io.IOException;
 import java.util.concurrent.Executor;
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.LocalReplyHandler;
 import org.jboss.xnio.AbstractIoFuture;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoFuture;
@@ -36,28 +36,30 @@
 
     private final Executor executor;
     private final Checker<? extends O> checker;
-    private final ReplyHandler replyHandler = new Handler();
+    private final ClassLoader classLoader;
+    private final LocalReplyHandler replyHandler = new Handler();
     private volatile Cancellable remoteRequestContext;
 
-    FutureReplyImpl(final Executor executor, final Checker<? extends O> checker) {
+    FutureReplyImpl(final Executor executor, final Checker<? extends O> checker, final ClassLoader classLoader) {
         this.executor = executor;
         this.checker = checker;
+        this.classLoader = classLoader;
     }
 
-    FutureReplyImpl(final Executor executor, final Class<? extends O> expectedType) {
+    FutureReplyImpl(final Executor executor, final Class<? extends O> expectedType, final ClassLoader classLoader) {
         this(executor, new Checker<O>() {
             public O cast(final Object input) {
                 return expectedType.cast(input);
             }
-        });
+        }, classLoader);
     }
 
-    FutureReplyImpl(final Executor executor, final TypedRequest<?, ? extends O> typedRequest) {
+    FutureReplyImpl(final Executor executor, final TypedRequest<?, ? extends O> typedRequest, final ClassLoader classLoader) {
         this(executor, new Checker<O>() {
             public O cast(final Object input) {
                 return typedRequest.castReply(input);
             }
-        });
+        }, classLoader);
     }
 
     void setRemoteRequestContext(final Cancellable remoteRequestContext) {
@@ -74,7 +76,7 @@
         return executor;
     }
 
-    ReplyHandler getReplyHandler() {
+    LocalReplyHandler getReplyHandler() {
         return replyHandler;
     }
 
@@ -82,7 +84,7 @@
         O cast(Object input);
     }
 
-    private final class Handler implements ReplyHandler {
+    private final class Handler implements LocalReplyHandler {
 
         public void handleReply(final Object reply) {
             final Checker<? extends O> checker = FutureReplyImpl.this.checker;
@@ -104,5 +106,9 @@
         public void handleCancellation() {
             setCancelled();
         }
+
+        public ClassLoader getClassLoader() {
+            return classLoader;
+        }
     }
 }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalConnectionHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalConnectionHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalConnectionHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -25,7 +25,8 @@
 import java.io.IOException;
 import org.jboss.remoting3.spi.ConnectionHandler;
 import org.jboss.remoting3.spi.ConnectionHandlerContext;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoUtils;
@@ -35,29 +36,26 @@
 final class LocalConnectionHandler implements ConnectionHandler {
 
     private final ConnectionHandlerContext connectionHandlerContext;
+    private final OptionMap connectionOptionMap;
 
-    public LocalConnectionHandler(final ConnectionHandlerContext connectionHandlerContext) {
+    public LocalConnectionHandler(final ConnectionHandlerContext connectionHandlerContext, final OptionMap connectionOptionMap) {
         this.connectionHandlerContext = connectionHandlerContext;
+        this.connectionOptionMap = connectionOptionMap;
     }
 
-    public Cancellable open(final String serviceType, final String groupName, final Result<RequestHandler> result) {
-        // todo: support for call-by-value
-        final RequestHandler handler = connectionHandlerContext.openService(serviceType, groupName, OptionMap.EMPTY);
+    public Cancellable open(final String serviceType, final String groupName, final Result<RemoteRequestHandler> result, final ClassLoader classLoader, final OptionMap optionMap) {
+        final LocalRequestHandler handler = connectionHandlerContext.openService(serviceType, groupName, optionMap);
         if (handler == null) {
             result.setException(new ServiceNotFoundException(ServiceURI.create(serviceType, groupName, null)));
         } else {
-            result.setResult(handler);
+            final LocalRemoteRequestHandler requestHandler = new LocalRemoteRequestHandler(handler, classLoader, optionMap, connectionOptionMap, connectionHandlerContext.getConnectionProviderContext().getExecutor());
+            result.setResult(requestHandler);
         }
         return IoUtils.nullCancellable();
     }
 
-    public RequestHandlerConnector createConnector(final RequestHandler localHandler) {
-        return new RequestHandlerConnector() {
-            public Cancellable createRequestHandler(final Result<RequestHandler> result) throws SecurityException {
-                result.setResult(localHandler);
-                return IoUtils.nullCancellable();
-            }
-        };
+    public RequestHandlerConnector createConnector(final LocalRequestHandler localHandler) {
+        return new LocalRequestHandlerConnector(localHandler, connectionHandlerContext.getConnectionProviderContext().getExecutor());
     }
 
     public void close() throws IOException {

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalConnectionProvider.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalConnectionProvider.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalConnectionProvider.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -48,9 +48,9 @@
                 final Holder h = new Holder();
                 providerContext.accept(new ConnectionHandlerFactory() {
                     public ConnectionHandler createInstance(final ConnectionHandlerContext inboundContext) {
-                        final LocalConnectionHandler inboundHandler = new LocalConnectionHandler(inboundContext);
+                        final LocalConnectionHandler inboundHandler = new LocalConnectionHandler(inboundContext, connectOptions);
                         h.set(inboundHandler);
-                        return new LocalConnectionHandler(outboundContext);
+                        return new LocalConnectionHandler(outboundContext, connectOptions);
                     }
                 });
                 return h.get(); // outbound connection handler

Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRemoteReplyHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRemoteReplyHandler.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRemoteReplyHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3;
+
+import java.io.IOException;
+import org.jboss.marshalling.cloner.ObjectCloner;
+import org.jboss.remoting3.spi.LocalReplyHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
+
+class LocalRemoteReplyHandler implements RemoteReplyHandler {
+
+    private final LocalReplyHandler replyHandler;
+    private final ObjectCloner replyCloner;
+
+    public LocalRemoteReplyHandler(final LocalReplyHandler replyHandler, final ObjectCloner replyCloner) {
+        this.replyHandler = replyHandler;
+        this.replyCloner = replyCloner;
+    }
+
+    public void handleReply(final Object reply) throws IOException {
+        try {
+            replyHandler.handleReply(replyCloner.clone(reply));
+        } catch (ClassNotFoundException e) {
+            final ReplyException re = new ReplyException("Cannot clone reply", e);
+            replyHandler.handleException(re);
+            throw re;
+        }
+    }
+
+    public void handleException(final IOException exception) throws IOException {
+        try {
+            replyHandler.handleException((IOException) replyCloner.clone(exception));
+        } catch (ClassNotFoundException e) {
+            final ReplyException re = new ReplyException("Cannot clone reply", e);
+            replyHandler.handleException(re);
+            throw re;
+        }
+    }
+
+    public void handleCancellation() throws IOException {
+        replyHandler.handleCancellation();
+    }
+
+    public ClassLoader getClassLoader() {
+        return replyHandler.getClassLoader();
+    }
+}

Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRemoteRequestHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRemoteRequestHandler.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRemoteRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -0,0 +1,271 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3;
+
+import java.io.IOException;
+import java.io.InvalidClassException;
+import java.io.InvalidObjectException;
+import java.util.NoSuchElementException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
+import org.jboss.marshalling.Pair;
+import org.jboss.marshalling.cloner.ClassCloner;
+import org.jboss.marshalling.cloner.ClassLoaderClassCloner;
+import org.jboss.marshalling.cloner.CloneTable;
+import org.jboss.marshalling.cloner.ClonerConfiguration;
+import org.jboss.marshalling.cloner.ObjectCloner;
+import org.jboss.marshalling.cloner.ObjectClonerFactory;
+import org.jboss.marshalling.cloner.ObjectCloners;
+import org.jboss.remoting3.spi.AbstractHandleableCloseable;
+import org.jboss.remoting3.spi.LocalReplyHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
+import org.jboss.remoting3.spi.SpiUtils;
+import org.jboss.remoting3.stream.ObjectSink;
+import org.jboss.remoting3.stream.ObjectSource;
+import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
+
+class LocalRemoteRequestHandler extends AbstractHandleableCloseable<RemoteRequestHandler> implements RemoteRequestHandler {
+
+    private final LocalRequestHandler handler;
+    private final ClonerPairSource clonerPairSource;
+
+    public LocalRemoteRequestHandler(final LocalRequestHandler handler, final ClassLoader replyClassLoader, final OptionMap optionMap, final OptionMap defaultOptionMap, final Executor executor) {
+        super(executor);
+        final boolean callByValue = optionMap.get(RemotingOptions.CALL_BY_VALUE, defaultOptionMap.get(RemotingOptions.CALL_BY_VALUE, false));
+        final ClonerPairSource clonerPairSource;
+        if (callByValue) {
+            handler.addCloseHandler(SpiUtils.closingCloseHandler(LocalRemoteRequestHandler.this));
+            final ClonerConfiguration configuration = new ClonerConfiguration();
+            final ClassLoader requestClassLoader = handler.getClassLoader();
+            clonerPairSource = new HandlerClonerSource(configuration, ObjectCloners.getSerializingObjectClonerFactory(), requestClassLoader, replyClassLoader);
+        } else {
+            clonerPairSource = ClonerPairSource.IDENTITY;
+        }
+
+        this.clonerPairSource = clonerPairSource;
+        this.handler = handler;
+    }
+
+    protected void closeAction() throws IOException {
+        handler.close();
+    }
+
+    public Cancellable receiveRequest(final Object request, final LocalReplyHandler replyHandler) {
+        final Pair<ObjectCloner, ObjectCloner> pair = clonerPairSource.createPair();
+        final ObjectCloner requestCloner = pair.getA();
+        final ObjectCloner replyCloner = pair.getB();
+        final Object clonedRequest;
+        try {
+            clonedRequest = requestCloner.clone(request);
+        } catch (IOException e) {
+            replyHandler.handleException(e);
+            return IoUtils.nullCancellable();
+        } catch (ClassNotFoundException e) {
+            final InvalidObjectException ioe = new InvalidObjectException("Invalid object: " + e);
+            ioe.initCause(e);
+            replyHandler.handleException(ioe);
+            return IoUtils.nullCancellable();
+        }
+        return handler.receiveRequest(clonedRequest, new LocalRemoteReplyHandler(replyHandler, replyCloner));
+    }
+
+    private static class LocalCloneTable implements CloneTable {
+
+        private volatile ObjectCloner inboundCloner;
+
+        LocalCloneTable() {
+        }
+
+        void setInboundCloner(final ObjectCloner inboundCloner) {
+            this.inboundCloner = inboundCloner;
+        }
+
+        public Object clone(final Object original, final ObjectCloner outboundCloner, final ClassCloner classCloner) throws IOException, ClassNotFoundException {
+            if (original instanceof ObjectSource) {
+                return new CloningObjectSource((ObjectSource) original, outboundCloner);
+            } else if (original instanceof ObjectSink) {
+                return new CloningObjectSink(inboundCloner, (ObjectSink) original);
+            } else if (original instanceof LocalRequestHandlerConnector) {
+                return original;
+            } else if (original instanceof EndpointImpl) {
+                return original;
+            } else {
+                return null;
+            }
+        }
+    }
+
+    private interface ClonerPairSource {
+        Pair<ObjectCloner, ObjectCloner> createPair();
+
+        Pair<ObjectCloner, ObjectCloner> IDENTITY_PAIR = Pair.create(ObjectCloner.IDENTITY, ObjectCloner.IDENTITY);
+
+        ClonerPairSource IDENTITY = new ClonerPairSource() {
+            public Pair<ObjectCloner, ObjectCloner> createPair() {
+                return IDENTITY_PAIR;
+            }
+        };
+    }
+
+    private static class HandlerClonerSource implements ClonerPairSource {
+
+        private final ObjectClonerFactory clonerFactory;
+        private final ClassLoader requestClassLoader;
+        private final ClassLoader replyClassLoader;
+        private final ClonerConfiguration configuration;
+
+        public HandlerClonerSource(final ClonerConfiguration configuration, final ObjectClonerFactory clonerFactory, final ClassLoader requestClassLoader, final ClassLoader replyClassLoader) {
+            this.configuration = configuration;
+            this.clonerFactory = clonerFactory;
+            this.requestClassLoader = requestClassLoader;
+            this.replyClassLoader = replyClassLoader;
+        }
+
+        public Pair<ObjectCloner, ObjectCloner> createPair() {
+            final ClonerConfiguration requestConfiguration = configuration.clone();
+            final ClonerConfiguration replyConfiguration = configuration.clone();
+            final ClassLoader requestClassLoader = this.requestClassLoader;
+            final ClassLoader replyClassLoader = this.replyClassLoader;
+            if (requestClassLoader == replyClassLoader) {
+                requestConfiguration.setClassCloner(ClassCloner.IDENTITY);
+                replyConfiguration.setClassCloner(ClassCloner.IDENTITY);
+            } else {
+                requestConfiguration.setClassCloner(new ClassLoaderClassCloner(requestClassLoader));
+                replyConfiguration.setClassCloner(new ClassLoaderClassCloner(replyClassLoader));
+            }
+            final LocalCloneTable requestCloneTable = new LocalCloneTable();
+            final LocalCloneTable replyCloneTable = new LocalCloneTable();
+            requestConfiguration.setCloneTable(requestCloneTable);
+            replyConfiguration.setCloneTable(replyCloneTable);
+            final ObjectCloner requestCloner = clonerFactory.createCloner(requestConfiguration);
+            final ObjectCloner replyCloner = clonerFactory.createCloner(replyConfiguration);
+            requestCloneTable.setInboundCloner(replyCloner);
+            replyCloneTable.setInboundCloner(requestCloner);
+            return Pair.create(requestCloner, replyCloner);
+        }
+
+        public ObjectCloner createNew() {
+            final ClonerConfiguration configuration = this.configuration.clone();
+            configuration.setCloneTable(new LocalCloneTable());
+            return clonerFactory.createCloner(configuration);
+        }
+    }
+
+    private static class CloningObjectSink implements ObjectSink<Object> {
+
+        private volatile Pair<ObjectCloner, ObjectSink> pair;
+
+        private static final AtomicReferenceFieldUpdater<CloningObjectSink, Pair> pairUpdater = AtomicReferenceFieldUpdater.newUpdater(CloningObjectSink.class, Pair.class, "pair");
+
+        public CloningObjectSink(final ObjectCloner cloner, final ObjectSink objectSink) {
+            pair = Pair.create(cloner, objectSink);
+        }
+
+        @SuppressWarnings({ "unchecked" })
+        public void accept(final Object instance) throws IOException {
+            final Pair<ObjectCloner, ObjectSink> pair = this.pair;
+            if (pair == null) {
+                throw closed();
+            }
+            final ObjectSink objectSink = pair.getB();
+            final ObjectCloner cloner = pair.getA();
+            try {
+                objectSink.accept(cloner.clone(instance));
+            } catch (ClassNotFoundException e) {
+                throw new InvalidClassException(e.getMessage());
+            }
+        }
+
+        public void flush() throws IOException {
+            final Pair<ObjectCloner, ObjectSink> pair = this.pair;
+            if (pair == null) {
+                throw closed();
+            }
+            final ObjectSink objectSink = pair.getB();
+            if (objectSink == null) {
+                throw closed();
+            }
+            objectSink.flush();
+        }
+
+        private static IOException closed() {
+            return new IOException("Object sink has been closed");
+        }
+
+        @SuppressWarnings({ "unchecked" })
+        public void close() throws IOException {
+            final Pair<ObjectCloner, ObjectSink> pair = pairUpdater.getAndSet(this, null);
+            if (pair == null) {
+                return;
+            }
+            pair.getB().close();
+        }
+    }
+
+    private static class CloningObjectSource implements ObjectSource {
+
+        private volatile Pair<ObjectSource, ObjectCloner> pair;
+
+        private static final AtomicReferenceFieldUpdater<CloningObjectSource, Pair> pairUpdater = AtomicReferenceFieldUpdater.newUpdater(CloningObjectSource.class, Pair.class, "pair");
+
+        CloningObjectSource(final ObjectSource objectSource, final ObjectCloner outboundCloner) {
+            pair = Pair.create(objectSource, outboundCloner);
+        }
+
+        public boolean hasNext() throws IOException {
+            final Pair<ObjectSource, ObjectCloner> pair = this.pair;
+            if (pair == null) {
+                throw closed();
+            }
+            return pair.getA().hasNext();
+        }
+
+        public Object next() throws NoSuchElementException, IOException {
+            final Pair<ObjectSource, ObjectCloner> pair = this.pair;
+            if (pair == null) {
+                throw closed();
+            }
+            try {
+                return pair.getB().clone(pair.getA().next());
+            } catch (ClassNotFoundException e) {
+                throw new InvalidObjectException("Class not found: " + e);
+            }
+        }
+
+        private static IOException closed() {
+            return new IOException("Object source has been closed");
+        }
+
+        @SuppressWarnings({ "unchecked" })
+        public void close() throws IOException {
+            final Pair<ObjectSource, ObjectCloner> pair = pairUpdater.getAndSet(this, null);
+            if (pair == null) {
+                return;
+            }
+            pair.getA().close();
+        }
+    }
+}

Deleted: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -1,99 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.remoting3;
-
-import java.io.IOException;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionException;
-import org.jboss.remoting3.spi.AbstractHandleableCloseable;
-import org.jboss.remoting3.spi.ReplyHandler;
-import org.jboss.remoting3.spi.RequestHandler;
-import org.jboss.remoting3.spi.SpiUtils;
-import org.jboss.xnio.Cancellable;
-import org.jboss.xnio.IoUtils;
-import org.jboss.xnio.log.Logger;
-
-/**
- *
- */
-final class LocalRequestHandler<I, O> extends AbstractHandleableCloseable<RequestHandler> implements RequestHandler {
-
-    private final RequestListener<I, O> requestListener;
-    private final ClientContextImpl clientContext;
-    private final Class<I> requestClass;
-    private final Class<O> replyClass;
-    private final ClassLoader serviceClassLoader;
-
-    private static final Logger log = Logger.getLogger("org.jboss.remoting.listener");
-
-    @SuppressWarnings({ "unchecked" })
-    LocalRequestHandler(final Executor executor, final RequestListener<? super I, ? extends O> requestListener, final ClientContextImpl clientContext, final Class<I> requestClass, final Class<O> replyClass, final ClassLoader serviceClassLoader) {
-        super(executor);
-        this.serviceClassLoader = serviceClassLoader;
-        this.requestListener = (RequestListener<I, O>) requestListener;
-        this.clientContext = clientContext;
-        this.requestClass = requestClass;
-        this.replyClass = replyClass;
-    }
-
-    public Cancellable receiveRequest(final Object request, final ReplyHandler replyHandler) {
-        final RequestContextImpl<O> context = new RequestContextImpl<O>(replyHandler, clientContext, replyClass, serviceClassLoader);
-        try {
-            final I castRequest;
-            try {
-                castRequest = requestClass.cast(request);
-            } catch (ClassCastException e) {
-                SpiUtils.safeHandleException(replyHandler, new RemoteRequestException("Request is the wrong type; expected " + requestClass + " but got " + request.getClass()));
-                return IoUtils.nullCancellable();
-            }
-            context.execute(new Runnable() {
-                public void run() {
-                    try {
-                        requestListener.handleRequest(context, castRequest);
-                    } catch (RemoteExecutionException e) {
-                        SpiUtils.safeHandleException(replyHandler, e);
-                    } catch (Throwable t) {
-                        SpiUtils.safeHandleException(replyHandler, new RemoteExecutionException("Request handler threw an exception", t));
-                    }
-                }
-            });
-        } catch (RejectedExecutionException e) {
-            SpiUtils.safeHandleException(replyHandler, new RemoteRequestException("Execution was rejected (server may be too busy)", e));
-            return IoUtils.nullCancellable();
-        }
-        return new Cancellable() {
-            public Cancellable cancel() {
-                context.cancel();
-                return this;
-            }
-        };
-    }
-
-    protected void closeAction() throws IOException {
-        clientContext.close();
-    }
-
-    public String toString() {
-        return "local request handler <" + Integer.toHexString(hashCode()) + "> (request listener = " + String.valueOf(requestListener) + ")";
-    }
-}

Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandlerConnector.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandlerConnector.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandlerConnector.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -0,0 +1,51 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3;
+
+import java.util.concurrent.Executor;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
+import org.jboss.remoting3.spi.RequestHandlerConnector;
+import org.jboss.remoting3.spi.SpiUtils;
+import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
+import org.jboss.xnio.Result;
+
+final class LocalRequestHandlerConnector implements RequestHandlerConnector {
+
+    private final LocalRequestHandler localHandler;
+    private final Executor executor;
+
+    LocalRequestHandlerConnector(final LocalRequestHandler localHandler, final Executor executor) {
+        this.localHandler = localHandler;
+        this.executor = executor;
+    }
+
+    public Cancellable createRequestHandler(final Result<RemoteRequestHandler> result) throws SecurityException {
+        final LocalRemoteRequestHandler handler = new LocalRemoteRequestHandler(localHandler, null, OptionMap.EMPTY, OptionMap.EMPTY, executor);
+        localHandler.addCloseHandler(SpiUtils.closingCloseHandler(handler));
+        result.setResult(handler);
+        return IoUtils.nullCancellable();
+    }
+}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemoteClassTable.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemoteClassTable.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemoteClassTable.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -31,6 +31,7 @@
 import org.jboss.marshalling.Unmarshaller;
 import org.jboss.remoting3.service.classtable.ClassLookupRequest;
 import org.jboss.remoting3.service.classtable.ClassLookupResponse;
+import org.jboss.xnio.OptionMap;
 
 final class RemoteClassTable implements ClassTable {
     private final Client<ClassLookupRequest, ClassLookupResponse> resolver;
@@ -148,7 +149,7 @@
     }
 
     private class RctClientListener implements ClientListener<ClassLookupRequest, ClassLookupResponse> {
-        public RequestListener<ClassLookupRequest, ClassLookupResponse> handleClientOpen(final ClientContext clientContext) {
+        public RequestListener<ClassLookupRequest, ClassLookupResponse> handleClientOpen(final ClientContext clientContext, final OptionMap optionMap) {
             return requestListener;
         }
     }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/Remoting.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -23,39 +23,37 @@
 package org.jboss.remoting3;
 
 import java.io.IOException;
-import java.io.InputStreamReader;
 import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.ServiceLoader;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
-import java.util.ServiceLoader;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Properties;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.lang.reflect.InvocationTargetException;
+import org.jboss.marshalling.ClassExternalizerFactory;
+import org.jboss.marshalling.ClassResolver;
+import org.jboss.marshalling.ClassTable;
+import org.jboss.marshalling.ObjectResolver;
+import org.jboss.marshalling.ObjectTable;
+import org.jboss.marshalling.ProviderDescriptor;
 import org.jboss.remoting3.security.RemotingPermission;
-import org.jboss.remoting3.spi.RequestHandler;
-import org.jboss.remoting3.spi.RemotingServiceDescriptor;
 import org.jboss.remoting3.spi.ConnectionProviderFactory;
 import org.jboss.remoting3.spi.ProtocolServiceType;
+import org.jboss.remoting3.spi.RemotingServiceDescriptor;
 import org.jboss.xnio.IoUtils;
 import org.jboss.xnio.Option;
 import org.jboss.xnio.OptionMap;
 import org.jboss.xnio.log.Logger;
-import org.jboss.marshalling.ClassTable;
-import org.jboss.marshalling.ObjectTable;
-import org.jboss.marshalling.ClassResolver;
-import org.jboss.marshalling.ObjectResolver;
-import org.jboss.marshalling.ClassExternalizerFactory;
-import org.jboss.marshalling.ProviderDescriptor;
-import org.jboss.marshalling.MarshallerFactory;
 
 /**
  * The standalone interface into Remoting.  This class contains static methods that are useful to standalone programs
@@ -294,32 +292,5 @@
         return endpoint;
     }
 
-    /**
-     * Create a local client from a request listener.  The client will retain the sole reference to the request listener,
-     * so when the client is closed, the listener will also be closed (unless the client is sent to a remote endpoint).
-     *
-     * @param endpoint the endpoint to bind the request listener to
-     * @param requestListener the request listener
-     * @param requestClass the request class
-     * @param replyClass the reply class
-     * @param <I> the request type
-     * @param <O> the reply type
-     * @return a new client
-     * @throws IOException if an error occurs
-     */
-    public static <I, O> Client<I, O> createLocalClient(final Endpoint endpoint, final RequestListener<I, O> requestListener, final Class<I> requestClass, final Class<O> replyClass) throws IOException {
-        boolean ok = false;
-        final RequestHandler requestHandler = endpoint.createLocalRequestHandler(requestListener, requestClass, replyClass);
-        try {
-            final Client<I, O> client = endpoint.createClient(requestHandler, requestClass, replyClass);
-            ok = true;
-            return client;
-        } finally {
-            if (! ok) {
-                IoUtils.safeClose(requestHandler);
-            }
-        }
-    }
-
     private Remoting() { /* empty */ }
 }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestContextImpl.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestContextImpl.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestContextImpl.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -30,7 +30,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
 import org.jboss.remoting3.spi.SpiUtils;
 
 /**
@@ -40,7 +40,7 @@
 
     private final AtomicBoolean closed = new AtomicBoolean();
     private final Object cancelLock = new Object();
-    private final ReplyHandler replyHandler;
+    private final RemoteReplyHandler replyHandler;
     private final ClientContextImpl clientContext;
     private final AtomicInteger taskCount = new AtomicInteger();
 
@@ -52,7 +52,7 @@
     private final Class<O> replyClass;
     private final ClassLoader serviceClassLoader;
 
-    RequestContextImpl(final ReplyHandler replyHandler, final ClientContextImpl clientContext, final Class<O> replyClass, final ClassLoader serviceClassLoader) {
+    RequestContextImpl(final RemoteReplyHandler replyHandler, final ClientContextImpl clientContext, final Class<O> replyClass, final ClassLoader serviceClassLoader) {
         this.replyHandler = replyHandler;
         this.clientContext = clientContext;
         this.replyClass = replyClass;

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestHandlerFactory.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestHandlerFactory.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RequestHandlerFactory.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -23,7 +23,8 @@
 package org.jboss.remoting3;
 
 import java.util.concurrent.Executor;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.xnio.OptionMap;
 
 /**
  * A factory which creates request handlers corresponding to request listeners for a given client listener.
@@ -47,9 +48,9 @@
         return new RequestHandlerFactory<I, O>(executor, clientListener, requestClass, replyClass, serviceClassLoader);
     }
 
-    RequestHandler createRequestHandler(final Connection connection) {
+    LocalRequestHandler createRequestHandler(final Connection connection, final OptionMap optionMap) {
         final ClientContextImpl context = new ClientContextImpl(executor, connection);
-        return new LocalRequestHandler<I, O>(executor, clientListener.handleClientOpen(context), context, requestClass, replyClass, serviceClassLoader);
+        return new TerminatingLocalRequestHandler<I, O>(executor, clientListener.handleClientOpen(context, optionMap), context, requestClass, replyClass, serviceClassLoader);
     }
 
     Class<I> getRequestClass() {

Copied: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/TerminatingLocalRequestHandler.java (from rev 5792, remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/LocalRequestHandler.java)
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/TerminatingLocalRequestHandler.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/TerminatingLocalRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -0,0 +1,103 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3;
+
+import java.io.IOException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import org.jboss.remoting3.spi.AbstractHandleableCloseable;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
+import org.jboss.remoting3.spi.SpiUtils;
+import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.log.Logger;
+
+/**
+ *
+ */
+final class TerminatingLocalRequestHandler<I, O> extends AbstractHandleableCloseable<LocalRequestHandler> implements LocalRequestHandler {
+
+    private final RequestListener<I, O> requestListener;
+    private final ClientContextImpl clientContext;
+    private final Class<I> requestClass;
+    private final Class<O> replyClass;
+    private final ClassLoader serviceClassLoader;
+
+    private static final Logger log = Logger.getLogger("org.jboss.remoting.listener");
+
+    @SuppressWarnings({ "unchecked" })
+    TerminatingLocalRequestHandler(final Executor executor, final RequestListener<? super I, ? extends O> requestListener, final ClientContextImpl clientContext, final Class<I> requestClass, final Class<O> replyClass, final ClassLoader serviceClassLoader) {
+        super(executor);
+        this.serviceClassLoader = serviceClassLoader;
+        this.requestListener = (RequestListener<I, O>) requestListener;
+        this.clientContext = clientContext;
+        this.requestClass = requestClass;
+        this.replyClass = replyClass;
+    }
+
+    public Cancellable receiveRequest(final Object request, final RemoteReplyHandler replyHandler) {
+        final RequestContextImpl<O> context = new RequestContextImpl<O>(replyHandler, clientContext, replyClass, serviceClassLoader);
+        try {
+            final I castRequest;
+            try {
+                castRequest = requestClass.cast(request);
+            } catch (ClassCastException e) {
+                SpiUtils.safeHandleException(replyHandler, new RemoteRequestException("Request is the wrong type; expected " + requestClass + " but got " + request.getClass()));
+                return IoUtils.nullCancellable();
+            }
+            context.execute(new Runnable() {
+                public void run() {
+                    try {
+                        requestListener.handleRequest(context, castRequest);
+                    } catch (RemoteExecutionException e) {
+                        SpiUtils.safeHandleException(replyHandler, e);
+                    } catch (Throwable t) {
+                        SpiUtils.safeHandleException(replyHandler, new RemoteExecutionException("Request handler threw an exception", t));
+                    }
+                }
+            });
+        } catch (RejectedExecutionException e) {
+            SpiUtils.safeHandleException(replyHandler, new RemoteRequestException("Execution was rejected (server may be too busy)", e));
+            return IoUtils.nullCancellable();
+        }
+        return new Cancellable() {
+            public Cancellable cancel() {
+                context.cancel();
+                return this;
+            }
+        };
+    }
+
+    public ClassLoader getClassLoader() {
+        return serviceClassLoader;
+    }
+
+    protected void closeAction() throws IOException {
+        clientContext.close();
+    }
+
+    public String toString() {
+        return "local request handler <" + Integer.toHexString(hashCode()) + "> (request listener = " + String.valueOf(requestListener) + ")";
+    }
+}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientAuthenticationHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientAuthenticationHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientAuthenticationHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -25,10 +25,10 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import org.jboss.marshalling.MarshallerFactory;
-import org.jboss.remoting3.CloseHandler;
 import org.jboss.remoting3.spi.ConnectionHandler;
 import org.jboss.remoting3.spi.ConnectionHandlerContext;
 import org.jboss.remoting3.spi.ConnectionHandlerFactory;
+import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.Buffers;
 import org.jboss.xnio.IoUtils;
 import org.jboss.xnio.Result;
@@ -128,11 +128,7 @@
                         // this happens immediately.
                         final MarshallerFactory marshallerFactory = remoteConnection.getProviderDescriptor().getMarshallerFactory();
                         final RemoteConnectionHandler connectionHandler = new RemoteConnectionHandler(connectionContext, remoteConnection, marshallerFactory);
-                        remoteConnection.addCloseHandler(new CloseHandler<Object>() {
-                            public void handleClose(final Object closed) {
-                                IoUtils.safeClose(connectionHandler);
-                            }
-                        });
+                        remoteConnection.addCloseHandler(SpiUtils.closingCloseHandler(connectionHandler));
                         remoteConnection.setMessageHandler(new RemoteMessageHandler(connectionHandler, remoteConnection));
                         return connectionHandler;
                     }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundClient.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundClient.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundClient.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,28 +22,25 @@
 
 package org.jboss.remoting3.remote;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.nio.ByteBuffer;
-import org.jboss.remoting3.CloseHandler;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.SpiUtils;
 
-final class InboundClient {
-    private final RequestHandler handler;
+final class InboundClient implements Closeable {
+    private final LocalRequestHandler handler;
     private final RemoteConnectionHandler remoteConnectionHandler;
     private final int id;
 
-    InboundClient(final RemoteConnectionHandler remoteConnectionHandler, final RequestHandler handler, final int id) {
+    InboundClient(final RemoteConnectionHandler remoteConnectionHandler, final LocalRequestHandler handler, final int id) {
         this.remoteConnectionHandler = remoteConnectionHandler;
         this.handler = handler;
         this.id = id;
-        handler.addCloseHandler(new CloseHandler<RequestHandler>() {
-            public void handleClose(final RequestHandler closed) {
-                close();
-            }
-        });
+        handler.addCloseHandler(SpiUtils.closingCloseHandler(this));
     }
 
-    RequestHandler getHandler() {
+    LocalRequestHandler getHandler() {
         return handler;
     }
 
@@ -51,7 +48,7 @@
         return remoteConnectionHandler;
     }
 
-    void close() {
+    public void close() {
         final RemoteConnection remoteConnection = remoteConnectionHandler.getRemoteConnection();
         final ByteBuffer buffer = remoteConnection.allocate();
         try {

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyExceptionTask.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyExceptionTask.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyExceptionTask.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -27,7 +27,7 @@
 import org.jboss.marshalling.Unmarshaller;
 import org.jboss.remoting3.RemoteReplyException;
 import org.jboss.remoting3.RemoteRequestException;
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.LocalReplyHandler;
 import org.jboss.remoting3.spi.SpiUtils;
 
 final class InboundReplyExceptionTask implements Runnable {
@@ -41,7 +41,7 @@
     }
 
     public void run() {
-        final ReplyHandler replyHandler;
+        final LocalReplyHandler replyHandler;
         final OutboundRequest outboundRequest = this.outboundRequest;
         final NioByteInput oldByteInput;
         synchronized (outboundRequest) {

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyTask.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyTask.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyTask.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -25,7 +25,7 @@
 import java.io.IOException;
 import org.jboss.marshalling.Unmarshaller;
 import org.jboss.remoting3.RemoteRequestException;
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.LocalReplyHandler;
 import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.IoUtils;
 import org.jboss.xnio.log.Logger;
@@ -43,7 +43,7 @@
     }
 
     public void run() {
-        final ReplyHandler replyHandler;
+        final LocalReplyHandler replyHandler;
         final OutboundRequest outboundRequest = this.outboundRequest;
         synchronized (outboundRequest) {
             replyHandler = outboundRequest.getInboundReplyHandler();

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundClient.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundClient.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundClient.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,7 +22,7 @@
 
 package org.jboss.remoting3.remote;
 
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.Result;
 
@@ -30,15 +30,15 @@
 
     private State state = State.REPLY_WAIT;
 
-    private Result<RequestHandler> result;
+    private Result<RemoteRequestHandler> result;
 
     private final int id;
     private final String serviceType;
     private final String groupName;
     private RemoteConnectionHandler remoteConnectionHandler;
-    private RequestHandler requestHandler;
+    private RemoteRequestHandler requestHandler;
 
-    OutboundClient(final RemoteConnectionHandler remoteConnectionHandler, final int id, final Result<RequestHandler> result, final String serviceType, final String groupName) {
+    OutboundClient(final RemoteConnectionHandler remoteConnectionHandler, final int id, final Result<RemoteRequestHandler> result, final String serviceType, final String groupName) {
         this.remoteConnectionHandler = remoteConnectionHandler;
         this.id = id;
         this.result = result;
@@ -69,7 +69,7 @@
         return this;
     }
 
-    Result<RequestHandler> getResult() {
+    Result<RemoteRequestHandler> getResult() {
         return result;
     }
 
@@ -89,11 +89,11 @@
         return id;
     }
 
-    RequestHandler getRequestHandler() {
+    RemoteRequestHandler getRequestHandler() {
         return requestHandler;
     }
 
-    void setResult(final RequestHandler requestHandler) {
+    void setResult(final RemoteRequestHandler requestHandler) {
         result.setResult(requestHandler);
         this.requestHandler = requestHandler;
     }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -27,10 +27,10 @@
 import java.util.concurrent.atomic.AtomicBoolean;
 import org.jboss.marshalling.Marshaller;
 import org.jboss.marshalling.NioByteOutput;
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
 import org.jboss.xnio.Pool;
 
-final class OutboundReplyHandler implements ReplyHandler {
+final class OutboundReplyHandler implements RemoteReplyHandler {
 
     private final int rid;
     private final AtomicBoolean done = new AtomicBoolean();

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequest.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequest.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequest.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -24,19 +24,19 @@
 
 import java.util.concurrent.Semaphore;
 import org.jboss.marshalling.NioByteInput;
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.LocalReplyHandler;
 import org.jboss.xnio.Cancellable;
 
 final class OutboundRequest implements Cancellable {
     private final int cid;
-    private final ReplyHandler inboundReplyHandler;
+    private final LocalReplyHandler inboundReplyHandler;
     private final Semaphore flowSemaphore = new Semaphore(5); // todo receive window size
 
     private State state = State.SENDING;
     private NioByteInput byteInput;
     private RemoteConnectionHandler remoteConnectionHandler;
 
-    OutboundRequest(final RemoteConnectionHandler remoteConnectionHandler, final ReplyHandler inboundReplyHandler, final int cid) {
+    OutboundRequest(final RemoteConnectionHandler remoteConnectionHandler, final LocalReplyHandler inboundReplyHandler, final int cid) {
         this.remoteConnectionHandler = remoteConnectionHandler;
         this.inboundReplyHandler = inboundReplyHandler;
         this.cid = cid;
@@ -105,7 +105,7 @@
         CLOSED,
     }
 
-    ReplyHandler getInboundReplyHandler() {
+    LocalReplyHandler getInboundReplyHandler() {
         return inboundReplyHandler;
     }
 

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -29,14 +29,14 @@
 import org.jboss.marshalling.NioByteOutput;
 import org.jboss.marshalling.util.IntKeyMap;
 import org.jboss.remoting3.spi.AbstractHandleableCloseable;
-import org.jboss.remoting3.spi.ReplyHandler;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalReplyHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.Pool;
 import org.jboss.xnio.log.Logger;
 
-final class OutboundRequestHandler extends AbstractHandleableCloseable<RequestHandler> implements RequestHandler {
+final class OutboundRequestHandler extends AbstractHandleableCloseable<RemoteRequestHandler> implements RemoteRequestHandler {
 
     private final OutboundClient outboundClient;
     private static final Logger log = Loggers.main;
@@ -46,7 +46,7 @@
         this.outboundClient = outboundClient;
     }
 
-    public Cancellable receiveRequest(final Object request, final ReplyHandler replyHandler) {
+    public Cancellable receiveRequest(final Object request, final LocalReplyHandler replyHandler) {
         final RemoteConnectionHandler connectionHandler = outboundClient.getRemoteConnectionHandler();
         final OutboundRequest outboundRequest = new OutboundRequest(connectionHandler, replyHandler, outboundClient.getId());
         int rid;

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/PrimaryExternalizerFactory.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/PrimaryExternalizerFactory.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/PrimaryExternalizerFactory.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -35,7 +35,7 @@
 
     public Externalizer getExternalizer(final Class<?> type) {
         if (type == UnsentRequestHandlerConnector.class) {
-            return new RequestHandlerConnectorExternalizer();
+            return RequestHandlerConnectorExternalizer.INSTANCE;
         }
         return null;
     }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ReceivedRequestHandlerConnector.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ReceivedRequestHandlerConnector.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ReceivedRequestHandlerConnector.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -23,7 +23,7 @@
 package org.jboss.remoting3.remote;
 
 import org.jboss.marshalling.util.IntKeyMap;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoUtils;
@@ -38,7 +38,7 @@
         this.clientId = clientId;
     }
 
-    public Cancellable createRequestHandler(final Result<RequestHandler> result) throws SecurityException {
+    public Cancellable createRequestHandler(final Result<RemoteRequestHandler> result) throws SecurityException {
         final OutboundClient client = new OutboundClient(connectionHandler, clientId, result, "anonymous", "anonymous");
         final IntKeyMap<OutboundClient> outboundClients = connectionHandler.getOutboundClients();
         synchronized (outboundClients) {

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -35,12 +35,14 @@
 import org.jboss.remoting3.spi.AbstractHandleableCloseable;
 import org.jboss.remoting3.spi.ConnectionHandler;
 import org.jboss.remoting3.spi.ConnectionHandlerContext;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
 import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.Buffers;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
 import org.jboss.xnio.Pool;
 import org.jboss.xnio.Result;
 
@@ -81,7 +83,7 @@
         marshallingConfiguration = config;
     }
 
-    public Cancellable open(final String serviceType, final String groupName, final Result<RequestHandler> result) {
+    public Cancellable open(final String serviceType, final String groupName, final Result<RemoteRequestHandler> result, final ClassLoader classLoader, final OptionMap optionMap) {
         final OutboundClient outboundClient;
         int id;
         synchronized (outboundClients) {
@@ -111,7 +113,7 @@
         return outboundClient;
     }
 
-    public RequestHandlerConnector createConnector(final RequestHandler localHandler) {
+    public RequestHandlerConnector createConnector(final LocalRequestHandler localHandler) {
         int id;
         synchronized (inboundClients) {
             while (inboundClients.containsKey(id = random.nextInt() & ~1));

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteMessageHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteMessageHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteMessageHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -30,8 +30,8 @@
 import org.jboss.remoting3.ReplyException;
 import org.jboss.remoting3.ServiceNotFoundException;
 import org.jboss.remoting3.ServiceURI;
-import org.jboss.remoting3.spi.ReplyHandler;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalReplyHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
 import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.Buffers;
 import org.jboss.xnio.IoUtils;
@@ -60,7 +60,7 @@
                 final int id = buffer.getInt();
                 final String serviceType = Buffers.getModifiedUtf8Z(buffer);
                 final String groupName = Buffers.getModifiedUtf8Z(buffer);
-                final RequestHandler handler;
+                final LocalRequestHandler handler;
                 handler = connectionHandler.getConnectionContext().openService(serviceType, groupName, OptionMap.EMPTY);
                 final Pool<ByteBuffer> bufferPool = connectionHandler.getBufferPool();
                 final ByteBuffer outBuf = bufferPool.allocate();
@@ -310,7 +310,7 @@
                     return;
                 }
                 final NioByteInput byteInput;
-                final ReplyHandler replyHandler;
+                final LocalReplyHandler replyHandler;
                 synchronized (outboundRequest) {
                     byteInput = outboundRequest.getByteInput();
                     replyHandler = outboundRequest.getInboundReplyHandler();

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerAuthenticationHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerAuthenticationHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerAuthenticationHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -25,11 +25,11 @@
 import java.io.IOException;
 import java.nio.ByteBuffer;
 import org.jboss.marshalling.MarshallerFactory;
-import org.jboss.remoting3.CloseHandler;
 import org.jboss.remoting3.spi.ConnectionHandler;
 import org.jboss.remoting3.spi.ConnectionHandlerContext;
 import org.jboss.remoting3.spi.ConnectionHandlerFactory;
 import org.jboss.remoting3.spi.ConnectionProviderContext;
+import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.Buffers;
 import org.jboss.xnio.IoUtils;
 import org.jboss.xnio.log.Logger;
@@ -75,11 +75,7 @@
                             public ConnectionHandler createInstance(final ConnectionHandlerContext connectionContext) {
                                 final MarshallerFactory marshallerFactory = remoteConnection.getProviderDescriptor().getMarshallerFactory();
                                 final RemoteConnectionHandler connectionHandler = new RemoteConnectionHandler(connectionContext, remoteConnection, marshallerFactory);
-                                remoteConnection.addCloseHandler(new CloseHandler<Object>() {
-                                    public void handleClose(final Object closed) {
-                                        IoUtils.safeClose(connectionHandler);
-                                    }
-                                });
+                                remoteConnection.addCloseHandler(SpiUtils.closingCloseHandler(connectionHandler));
                                 remoteConnection.setMessageHandler(new RemoteMessageHandler(connectionHandler, remoteConnection));
                                 return connectionHandler;
                             }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/UnsentRequestHandlerConnector.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/UnsentRequestHandlerConnector.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/UnsentRequestHandlerConnector.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -24,7 +24,7 @@
 
 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
 import org.jboss.marshalling.util.IntKeyMap;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.Result;
@@ -42,7 +42,7 @@
         this.remoteConnectionHandler = remoteConnectionHandler;
     }
 
-    public Cancellable createRequestHandler(final Result<RequestHandler> result) throws SecurityException {
+    public Cancellable createRequestHandler(final Result<RemoteRequestHandler> result) throws SecurityException {
         throw new SecurityException("Request handler not sent");
     }
 

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/SimpleClientCallbackHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/SimpleClientCallbackHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/SimpleClientCallbackHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,7 +22,6 @@
 
 package org.jboss.remoting3.security;
 
-import java.io.IOException;
 import org.jboss.xnio.log.Logger;
 
 import javax.security.auth.callback.Callback;

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -24,6 +24,7 @@
 
 import java.io.Closeable;
 import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.OptionMap;
 import org.jboss.xnio.Result;
 
 /**
@@ -36,9 +37,12 @@
      *
      * @param serviceType the service type string
      * @param groupName the group name string
-     * @param result the result for the connected request handler  @return a handle which may be used to cancel the pending operation
+     * @param result the result for the connected request handler
+     * @param classLoader the class loader to use for replies
+     * @param optionMap the options for this service
+     * @return a handle which may be used to cancel the pending operation
      */
-    Cancellable open(String serviceType, String groupName, Result<RequestHandler> result);
+    Cancellable open(String serviceType, String groupName, Result<RemoteRequestHandler> result, ClassLoader classLoader, OptionMap optionMap);
 
     /**
      * Create a connector which may be used to communicate with the given local RequestHandler.  The connector
@@ -47,5 +51,5 @@
      * @param localHandler the local handler
      * @return the connector
      */
-    RequestHandlerConnector createConnector(RequestHandler localHandler);
+    RequestHandlerConnector createConnector(LocalRequestHandler localHandler);
 }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandlerContext.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandlerContext.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionHandlerContext.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -50,7 +50,7 @@
      * @return the new request handler
      * @throws IOException if an error occurs
      */
-    RequestHandler openService(String serviceType, String groupName, OptionMap optionMap);
+    LocalRequestHandler openService(String serviceType, String groupName, OptionMap optionMap);
 
     /**
      * Indicate that the remote side has terminated the connection, so the local side should be closed as well.
@@ -58,23 +58,4 @@
      * @remoting.nonblocking
      */
     void remoteClosed();
-
-    /**
-     * The result acceptor for a service open request.
-     */
-    interface ServiceResult {
-
-        /**
-         * Called if the service was opened.
-         *
-         * @param requestHandler the opened request handler
-         * @param optionMap the service's option map
-         */
-        void opened(RequestHandler requestHandler, OptionMap optionMap);
-
-        /**
-         * Called if no matching service was found.
-         */
-        void notFound();
-    }
 }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ConnectionProvider.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -23,9 +23,9 @@
 package org.jboss.remoting3.spi;
 
 import java.net.URI;
-import org.jboss.xnio.Result;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.OptionMap;
+import org.jboss.xnio.Result;
 
 import javax.security.auth.callback.CallbackHandler;
 

Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/LocalReplyHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/LocalReplyHandler.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/LocalReplyHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -0,0 +1,58 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3.spi;
+
+import java.io.IOException;
+
+/**
+ * A reply handler which is local to this machine.
+ */
+public interface LocalReplyHandler {
+
+    /**
+     * Get the class loader to be used to unmarshall replies.
+     *
+     * @return the class loader
+     */
+    ClassLoader getClassLoader();
+
+    /**
+     * Handle a successful reply.  If the reply could not be forwarded, an exception is thrown.
+     *
+     * @param reply the reply
+     */
+    void handleReply(Object reply);
+
+    /**
+     * Handle an exception.  If the exception could not be forwarded, a (different) {@code IOException} is thrown.
+     *
+     * @param exception an exception which describes the problem
+     */
+    void handleException(IOException exception);
+
+    /**
+     * Handle a cancellation acknowledgement.  If the cancellation acknowledgement could not be forwarded, an exception is
+     * thrown.
+     */
+    void handleCancellation();
+}

Added: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/LocalRequestHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/LocalRequestHandler.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/LocalRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3.spi;
+
+import org.jboss.remoting3.HandleableCloseable;
+import org.jboss.xnio.Cancellable;
+
+/**
+ * A request handler which is local to the machine.
+ * <p>
+ * This is an internal Remoting interface, intended to be implemented only by Remoting internals and protocol implementations.
+ * It should not be used or implemented by end-users.  Members may be added without notice.  Applications should instead use
+ * the {@link org.jboss.remoting3.Client Client} and {@link org.jboss.remoting3.RequestListener RequestListener} interfaces.
+ */
+public interface LocalRequestHandler extends HandleableCloseable<LocalRequestHandler> {
+
+    /**
+     * Receive a request bound to this system.  This method is intended to be called by protocol handlers.  If the
+     * request cannot be accepted for some reason, the
+     * {@link RemoteReplyHandler#handleException(java.io.IOException)}
+     * method is called immediately.
+     *
+     * @param request the request
+     * @param replyHandler a handler for the reply
+     * @return a reference which may be used to cancel the request
+     */
+    Cancellable receiveRequest(Object request, RemoteReplyHandler replyHandler);
+
+    /**
+     * Get the class loader to use to unmarshall inbound requests for this handler.
+     *
+     * @return the class loader
+     */
+    ClassLoader getClassLoader();
+}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ProtocolServiceType.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ProtocolServiceType.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ProtocolServiceType.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,13 +22,13 @@
 
 package org.jboss.remoting3.spi;
 
+import java.io.Serializable;
+import org.jboss.marshalling.ClassExternalizerFactory;
+import org.jboss.marshalling.ClassResolver;
 import org.jboss.marshalling.ClassTable;
+import org.jboss.marshalling.ObjectResolver;
 import org.jboss.marshalling.ObjectTable;
-import org.jboss.marshalling.ClassResolver;
-import org.jboss.marshalling.ObjectResolver;
-import org.jboss.marshalling.ClassExternalizerFactory;
 import org.jboss.marshalling.ProviderDescriptor;
-import java.io.Serializable;
 import org.jboss.remoting3.security.ServerAuthenticationProvider;
 
 public final class ProtocolServiceType<T> implements Serializable {

Copied: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemoteReplyHandler.java (from rev 5781, remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ReplyHandler.java)
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemoteReplyHandler.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemoteReplyHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -0,0 +1,52 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3.spi;
+
+import java.io.IOException;
+
+/**
+ * A handler for replies from a request.  The handler should respect the first invocation made on it, and ignore
+ * any subsequent invocations.
+ */
+public interface RemoteReplyHandler {
+
+    /**
+     * Handle a successful reply.  If the reply could not be forwarded, an exception is thrown.
+     *
+     * @param reply the reply
+     */
+    void handleReply(Object reply) throws IOException;
+
+    /**
+     * Handle an exception.  If the exception could not be forwarded, a (different) {@code IOException} is thrown.
+     *
+     * @param exception an exception which describes the problem
+     */
+    void handleException(IOException exception) throws IOException;
+
+    /**
+     * Handle a cancellation acknowledgement.  If the cancellation acknowledgement could not be forwarded, an
+     * exception is thrown.
+     */
+    void handleCancellation() throws IOException;
+}

Copied: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemoteRequestHandler.java (from rev 5781, remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandler.java)
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemoteRequestHandler.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemoteRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -0,0 +1,48 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3.spi;
+
+import org.jboss.remoting3.HandleableCloseable;
+import org.jboss.xnio.Cancellable;
+
+/**
+ * A request handler which forwards across the JVM boundary.
+ * <p>
+ * This is an internal Remoting interface, intended to be implemented only by Remoting internals and protocol implementations.
+ * It should not be used or implemented by end-users.  Members may be added without notice.  Applications should instead use
+ * the {@link org.jboss.remoting3.Client Client} and {@link org.jboss.remoting3.RequestListener RequestListener} interfaces.
+ */
+public interface RemoteRequestHandler extends HandleableCloseable<RemoteRequestHandler> {
+
+    /**
+     * Receive a request bound to a remote system.  This method is intended to be called by protocol handlers.  If the
+     * request cannot be accepted for some reason, the
+     * {@link RemoteReplyHandler#handleException(java.io.IOException)}
+     * method is called immediately.
+     *
+     * @param request the request
+     * @param replyHandler a handler for the reply
+     * @return a reference which may be used to cancel the request
+     */
+    Cancellable receiveRequest(Object request, LocalReplyHandler replyHandler);
+}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemotingServiceDescriptor.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemotingServiceDescriptor.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RemotingServiceDescriptor.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,8 +22,8 @@
 
 package org.jboss.remoting3.spi;
 
+import java.io.IOException;
 import java.util.Properties;
-import java.io.IOException;
 
 /**
  * A descriptor for automatically-discovered remoting service types.  Since instances of this interface are

Deleted: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ReplyHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ReplyHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ReplyHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -1,52 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.remoting3.spi;
-
-import java.io.IOException;
-
-/**
- * A handler for replies from a request.  The handler should respect the first invocation made on it, and ignore
- * any subsequent invocations.
- */
-public interface ReplyHandler {
-
-    /**
-     * Handle a successful reply.  If the reply could not be forwarded, an exception is thrown.
-     *
-     * @param reply the reply
-     */
-    void handleReply(Object reply) throws IOException;
-
-    /**
-     * Handle an exception.  If the exception could not be forwarded, a (different) {@code IOException} is thrown.
-     *
-     * @param exception an exception which describes the problem
-     */
-    void handleException(IOException exception) throws IOException;
-
-    /**
-     * Handle a cancellation acknowledgement.  If the cancellation acknowledgement could not be forwarded, an
-     * exception is thrown.
-     */
-    void handleCancellation() throws IOException;
-}

Deleted: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -1,48 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.remoting3.spi;
-
-import org.jboss.remoting3.HandleableCloseable;
-import org.jboss.xnio.Cancellable;
-
-/**
- * A request handler.
- * <p>
- * This is an internal Remoting interface, intended to be implemented only by Remoting internals and protocol implementations.
- * It should not be used or implemented by end-users.  Members may be added without notice.  Applications should instead use
- * the {@link org.jboss.remoting3.Client Client} and {@link org.jboss.remoting3.RequestListener RequestListener} interfaces.
- */
-public interface RequestHandler extends HandleableCloseable<RequestHandler> {
-
-    /**
-     * Receive a request from a remote system.  This method is intended to be called by protocol handlers.  If the
-     * request cannot be accepted for some reason, the
-     * {@link ReplyHandler#handleException(java.io.IOException)}
-     * method is called immediately.
-     *
-     * @param request the request
-     * @param replyHandler a handler for the reply
-     * @return a reference which may be used to cancel the request
-     */
-    Cancellable receiveRequest(Object request, ReplyHandler replyHandler);
-}

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandlerConnector.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandlerConnector.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/RequestHandlerConnector.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -23,6 +23,7 @@
 package org.jboss.remoting3.spi;
 
 import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.Result;
 
 /**
  * A holder for a request handler that is to be sent to a remote peer.
@@ -37,5 +38,5 @@
      * @return the cancellation handle
      * @throws SecurityException if this is a forwarding connector, thrown if the connector was not forwarded or if this method is called more than one time
      */
-    Cancellable createRequestHandler(org.jboss.xnio.Result<RequestHandler> result) throws SecurityException;
+    Cancellable createRequestHandler(Result<RemoteRequestHandler> result) throws SecurityException;
 }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/SpiUtils.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/SpiUtils.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/SpiUtils.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,10 +22,12 @@
 
 package org.jboss.remoting3.spi;
 
+import java.io.Closeable;
 import java.io.IOException;
 import org.jboss.remoting3.CloseHandler;
 import org.jboss.remoting3.RequestCancelHandler;
 import org.jboss.remoting3.RequestContext;
+import org.jboss.xnio.IoUtils;
 import org.jboss.xnio.log.Logger;
 
 /**
@@ -41,9 +43,9 @@
      * Safely notify a reply handler of an exception.
      *
      * @param replyHandler the reply handler
-     * @param exception
+     * @param exception the exception
      */
-    public static void safeHandleException(final ReplyHandler replyHandler, final IOException exception) {
+    public static void safeHandleException(final RemoteReplyHandler replyHandler, final IOException exception) {
         try {
             if (replyHandler != null) replyHandler.handleException(exception);
         } catch (Throwable t) {
@@ -52,13 +54,27 @@
     }
 
     /**
+     * Safely notify a reply handler of an exception.
+     *
+     * @param replyHandler the reply handler
+     * @param exception the exception
+     */
+    public static void safeHandleException(final LocalReplyHandler replyHandler, final IOException exception) {
+        try {
+            if (replyHandler != null) replyHandler.handleException(exception);
+        } catch (Throwable t) {
+            heLog.debug(t, "Failed to properly handle exception");
+        }
+    }
+
+    /**
      * Safely notify a reply handler of a reply.
      *
      * @param <O> the reply type
      * @param replyHandler the reply handler
      * @param reply the reply
      */
-    public static <O> void safeHandleReply(final ReplyHandler replyHandler, final O reply) {
+    public static <O> void safeHandleReply(final RemoteReplyHandler replyHandler, final O reply) {
         try {
             if (replyHandler != null) replyHandler.handleReply(reply);
         } catch (Throwable t) {
@@ -67,11 +83,26 @@
     }
 
     /**
+     * Safely notify a reply handler of a reply.
+     *
+     * @param <O> the reply type
+     * @param replyHandler the reply handler
+     * @param reply the reply
+     */
+    public static <O> void safeHandleReply(final LocalReplyHandler replyHandler, final O reply) {
+        try {
+            if (replyHandler != null) replyHandler.handleReply(reply);
+        } catch (Throwable t) {
+            heLog.debug(t, "Failed to properly handle reply");
+        }
+    }
+
+    /**
      * Safely notify a reply handler of a cancellation.
      *
      * @param replyHandler the reply handler
      */
-    public static void safeHandleCancellation(final ReplyHandler replyHandler) {
+    public static void safeHandleCancellation(final RemoteReplyHandler replyHandler) {
         try {
             if (replyHandler != null) replyHandler.handleCancellation();
         } catch (Throwable t) {
@@ -80,6 +111,19 @@
     }
 
     /**
+     * Safely notify a reply handler of a cancellation.
+     *
+     * @param replyHandler the reply handler
+     */
+    public static void safeHandleCancellation(final LocalReplyHandler replyHandler) {
+        try {
+            if (replyHandler != null) replyHandler.handleCancellation();
+        } catch (Throwable t) {
+            heLog.debug(t, "Failed to properly handle cancellation");
+        }
+    }
+
+    /**
      * Safely notify a request listener's cancel handler of cancellation.
      *
      * @param <O> the reply type
@@ -108,5 +152,18 @@
             heLog.error(t, "Close handler threw an exception");
         }
     }
+
+    /**
+     * A close handler which closes another resource.
+     *
+     * @param c the resource to close
+     * @return the close handler
+     */
+    public static CloseHandler<Object> closingCloseHandler(final Closeable c) {
+        return new CloseHandler<Object>() {
+            public void handleClose(final Object closed) {
+                IoUtils.safeClose(c);
+            }
+        };
+    }
 }
-

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/InputStreamHandlerFactory.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/InputStreamHandlerFactory.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/InputStreamHandlerFactory.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -26,9 +26,9 @@
 import java.io.InputStream;
 import java.nio.ByteBuffer;
 import java.nio.channels.Channel;
+import org.jboss.xnio.ChannelListener;
 import org.jboss.xnio.IoFuture;
 import org.jboss.xnio.IoUtils;
-import org.jboss.xnio.ChannelListener;
 import org.jboss.xnio.channels.StreamChannel;
 import org.jboss.xnio.log.Logger;
 

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/ObjectPipe.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/ObjectPipe.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/ObjectPipe.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,15 +22,15 @@
 
 package org.jboss.remoting3.stream;
 
+import java.io.EOFException;
 import java.io.IOException;
 import java.io.InterruptedIOException;
-import java.io.EOFException;
 import java.util.ArrayDeque;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.locks.Condition;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.Condition;
-import java.util.Queue;
-import java.util.NoSuchElementException;
 
 /**
  * A pipe for objects.  Typically, data is written to the sink side of the pipe from one thread while being read from

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/OutputStreamHandlerFactory.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/OutputStreamHandlerFactory.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/OutputStreamHandlerFactory.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -26,19 +26,20 @@
 import java.io.InputStreamReader;
 import java.io.InterruptedIOException;
 import java.io.OutputStream;
-import static java.lang.Math.min;
-import static java.lang.Thread.currentThread;
 import java.nio.ByteBuffer;
 import java.nio.channels.Channel;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
+import org.jboss.xnio.ChannelListener;
 import org.jboss.xnio.IoFuture;
-import org.jboss.xnio.ChannelListener;
 import org.jboss.xnio.IoUtils;
-import static org.jboss.xnio.IoUtils.safeClose;
 import org.jboss.xnio.channels.ChannelInputStream;
 import org.jboss.xnio.channels.StreamChannel;
 
+import static java.lang.Math.min;
+import static java.lang.Thread.currentThread;
+import static org.jboss.xnio.IoUtils.safeClose;
+
 /**
  * A handler factory for automatic forwarding of output streams.
  */

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/ReaderInputStream.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/ReaderInputStream.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/ReaderInputStream.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -33,31 +33,66 @@
 import java.nio.charset.CharsetEncoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
+import org.jboss.marshalling.ByteInput;
 import org.jboss.xnio.Buffers;
 
-public final class ReaderInputStream extends InputStream {
+/**
+ * An input stream which encodes characters into bytes.
+ */
+public final class ReaderInputStream extends InputStream implements ByteInput {
 
     private final Reader reader;
     private final CharsetEncoder encoder;
     private final CharBuffer charBuffer;
     private final ByteBuffer byteBuffer;
 
+    /**
+     * Construct a new instance.
+     *
+     * @param reader the reader to encode from
+     */
     public ReaderInputStream(final Reader reader) {
         this(reader, Charset.defaultCharset());
     }
 
+    /**
+     * Construct a new instance.
+     *
+     * @param reader the reader to encode from
+     * @param charsetName the character set name
+     * @throws UnsupportedEncodingException if the character set is not supported
+     */
     public ReaderInputStream(final Reader reader, final String charsetName) throws UnsupportedEncodingException {
         this(reader, Streams.getCharset(charsetName));
     }
 
+    /**
+     * Construct a new instance.
+     *
+     * @param reader the reader to encode from
+     * @param charset the character set
+     */
     public ReaderInputStream(final Reader reader, final Charset charset) {
         this(reader, getEncoder(charset));
     }
 
+    /**
+     * Construct a new instance.
+     *
+     * @param reader the reader to encode from
+     * @param encoder the character set encoder
+     */
     public ReaderInputStream(final Reader reader, final CharsetEncoder encoder) {
         this(reader, encoder, 1024);
     }
 
+    /**
+     * Construct a new instance.
+     *
+     * @param reader the reader to encode from
+     * @param encoder the character set encoder
+     * @param bufferSize the buffer size to use
+     */
     public ReaderInputStream(final Reader reader, final CharsetEncoder encoder, final int bufferSize) {
         this.reader = reader;
         this.encoder = encoder;
@@ -72,6 +107,7 @@
         return encoder;
     }
 
+    /** {@inheritDoc} */
     public int read() throws IOException {
         final ByteBuffer byteBuffer = this.byteBuffer;
         if (! byteBuffer.hasRemaining()) {
@@ -82,6 +118,7 @@
         return byteBuffer.get() & 0xff;
     }
 
+    /** {@inheritDoc} */
     public int read(final byte[] b, int off, int len) throws IOException {
         final ByteBuffer byteBuffer = this.byteBuffer;
         int cnt = 0;
@@ -140,6 +177,7 @@
         }
     }
 
+    /** {@inheritDoc} */
     public long skip(long n) throws IOException {
         final ByteBuffer byteBuffer = this.byteBuffer;
         int cnt = 0;
@@ -157,16 +195,23 @@
         return cnt;
     }
 
+    /** {@inheritDoc} */
     public int available() throws IOException {
         return byteBuffer.remaining();
     }
 
+    /** {@inheritDoc} */
     public void close() throws IOException {
         byteBuffer.clear();
         charBuffer.clear();
         reader.close();
     }
 
+    /**
+     * Get a string representation of this object.
+     *
+     * @return the string
+     */
     public String toString() {
         return "ReaderInputStream over " + reader;
     }

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamContext.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamContext.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamContext.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,10 +22,10 @@
 
 package org.jboss.remoting3.stream;
 
+import java.io.Serializable;
+import java.util.concurrent.Executor;
 import org.jboss.marshalling.Marshaller;
 import org.jboss.marshalling.Unmarshaller;
-import java.io.Serializable;
-import java.util.concurrent.Executor;
 
 /**
  *

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamHandler.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,10 +22,10 @@
 
 package org.jboss.remoting3.stream;
 
+import java.io.Serializable;
+import java.nio.channels.Channel;
+import org.jboss.xnio.ChannelListener;
 import org.jboss.xnio.IoFuture;
-import org.jboss.xnio.ChannelListener;
-import java.nio.channels.Channel;
-import java.io.Serializable;
 
 /**
  * A stream handler for an individual object instance.  Instances of this class are used on both

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamHandlerFactory.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamHandlerFactory.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/StreamHandlerFactory.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,8 +22,8 @@
 
 package org.jboss.remoting3.stream;
 
+import java.io.IOException;
 import java.nio.channels.Channel;
-import java.io.IOException;
 
 /**
  * A stream handler factory.  Produces stream handler instances for the given object, which in turn uses a specified

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/Streams.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/Streams.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/Streams.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -30,13 +30,13 @@
 import java.util.Collection;
 import java.util.Enumeration;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.NoSuchElementException;
-import java.util.Map;
 import java.util.concurrent.Executor;
 import org.jboss.marshalling.Pair;
+import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.FutureResult;
 import org.jboss.xnio.IoFuture;
-import org.jboss.xnio.FutureResult;
-import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoUtils;
 
 /**

Modified: remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/WriterOutputStream.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/WriterOutputStream.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/stream/WriterOutputStream.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -33,8 +33,12 @@
 import java.nio.charset.CharsetDecoder;
 import java.nio.charset.CoderResult;
 import java.nio.charset.CodingErrorAction;
+import org.jboss.marshalling.ByteOutput;
 
-public final class WriterOutputStream extends OutputStream {
+/**
+ * An output stream which decodes bytes into a character writer.
+ */
+public final class WriterOutputStream extends OutputStream implements ByteOutput {
 
     private final Writer writer;
     private final CharsetDecoder decoder;
@@ -42,14 +46,32 @@
     private final char[] chars;
     private volatile boolean closed;
 
+    /**
+     * Construct a new instance.
+     *
+     * @param writer the writer to decode into
+     */
     public WriterOutputStream(final Writer writer) {
         this(writer, Charset.defaultCharset());
     }
 
+    /**
+     * Construct a new instance.
+     *
+     * @param writer the writer to decode into
+     * @param decoder the charset decoder to use
+     */
     public WriterOutputStream(final Writer writer, final CharsetDecoder decoder) {
         this(writer, decoder, 1024);
     }
 
+    /**
+     * Construct a new instance.
+     *
+     * @param writer the writer to decode into
+     * @param decoder the charset decoder to use
+     * @param bufferSize the buffer size to use
+     */
     public WriterOutputStream(final Writer writer, final CharsetDecoder decoder, int bufferSize) {
         this.writer = writer;
         this.decoder = decoder;
@@ -57,10 +79,23 @@
         chars = new char[(int) ((float)bufferSize * decoder.maxCharsPerByte() + 0.5f)];
     }
 
+    /**
+     * Construct a new instance.
+     *
+     * @param writer the writer to decode into
+     * @param charset the character set to use
+     */
     public WriterOutputStream(final Writer writer, final Charset charset) {
         this(writer, getDecoder(charset));
     }
 
+    /**
+     * Construct a new instance.
+     *
+     * @param writer the writer to decode into
+     * @param charsetName the character set name to use
+     * @throws UnsupportedEncodingException if the character set name is unknown
+     */
     public WriterOutputStream(final Writer writer, final String charsetName) throws UnsupportedEncodingException {
         this(writer, Streams.getCharset(charsetName));
     }
@@ -73,6 +108,7 @@
         return decoder;
     }
 
+    /** {@inheritDoc} */
     public void write(final int b) throws IOException {
         if (closed) throw new IOException("Stream closed");
         final ByteBuffer byteBuffer = this.byteBuffer;
@@ -82,6 +118,7 @@
         byteBuffer.put((byte) b);
     }
 
+    /** {@inheritDoc} */
     public void write(final byte[] b, int off, int len) throws IOException {
         if (closed) throw new IOException("Stream closed");
         final ByteBuffer byteBuffer = this.byteBuffer;
@@ -134,11 +171,13 @@
         }
     }
 
+    /** {@inheritDoc} */
     public void flush() throws IOException {
         if (closed) throw new IOException("Stream closed");
         writer.flush();
     }
 
+    /** {@inheritDoc} */
     public void close() throws IOException {
         closed = true;
         doFlush(true);
@@ -146,6 +185,11 @@
         writer.close();
     }
 
+    /**
+     * Get the string representation of this object.
+     *
+     * @return the string
+     */
     public String toString() {
         return "Output stream writing to " + writer;
     }

Modified: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/AbstractRemoteTestCase.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/AbstractRemoteTestCase.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/AbstractRemoteTestCase.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -28,16 +28,15 @@
 import java.net.URI;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
-import org.jboss.remoting3.CloseHandler;
 import org.jboss.remoting3.Connection;
 import org.jboss.remoting3.RemotingOptions;
 import org.jboss.remoting3.security.SimpleServerAuthenticationProvider;
 import org.jboss.remoting3.spi.NetworkServerProvider;
 import org.jboss.remoting3.spi.ProtocolServiceType;
+import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.AcceptingServer;
 import org.jboss.xnio.ChannelListener;
 import org.jboss.xnio.IoFuture;
-import org.jboss.xnio.IoUtils;
 import org.jboss.xnio.OptionMap;
 import org.jboss.xnio.Options;
 import org.jboss.xnio.Xnio;
@@ -53,9 +52,9 @@
 
     @BeforeTest
     public void setUp() throws IOException {
+        super.setUp();
         enter();
         try {
-            super.setUp();
             final SimpleServerAuthenticationProvider authenticationProvider = new SimpleServerAuthenticationProvider();
             authenticationProvider.addUser("user", "endpoint", "password".toCharArray());
             endpoint.addProtocolService(ProtocolServiceType.SERVER_AUTHENTICATION_PROVIDER, "test", authenticationProvider);
@@ -78,11 +77,7 @@
         final InetSocketAddress localAddress = future.get().getLocalAddress();
         final OptionMap clientOptions = OptionMap.EMPTY;
         final Connection connection = endpoint.connect(new URI(getScheme(), null, localAddress.getAddress().getHostAddress(), localAddress.getPort(), null, null, null), clientOptions, "user", null, "password".toCharArray()).get();
-        connection.addCloseHandler(new CloseHandler<Connection>() {
-            public void handleClose(final Connection closed) {
-                IoUtils.safeClose(server);
-            }
-        });
+        connection.addCloseHandler(SpiUtils.closingCloseHandler(server));
         return connection;
     }
 

Modified: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/CloseableTestCase.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/CloseableTestCase.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/CloseableTestCase.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -39,7 +39,7 @@
 /**
  *
  */
- at Test
+ at Test(suiteName = "utils")
 public final class CloseableTestCase {
 
     private static final Logger log = Logger.getLogger("test");

Modified: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/EndpointTestCase.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/EndpointTestCase.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/EndpointTestCase.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -27,6 +27,8 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
 import org.jboss.remoting3.Client;
+import org.jboss.remoting3.ClientContext;
+import org.jboss.remoting3.ClientListener;
 import org.jboss.remoting3.CloseHandler;
 import org.jboss.remoting3.Endpoint;
 import org.jboss.remoting3.RemoteExecutionException;
@@ -44,7 +46,7 @@
 /**
  *
  */
- at Test
+ at Test(suiteName = "endpoint")
 public final class EndpointTestCase {
 
     private static final Logger log = Logger.getLogger("test");
@@ -81,15 +83,19 @@
             try {
                 final Object requestObj = new Object();
                 final Object replyObj = new Object();
-                final Client<Object, Object> localClient = Remoting.createLocalClient(endpoint, new RequestListener<Object, Object>() {
-                    public void handleRequest(final RequestContext<Object> objectRequestContext, final Object request) throws RemoteExecutionException {
-                        try {
-                            objectRequestContext.sendReply(replyObj);
-                        } catch (IOException e) {
-                            throw new RemoteExecutionException(e);
-                        }
+                final Client<Object, Object> localClient = endpoint.createLocalClient(new ClientListener<Object, Object>() {
+                    public RequestListener<Object, Object> handleClientOpen(final ClientContext clientContext, final OptionMap optionMap) {
+                        return new RequestListener<Object, Object>() {
+                            public void handleRequest(final RequestContext<Object> objectRequestContext, final Object request) throws RemoteExecutionException {
+                                try {
+                                    objectRequestContext.sendReply(replyObj);
+                                } catch (IOException e) {
+                                    throw new RemoteExecutionException(e);
+                                }
+                            }
+                        };
                     }
-                }, Object.class, Object.class);
+                }, Object.class, Object.class, Thread.currentThread().getContextClassLoader(), OptionMap.EMPTY);
                 localClient.addCloseHandler(new CloseHandler<Client<Object, Object>>() {
                     public void handleClose(final Client<Object, Object> closed) {
                         log.info("Listener closed");
@@ -115,15 +121,19 @@
             try {
                 final Object requestObj = new Object();
                 final Object replyObj = new Object();
-                final Client<Object, Object> localClient = Remoting.createLocalClient(endpoint, new RequestListener<Object, Object>() {
-                    public void handleRequest(final RequestContext<Object> objectRequestContext, final Object request) throws RemoteExecutionException {
-                        try {
-                            objectRequestContext.sendReply(replyObj);
-                        } catch (IOException e) {
-                            throw new RemoteExecutionException(e);
-                        }
+                final Client<Object, Object> localClient = endpoint.createLocalClient(new ClientListener<Object, Object>() {
+                    public RequestListener<Object, Object> handleClientOpen(final ClientContext clientContext, final OptionMap optionMap) {
+                        return new RequestListener<Object, Object>() {
+                            public void handleRequest(final RequestContext<Object> objectRequestContext, final Object request) throws RemoteExecutionException {
+                                try {
+                                    objectRequestContext.sendReply(replyObj);
+                                } catch (IOException e) {
+                                    throw new RemoteExecutionException(e);
+                                }
+                            }
+                        };
                     }
-                }, Object.class, Object.class);
+                }, Object.class, Object.class, Thread.currentThread().getContextClassLoader(), OptionMap.EMPTY);
                 localClient.addCloseHandler(new CloseHandler<Client<Object, Object>>() {
                     public void handleClose(final Client<Object, Object> closed) {
                         log.info("Listener closed");

Modified: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -23,7 +23,6 @@
 package org.jboss.remoting3.test;
 
 import java.io.IOException;
-import org.jboss.marshalling.river.RiverMarshaller;
 import org.jboss.remoting3.Client;
 import org.jboss.remoting3.ClientConnector;
 import org.jboss.remoting3.ClientContext;
@@ -38,6 +37,7 @@
 import org.jboss.remoting3.RequestListener;
 import org.jboss.remoting3.ServiceNotFoundException;
 import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
 import org.jboss.xnio.Xnio;
 import org.jboss.xnio.log.Logger;
 import org.testng.SkipException;
@@ -58,7 +58,7 @@
     public void setUp() throws IOException {
         enter();
         try {
-            Thread.currentThread().setContextClassLoader(RiverMarshaller.class.getClassLoader());
+            Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
             endpoint = Remoting.getConfiguredEndpoint();
         } finally {
             exit();
@@ -85,7 +85,7 @@
             final InvocationTestObject replyObj = new InvocationTestObject();
             final Registration registration = endpoint.serviceBuilder().setGroupName("foo").setServiceType("test1").setRequestType(InvocationTestObject.class).
                     setReplyType(InvocationTestObject.class).setClientListener(new ClientListener<InvocationTestObject, InvocationTestObject>() {
-                public RequestListener<InvocationTestObject, InvocationTestObject> handleClientOpen(final ClientContext clientContext) {
+                public RequestListener<InvocationTestObject, InvocationTestObject> handleClientOpen(final ClientContext clientContext, final OptionMap optionMap) {
                     clientContext.addCloseHandler(new CloseHandler<ClientContext>() {
                         public void handleClose(final ClientContext closed) {
                             log.info("Client closed");
@@ -106,7 +106,7 @@
             try {
                 final Connection connection = getConnection();
                 try {
-                    final Client<InvocationTestObject, InvocationTestObject> client = connection.openClient("test1", "*", InvocationTestObject.class, InvocationTestObject.class).get();
+                    final Client<InvocationTestObject, InvocationTestObject> client = connection.openClient("test1", "*", InvocationTestObject.class, InvocationTestObject.class, getClass().getClassLoader(), OptionMap.EMPTY).get();
                     try {
                         assertEquals(replyObj, client.invoke(requestObj));
                     } finally {
@@ -133,7 +133,7 @@
             final InvocationTestObject replyObj = new InvocationTestObject();
             final Registration registration = endpoint.serviceBuilder().setGroupName("foo").setServiceType("test2").setRequestType(InvocationTestObject.class).
                     setReplyType(InvocationTestObject.class).setClientListener(new ClientListener<InvocationTestObject, InvocationTestObject>() {
-                public RequestListener<InvocationTestObject, InvocationTestObject> handleClientOpen(final ClientContext clientContext) {
+                public RequestListener<InvocationTestObject, InvocationTestObject> handleClientOpen(final ClientContext clientContext, final OptionMap optionMap) {
                     clientContext.addCloseHandler(new CloseHandler<ClientContext>() {
                         public void handleClose(final ClientContext closed) {
                             log.info("Listener closed");
@@ -183,7 +183,7 @@
 
             final Registration registration = endpoint.serviceBuilder().setGroupName("foo").setServiceType("test3").setRequestType(ClientConnector.class).
                     setReplyType(InvocationTestObject.class).setClientListener(new ClientListener<ClientConnector, InvocationTestObject>() {
-                public RequestListener<ClientConnector, InvocationTestObject> handleClientOpen(final ClientContext clientContext) {
+                public RequestListener<ClientConnector, InvocationTestObject> handleClientOpen(final ClientContext clientContext, final OptionMap optionMap) {
                     clientContext.addCloseHandler(new CloseHandler<ClientContext>() {
                         public void handleClose(final ClientContext closed) {
                             log.info("Listener closed");

Modified: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalTestCase.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalTestCase.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalTestCase.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -28,7 +28,7 @@
 import org.jboss.xnio.OptionMap;
 import org.testng.annotations.Test;
 
- at Test(description = "Local Tests")
+ at Test(suiteName = "local")
 public final class LocalTestCase extends InvocationTestBase {
 
     protected Connection getConnection() throws IOException {

Copied: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalValueTestCase.java (from rev 5793, remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalTestCase.java)
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalValueTestCase.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalValueTestCase.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -0,0 +1,38 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.remoting3.test;
+
+import java.io.IOException;
+import java.net.URI;
+import org.jboss.remoting3.Connection;
+import org.jboss.remoting3.RemotingOptions;
+import org.jboss.xnio.OptionMap;
+import org.testng.annotations.Test;
+
+ at Test(suiteName = "local")
+public final class LocalValueTestCase extends InvocationTestBase {
+
+    protected Connection getConnection() throws IOException {
+        return endpoint.connect(URI.create("local:///"), OptionMap.builder().set(RemotingOptions.CALL_BY_VALUE, true).getMap()).get();
+    }
+}
\ No newline at end of file

Modified: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteSslTestCase.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteSslTestCase.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteSslTestCase.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -22,7 +22,6 @@
 
 package org.jboss.remoting3.test;
 
-import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.security.NoSuchAlgorithmException;
 import java.security.NoSuchProviderException;
@@ -35,7 +34,7 @@
 import org.testng.SkipException;
 import org.testng.annotations.Test;
 
- at Test(suiteName = "Remote SSL tests")
+ at Test(suiteName = "remote+ssl")
 public final class RemoteSslTestCase extends AbstractRemoteTestCase {
     // Use anonymous ciphers so we don't need a trust store configuration of any sort
     private static final String[] CIPHER_SUITES = {

Modified: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -30,7 +30,7 @@
 import org.jboss.xnio.channels.ConnectedStreamChannel;
 import org.testng.annotations.Test;
 
- at Test(suiteName = "Remote tests")
+ at Test(suiteName = "remote")
 public final class RemoteTestCase extends AbstractRemoteTestCase {
     protected TcpServer getServer(final ChannelListener<ConnectedStreamChannel<InetSocketAddress>> listener, final Xnio xnio) {
         return xnio.createTcpServer(listener, OptionMap.EMPTY);

Modified: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/StreamsTestCase.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/StreamsTestCase.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/StreamsTestCase.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -40,7 +40,7 @@
 /**
  *
  */
- at Test(suiteName = "Streams Tests")
+ at Test(suiteName = "streams")
 public final class StreamsTestCase {
 
     public void testCollectionObjectSink() throws Throwable {

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/LocalBasicExampleMain.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/LocalBasicExampleMain.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/LocalBasicExampleMain.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -5,6 +5,7 @@
 import org.jboss.remoting3.Endpoint;
 import org.jboss.remoting3.Remoting;
 import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
 
 /**
  *
@@ -15,10 +16,10 @@
     }
 
     public static void main(String[] args) throws IOException {
-        final StringRot13RequestListener listener = new StringRot13RequestListener();
+        final StringRot13ClientListener  listener = new StringRot13ClientListener();
         final Endpoint endpoint = Remoting.getConfiguredEndpoint();
         try {
-            final Client<String,String> client = Remoting.createLocalClient(endpoint, listener, null, null);
+            final Client<String,String> client = endpoint.createLocalClient(listener, String.class, String.class, Thread.currentThread().getContextClassLoader(), OptionMap.EMPTY);
             try {
                 final String original = "The Secret Message\n";
                 final String result = client.invoke(original);

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StringRot13ClientListener.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StringRot13ClientListener.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/simple/StringRot13ClientListener.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -25,10 +25,11 @@
 import org.jboss.remoting3.ClientListener;
 import org.jboss.remoting3.RequestListener;
 import org.jboss.remoting3.ClientContext;
+import org.jboss.xnio.OptionMap;
 
 public final class StringRot13ClientListener implements ClientListener<String, String> {
 
-    public RequestListener<String, String> handleClientOpen(final ClientContext clientContext) {
+    public RequestListener<String, String> handleClientOpen(final ClientContext clientContext, final OptionMap optionMap) {
         return new StringRot13RequestListener();
     }
 }

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/RequestHandlerFuture.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/RequestHandlerFuture.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/RequestHandlerFuture.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -24,7 +24,7 @@
 
 import java.io.IOException;
 
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.xnio.Result;
 
 /**
@@ -34,8 +34,8 @@
  * Copyright Oct 24, 2009
  * </p>
  */
-public class RequestHandlerFuture implements Result<RequestHandler> {
-   private RequestHandler requestHandler;
+public class RequestHandlerFuture implements Result<RemoteRequestHandler> {
+   private RemoteRequestHandler requestHandler;
    private IOException exception;
 
    @Override
@@ -48,12 +48,12 @@
    }
 
    @Override
-   public boolean setResult(RequestHandler result) {
+   public boolean setResult(RemoteRequestHandler result) {
       this.requestHandler = result;
       return true;
    }
 
-   public RequestHandler get() {
+   public RemoteRequestHandler get() {
       return requestHandler;
    }
    

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketClientConnectionHandler.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketClientConnectionHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketClientConnectionHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -36,7 +36,8 @@
 import org.jboss.remoting3.samples.socket.SocketProtocol;
 import org.jboss.remoting3.spi.AbstractHandleableCloseable;
 import org.jboss.remoting3.spi.ConnectionHandler;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoUtils;
@@ -65,7 +66,7 @@
       this.localHost = localHost;
    }
 
-   public RequestHandlerConnector createConnector(RequestHandler localHandler) {
+   public RequestHandlerConnector createConnector(LocalRequestHandler localHandler) {
       try {
          SocketRequestHandlerConnector<?, ?> connector = new SocketRequestHandlerConnector<Object, Object>(getExecutor(), localHandler, localHost);
          registerCloseHandler(connector);
@@ -76,7 +77,7 @@
       } 
    }
 
-   public Cancellable open(final String serviceType, final String groupName, Result<RequestHandler> result) {
+   public Cancellable open(final String serviceType, final String groupName, Result<RemoteRequestHandler> result, final ClassLoader classLoader, final OptionMap optionMap) {
       try
       {
          final Socket socket = new Socket(remoteHost, remotePort);

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketClientRequestHandler.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketClientRequestHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketClientRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -27,8 +27,8 @@
 import org.jboss.marshalling.Marshaller;
 import org.jboss.marshalling.Unmarshaller;
 import org.jboss.remoting3.spi.AbstractHandleableCloseable;
-import org.jboss.remoting3.spi.ReplyHandler;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalReplyHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.SpiUtils;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoUtils;
@@ -41,7 +41,7 @@
  * Copyright Oct 14, 2009
  * </p>
  */
-public class SocketClientRequestHandler extends AbstractHandleableCloseable<RequestHandler> implements RequestHandler {
+public class SocketClientRequestHandler extends AbstractHandleableCloseable<RemoteRequestHandler> implements RemoteRequestHandler {
    private static final Logger log = Logger.getLogger("org.jboss.remoting.samples.socket.SocketRequestHandler");
 
    private Marshaller marshaller;
@@ -53,7 +53,7 @@
       this.unmarshaller = unmarshaller;
    }
 
-   public Cancellable receiveRequest(Object request, final ReplyHandler replyHandler) {
+   public Cancellable receiveRequest(Object request, final LocalReplyHandler replyHandler) {
       try {
          marshaller.writeObject(request);
          marshaller.flush();

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketRequestHandlerConnector.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketRequestHandlerConnector.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/client/SocketRequestHandlerConnector.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -42,7 +42,8 @@
 import org.jboss.remoting3.samples.socket.SocketProtocol;
 import org.jboss.remoting3.samples.socket.server.SocketServerRequestHandler;
 import org.jboss.remoting3.spi.AbstractHandleableCloseable;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.IoUtils;
@@ -70,7 +71,7 @@
       super(new ThreadPoolExecutor(10, 10, 0L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()));
    }
    
-   public SocketRequestHandlerConnector(Executor executor, RequestHandler localRequestHandler, String callbackHost) throws IOException {
+   public SocketRequestHandlerConnector(Executor executor, LocalRequestHandler localRequestHandler, String callbackHost) throws IOException {
       super(executor);
       this.callbackHost = callbackHost;
       requestHandlerServer = new RequestHandlerServer(localRequestHandler, callbackHost);
@@ -78,7 +79,7 @@
       requestHandlerServer.start();
    }
 
-   public Cancellable createRequestHandler(Result<RequestHandler> result) throws SecurityException {
+   public Cancellable createRequestHandler(Result<RemoteRequestHandler> result) throws SecurityException {
       if (socketClientRequestHandler != null) {
          throw new SecurityException(this + ": a SocketClientRequestHandler has already been created");
       }
@@ -125,12 +126,12 @@
    }
 
    static class RequestHandlerServer extends Thread {
-      private RequestHandler localRequestHandler;
+      private LocalRequestHandler localRequestHandler;
       private ServerSocket serverSocket;
       private Socket socket;
       private SocketServerRequestHandler socketServerRequestHandler;
 
-      RequestHandlerServer(RequestHandler localRequestHandler, String localHost) throws IOException {
+      RequestHandlerServer(LocalRequestHandler localRequestHandler, String localHost) throws IOException {
          this.localRequestHandler = localRequestHandler;
          serverSocket = new ServerSocket();
          serverSocket.bind(new InetSocketAddress(localHost, 0));

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketClientListener.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketClientListener.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketClientListener.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -30,6 +30,7 @@
 import org.jboss.remoting3.Endpoint;
 import org.jboss.remoting3.RequestListener;
 import org.jboss.remoting3.samples.socket.SocketServiceConfiguration;
+import org.jboss.xnio.OptionMap;
 
 /**
  * @author <a href="ron.sigal at jboss.com">Ron Sigal</a>
@@ -62,7 +63,7 @@
       this.requestListener = requestListener;
    }
    
-   public RequestListener<I, O> handleClientOpen(ClientContext clientContext) {
+   public RequestListener<I, O> handleClientOpen(ClientContext clientContext, final OptionMap optionMap) {
       return requestListener;
    }
 }

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerConnectionHandler.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerConnectionHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerConnectionHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -35,9 +35,11 @@
 import org.jboss.remoting3.spi.AbstractHandleableCloseable;
 import org.jboss.remoting3.spi.ConnectionHandler;
 import org.jboss.remoting3.spi.ConnectionHandlerContext;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.remoting3.spi.RequestHandlerConnector;
 import org.jboss.xnio.Cancellable;
+import org.jboss.xnio.OptionMap;
 import org.jboss.xnio.Result;
 import org.jboss.xnio.log.Logger;
 
@@ -105,12 +107,12 @@
    }
 
    @Override
-   public RequestHandlerConnector createConnector(RequestHandler localHandler) {
+   public RequestHandlerConnector createConnector(LocalRequestHandler localHandler) {
       return null;
    }
 
    @Override
-   public Cancellable open(final String serviceType, final String groupName, Result<RequestHandler> result) {
+   public Cancellable open(final String serviceType, final String groupName, Result<RemoteRequestHandler> result, final ClassLoader classLoader, final OptionMap optionMap) {
       return null;
    }
 

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerReplyHandler.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerReplyHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerReplyHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -24,7 +24,7 @@
 import java.io.IOException;
 
 import org.jboss.marshalling.Marshaller;
-import org.jboss.remoting3.spi.ReplyHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
 import org.jboss.xnio.log.Logger;
 
 /**
@@ -34,7 +34,7 @@
  * Copyright Oct 16, 2009
  * </p>
  */
-public class SocketServerReplyHandler implements ReplyHandler
+public class SocketServerReplyHandler implements RemoteReplyHandler
 {
    private static final Logger log = Logger.getLogger(SocketServerReplyHandler.class);
    private Marshaller marshaller;

Modified: remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerRequestHandler.java
===================================================================
--- remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerRequestHandler.java	2010-03-05 06:40:29 UTC (rev 5803)
+++ remoting3/trunk/samples/src/main/java/org/jboss/remoting3/samples/socket/server/SocketServerRequestHandler.java	2010-03-08 23:18:30 UTC (rev 5804)
@@ -37,8 +37,10 @@
 import org.jboss.remoting3.samples.socket.RequestHandlerFuture;
 import org.jboss.remoting3.samples.socket.SocketProtocol;
 import org.jboss.remoting3.spi.ConnectionHandlerContext;
-import org.jboss.remoting3.spi.ReplyHandler;
-import org.jboss.remoting3.spi.RequestHandler;
+import org.jboss.remoting3.spi.LocalReplyHandler;
+import org.jboss.remoting3.spi.LocalRequestHandler;
+import org.jboss.remoting3.spi.RemoteReplyHandler;
+import org.jboss.remoting3.spi.RemoteRequestHandler;
 import org.jboss.xnio.Cancellable;
 import org.jboss.xnio.OptionMap;
 import org.jboss.xnio.log.Logger;
@@ -50,13 +52,13 @@
  * Copyright Oct 14, 2009
  * </p>
  */
-public class SocketServerRequestHandler extends Thread implements RequestHandler {
+public class SocketServerRequestHandler extends Thread implements RemoteRequestHandler {
    private static final Logger log = Logger.getLogger(SocketServerRequestHandler.class);
    private Socket socket;
    private Marshaller marshaller;
    private Unmarshaller unmarshaller;
-   private RequestHandler requestHandler;
-   private ReplyHandler replyHandler;
+   private LocalRequestHandler requestHandler;
+   private RemoteReplyHandler replyHandler;
    private boolean running;
 
    /**
@@ -76,22 +78,14 @@
          final String serviceType = unmarshaller.readUTF();
          final String groupName = unmarshaller.readUTF();
          final RequestHandlerFuture requestHandlerFuture = new RequestHandlerFuture();
-
-         ConnectionHandlerContext.ServiceResult serviceResult = new ConnectionHandlerContext.ServiceResult() {
-            public void opened(final RequestHandler requestHandler, final OptionMap optionMap) {
-               requestHandlerFuture.setResult(requestHandler);
-            }
-            public void notFound() {
-               requestHandlerFuture.setException(new ServiceOpenException("No such service located"));
-            }
-         };
-         final RequestHandler requestHandler = connectionHandlerContext.openService(serviceType, groupName, OptionMap.EMPTY);
+         final LocalRequestHandler requestHandler = connectionHandlerContext.openService(serviceType, groupName, OptionMap.EMPTY);
          if (requestHandler == null) {
              requestHandlerFuture.setException(new ServiceNotFoundException(ServiceURI.create(serviceType, groupName, null)));
          } else {
-             requestHandlerFuture.setResult(requestHandler);
+//             requestHandlerFuture.setResult(requestHandler);
+             requestHandlerFuture.setResult(null);
          }
-         this.requestHandler = requestHandlerFuture.get();
+//         this.requestHandler = requestHandlerFuture.get();
          if (this.requestHandler == null) {
             throw requestHandlerFuture.getException();
          }
@@ -102,7 +96,7 @@
    }
 
 
-   public <I, O> SocketServerRequestHandler(RequestHandler localRequestHandler, Socket socket) {
+   public <I, O> SocketServerRequestHandler(LocalRequestHandler localRequestHandler, Socket socket) {
       try {
          this.requestHandler = localRequestHandler;
          this.socket = socket;
@@ -129,7 +123,8 @@
             log.info(SocketServerRequestHandler.this + " waiting for next request");
             request = unmarshaller.readObject();
             log.info(SocketServerRequestHandler.this + " got request: " + request);
-            requestHandler.receiveRequest(request, replyHandler);
+//            requestHandler.receiveRequest(request, replyHandler);
+            requestHandler.receiveRequest(null, null);
          } catch (ClassNotFoundException e) {
             e.printStackTrace();
          } catch (IOException e) {
@@ -147,13 +142,13 @@
 
 
    @Override
-   public Cancellable receiveRequest(Object request, ReplyHandler replyHandler) {
+   public Cancellable receiveRequest(Object request, LocalReplyHandler replyHandler) {
       return null;
    }
 
 
    @Override
-   public org.jboss.remoting3.HandleableCloseable.Key addCloseHandler( CloseHandler<? super RequestHandler> handler) {
+   public org.jboss.remoting3.HandleableCloseable.Key addCloseHandler( CloseHandler<? super RemoteRequestHandler> handler) {
       return null;
    }
 



More information about the jboss-remoting-commits mailing list