You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2015/06/01 15:03:00 UTC

[1/4] mina-sshd git commit: [SSHD-480] Replace all "new Thread(...)" calls with "ExecutorService#submit"

Repository: mina-sshd
Updated Branches:
  refs/heads/master f8d842b1e -> 330d17c81


[SSHD-480] Replace all "new Thread(...)" calls with "ExecutorService#submit"


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/009d832d
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/009d832d
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/009d832d

Branch: refs/heads/master
Commit: 009d832d4a1316bcfc1e2921c386d078dcb3a3ce
Parents: f8d842b
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Mon Jun 1 16:01:21 2015 +0300
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Mon Jun 1 16:01:21 2015 +0300

----------------------------------------------------------------------
 src/tomcat-apr-5.5.23-sources.jar               | Bin 0 -> 25227 bytes
 .../main/java/org/apache/sshd/SshClient.java    |   9 +-
 .../main/java/org/apache/sshd/SshServer.java    |   9 +-
 .../java/org/apache/sshd/agent/SshAgent.java    |   3 +-
 .../sshd/agent/common/AbstractAgentClient.java  |  28 ++---
 .../sshd/agent/common/AbstractAgentProxy.java   |  96 +++++++++++---
 .../apache/sshd/agent/common/AgentDelegate.java |   5 +
 .../sshd/agent/local/AgentForwardedChannel.java |  15 ++-
 .../org/apache/sshd/agent/local/AgentImpl.java  |  32 +++--
 .../org/apache/sshd/agent/unix/AgentClient.java |  45 +++++--
 .../org/apache/sshd/agent/unix/AgentServer.java |  90 ++++++++++---
 .../sshd/agent/unix/AgentServerProxy.java       | 125 +++++++++++++------
 .../sshd/agent/unix/ChannelAgentForwarding.java |  90 +++++++++----
 .../sshd/agent/unix/UnixAgentFactory.java       |  54 +++++++-
 .../client/channel/AbstractClientChannel.java   |   3 +-
 .../sshd/client/channel/ChannelSession.java     |  56 ++++++---
 .../sshd/client/channel/ChannelSubsystem.java   |   7 +-
 .../sshd/common/channel/AbstractChannel.java    |  41 +++++-
 .../sshd/common/forward/TcpipServerChannel.java |  58 +++++++--
 .../sshd/common/util/threads/ThreadUtils.java   |  83 ++++++------
 .../apache/sshd/server/command/ScpCommand.java  |   2 +-
 .../apache/sshd/server/sftp/SftpSubsystem.java  |   2 +-
 .../test/java/org/apache/sshd/AgentTest.java    |  35 +++---
 .../apache/sshd/git/pack/GitPackCommand.java    |  11 +-
 .../org/apache/sshd/git/pgm/GitPgmCommand.java  |  11 +-
 25 files changed, 665 insertions(+), 245 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/src/tomcat-apr-5.5.23-sources.jar
----------------------------------------------------------------------
diff --git a/src/tomcat-apr-5.5.23-sources.jar b/src/tomcat-apr-5.5.23-sources.jar
new file mode 100644
index 0000000..5f6fd04
Binary files /dev/null and b/src/tomcat-apr-5.5.23-sources.jar differ

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/SshClient.java
index 4f74d61..7e13195 100644
--- a/sshd-core/src/main/java/org/apache/sshd/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/SshClient.java
@@ -240,9 +240,12 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
                     public void run() {
                         connector = null;
                         ioServiceFactory = null;
-                        if (shutdownExecutor && executor != null) {
-                            executor.shutdownNow();
-                            executor = null;
+                        if (shutdownExecutor && (executor != null) && (!executor.isShutdown())) {
+                            try {
+                                executor.shutdownNow();
+                            } finally {
+                                executor = null;
+                            }
                         }
                     }
                 })

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/SshServer.java
index 87ce889..024fc76 100644
--- a/sshd-core/src/main/java/org/apache/sshd/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/SshServer.java
@@ -323,9 +323,12 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
                     public void run() {
                         acceptor = null;
                         ioServiceFactory = null;
-                        if (shutdownExecutor && executor != null) {
-                            executor.shutdownNow();
-                            executor = null;
+                        if (shutdownExecutor && (executor != null) && (!executor.isShutdown())) {
+                            try {
+                                executor.shutdownNow();
+                            } finally {
+                                executor = null;
+                            }
                         }
                     }
                 })

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java
index b3b2ff5..4303721 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgent.java
@@ -18,7 +18,6 @@
  */
 package org.apache.sshd.agent;
 
-import java.io.Closeable;
 import java.io.IOException;
 import java.security.KeyPair;
 import java.security.PublicKey;
@@ -27,7 +26,7 @@ import java.util.List;
 /**
  * SSH key agent server
  */
-public interface SshAgent extends Closeable {
+public interface SshAgent extends java.nio.channels.Channel {
 
     public static final String SSH_AUTHSOCKET_ENV_NAME = "SSH_AUTH_SOCK";
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
index 44d6c23..9e48c7d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
@@ -36,6 +36,7 @@ import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.common.util.AbstractLoggingBean;
 import org.apache.sshd.common.util.KeyUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.BufferUtils;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 
 public abstract class AbstractAgentClient extends AbstractLoggingBean {
@@ -43,7 +44,7 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
     private final Buffer buffer = new ByteArrayBuffer();
     private final SshAgent agent;
 
-    public AbstractAgentClient(SshAgent agent) {
+    protected AbstractAgentClient(SshAgent agent) {
         this.agent = agent;
     }
 
@@ -76,8 +77,7 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
     protected void process(Buffer req, Buffer rep) throws Exception {
         int cmd = req.getByte();
         switch (cmd) {
-            case SSH2_AGENTC_REQUEST_IDENTITIES:
-            {
+            case SSH2_AGENTC_REQUEST_IDENTITIES: {
                 List<SshAgent.Pair<PublicKey,String>> keys = agent.getIdentities();
                 rep.putByte(SSH2_AGENT_IDENTITIES_ANSWER);
                 rep.putInt(keys.size());
@@ -87,11 +87,14 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
                 }
                 break;
             }
-            case SSH2_AGENTC_SIGN_REQUEST:
-            {
+            case SSH2_AGENTC_SIGN_REQUEST: {
                 PublicKey key = req.getPublicKey();
                 byte[] data = req.getBytes();
                 int flags = req.getInt();
+                if (log.isDebugEnabled()) {
+                    log.debug("SSH2_AGENTC_SIGN_REQUEST key={}, flags=0x{}, data={}",
+                              key.getAlgorithm(), Integer.toHexString(flags), BufferUtils.printHex(':', data));
+                }
                 Buffer sig = new ByteArrayBuffer();
                 sig.putString(KeyUtils.getKeyType(key));
                 sig.putBytes(agent.sign(key, data));
@@ -99,30 +102,27 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
                 rep.putBytes(sig.array(), sig.rpos(), sig.available());
                 break;
             }
-            case SSH2_AGENTC_ADD_IDENTITY:
-            {
+            case SSH2_AGENTC_ADD_IDENTITY: {
                 agent.addIdentity(req.getKeyPair(), req.getString());
                 rep.putByte(SSH_AGENT_SUCCESS);
                 break;
             }
-            case SSH2_AGENTC_REMOVE_IDENTITY:
-            {
+            case SSH2_AGENTC_REMOVE_IDENTITY: {
                 PublicKey key = req.getPublicKey();
                 agent.removeIdentity(key);
                 rep.putByte(SSH_AGENT_SUCCESS);
                 break;
             }
             case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
-            {
                 agent.removeAllIdentities();
                 rep.putByte(SSH_AGENT_SUCCESS);
                 break;
-            }
             default:
-            {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unknown command: {}", Integer.valueOf(cmd));
+                }
+
                 rep.putByte(SSH2_AGENT_FAILURE);
-                break;
-            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
index 7af4ee2..61df6ae 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
@@ -31,14 +31,46 @@ import java.io.IOException;
 import java.security.KeyPair;
 import java.security.PublicKey;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.common.SshException;
+import org.apache.sshd.common.util.AbstractLoggingBean;
+import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.BufferUtils;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.threads.ExecutorServiceConfigurer;
 
-public abstract class AbstractAgentProxy implements SshAgent {
+public abstract class AbstractAgentProxy extends AbstractLoggingBean implements SshAgent, ExecutorServiceConfigurer {
+    private ExecutorService executor;
+    private boolean shutdownExecutor;
+
+    protected AbstractAgentProxy() {
+        super();
+    }
+
+    @Override
+    public ExecutorService getExecutorService() {
+        return executor;
+    }
+
+    @Override
+    public void setExecutorService(ExecutorService service) {
+        executor = service;
+    }
+
+    @Override
+    public boolean isShutdownOnExit() {
+        return shutdownExecutor;
+    }
+
+    @Override
+    public void setShutdownOnExit(boolean shutdown) {
+        shutdownExecutor = shutdown;
+    }
 
     @Override
     public List<Pair<PublicKey, String>> getIdentities() throws IOException {
@@ -46,13 +78,15 @@ public abstract class AbstractAgentProxy implements SshAgent {
         buffer = request(prepare(buffer));
         int type = buffer.getByte();
         if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
-            throw new SshException("SSH agent failure");
+            throw new SshException("Bad agent identities answer: " + type);
         }
+
         int nbIdentities = buffer.getInt();
         if (nbIdentities > 1024) {
-            throw new SshException("SSH agent failure");
+            throw new SshException("Bad identities count: " + nbIdentities);
         }
-        List<Pair<PublicKey, String>> keys = new ArrayList<Pair<PublicKey, String>>();
+
+        List<Pair<PublicKey, String>> keys = new ArrayList<Pair<PublicKey, String>>(nbIdentities);
         for (int i = 0; i < nbIdentities; i++) {
             PublicKey key = buffer.getPublicKey();
             keys.add(new Pair<PublicKey, String>(key, buffer.getString()));
@@ -67,12 +101,19 @@ public abstract class AbstractAgentProxy implements SshAgent {
         buffer.putBytes(data);
         buffer.putInt(0);
         buffer = request(prepare(buffer));
-        if (buffer.getByte() != SSH2_AGENT_SIGN_RESPONSE) {
-            throw new SshException("SSH agent failure");
+        
+        byte responseType = buffer.getByte(); 
+        if (responseType != SSH2_AGENT_SIGN_RESPONSE) {
+            throw new SshException("Bad signing response type: " + (responseType & 0xFF));
         }
         Buffer buf = new ByteArrayBuffer(buffer.getBytes());
-        buf.getString(); // algo
-        return buf.getBytes();
+        String algorithm = buf.getString();
+        byte[] signature = buf.getBytes(); 
+        if (log.isDebugEnabled()) {
+            log.debug("sign(" + algorithm + "): " + BufferUtils.printHex(':', signature));
+        }
+
+        return signature;
     }
 
     @Override
@@ -80,9 +121,15 @@ public abstract class AbstractAgentProxy implements SshAgent {
         Buffer buffer = createBuffer(SSH2_AGENTC_ADD_IDENTITY);
         buffer.putKeyPair(key);
         buffer.putString(comment);
+        if (log.isDebugEnabled()) {
+            log.debug("addIdentity(" + comment + "): " + key.getPublic().getAlgorithm());
+        }
         buffer = request(prepare(buffer));
-        if (buffer.available() != 1 || buffer.getByte() != SSH_AGENT_SUCCESS) {
-            throw new SshException("SSH agent failure");
+        
+        int available = buffer.available();
+        byte response = (available >= 1) ? buffer.getByte() : -1;
+        if ((available != 1) || (response != SSH_AGENT_SUCCESS)) {
+            throw new SshException("Bad addIdentity response (" + (response & 0xFF) + ") - available=" + available);
         }
     }
 
@@ -90,24 +137,43 @@ public abstract class AbstractAgentProxy implements SshAgent {
     public void removeIdentity(PublicKey key) throws IOException {
         Buffer buffer = createBuffer(SSH2_AGENTC_REMOVE_IDENTITY);
         buffer.putPublicKey(key);
+        if (log.isDebugEnabled()) {
+            log.debug("removeIdentity: " + key.getAlgorithm());
+        }
+
         buffer = request(prepare(buffer));
-        if (buffer.available() != 1 || buffer.getByte() != SSH_AGENT_SUCCESS) {
-            throw new SshException("SSH agent failure");
+
+        int available = buffer.available();
+        byte response = (available >= 1) ? buffer.getByte() : -1;
+        if ((available != 1) || (response != SSH_AGENT_SUCCESS)) {
+            throw new SshException("Bad removeIdentity response (" + (response & 0xFF) + ") - available=" + available);
         }
     }
 
     @Override
     public void removeAllIdentities() throws IOException {
         Buffer buffer = createBuffer(SSH2_AGENTC_REMOVE_ALL_IDENTITIES);
+        if (log.isDebugEnabled()) {
+            log.debug("removeAllIdentities");
+        }
         buffer = request(prepare(buffer));
-        if (buffer.available() != 1 || buffer.getByte() != SSH_AGENT_SUCCESS) {
-            throw new SshException("SSH agent failure");
+
+        int available = buffer.available();
+        byte response = (available >= 1) ? buffer.getByte() : -1;
+        if ((available != 1) || (response != SSH_AGENT_SUCCESS)) {
+            throw new SshException("Bad removeAllIdentities response (" + (response & 0xFF) + ") - available=" + available);
         }
     }
 
     @Override
     public void close() throws IOException {
-        // nothing
+        ExecutorService service = getExecutorService();
+        if ((service != null) && isShutdownOnExit() && (!service.isShutdown())) {
+            Collection<?> runners = service.shutdownNow();
+            if (log.isDebugEnabled()) {
+                log.debug("close() - shutdown runners count=" + GenericUtils.size(runners));
+            }
+        }
     }
 
     protected Buffer createBuffer(byte cmd) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java b/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java
index 26df439..ed74fb6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/common/AgentDelegate.java
@@ -34,6 +34,11 @@ public class AgentDelegate implements SshAgent {
     }
 
     @Override
+    public boolean isOpen() {
+        return agent.isOpen();
+    }
+
+    @Override
     public void close() throws IOException {
         // ignored
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
index ea0779a..0318ac1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentForwardedChannel.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.util.Queue;
 import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.common.AbstractAgentProxy;
@@ -42,15 +43,25 @@ public class AgentForwardedChannel extends AbstractClientChannel {
 
     public SshAgent getAgent() {
         return new AbstractAgentProxy() {
+            private final AtomicBoolean open = new AtomicBoolean(true);
+
+            @Override
+            public boolean isOpen() {
+                return open.get();
+            }
+
             @Override
             protected Buffer request(Buffer buffer) throws IOException {
                 return AgentForwardedChannel.this.request(buffer);
             }
+
             @Override
             public void close() throws IOException {
-                AgentForwardedChannel.this.close(false);
+                if (open.getAndSet(false)) {
+                    AgentForwardedChannel.this.close(false);
+                    super.close();
+                }
             }
-
         };
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
index d4c6850..5ccea64 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
@@ -28,6 +28,7 @@ import java.security.interfaces.RSAPublicKey;
 import java.security.spec.ECParameterSpec;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.common.Signature;
@@ -40,13 +41,23 @@ import org.apache.sshd.common.signature.BuiltinSignatures;
 public class AgentImpl implements SshAgent {
 
     private final List<Pair<KeyPair, String>> keys = new ArrayList<Pair<KeyPair, String>>();
-    private boolean closed;
+    private final AtomicBoolean open = new AtomicBoolean(true);
+
+    public AgentImpl() {
+        super();
+    }
+
+    @Override
+    public boolean isOpen() {
+        return open.get();
+    }
 
     @Override
     public List<Pair<PublicKey, String>> getIdentities() throws IOException {
-        if (closed) {
+        if (!isOpen()) {
             throw new SshException("Agent closed");
         }
+
         List<Pair<PublicKey, String>> pks = new ArrayList<Pair<PublicKey, String>>();
         for (Pair<KeyPair, String> kp : keys) {
             pks.add(new Pair<PublicKey, String>(kp.getFirst().getPublic(), kp.getSecond()));
@@ -56,15 +67,17 @@ public class AgentImpl implements SshAgent {
 
     @Override
     public byte[] sign(PublicKey key, byte[] data) throws IOException {
-        if (closed) {
+        if (!isOpen()) {
             throw new SshException("Agent closed");
         }
+
         Pair<KeyPair, String> kp = getKeyPair(keys, key);
         if (kp == null) {
             throw new SshException("Key not found");
         }
+
         try {
-            Signature verif;
+            final Signature verif;
             if (kp.getFirst().getPublic() instanceof DSAPublicKey) {
                 verif = BuiltinSignatures.dsa.create();
             } else if (kp.getFirst().getPublic() instanceof ECPublicKey) {
@@ -87,7 +100,7 @@ public class AgentImpl implements SshAgent {
 
     @Override
     public void addIdentity(KeyPair key, String comment) throws IOException {
-        if (closed) {
+        if (!isOpen()) {
             throw new SshException("Agent closed");
         }
         keys.add(new Pair<KeyPair, String>(key, comment));
@@ -95,7 +108,7 @@ public class AgentImpl implements SshAgent {
 
     @Override
     public void removeIdentity(PublicKey key) throws IOException {
-        if (closed) {
+        if (!isOpen()) {
             throw new SshException("Agent closed");
         }
         Pair<KeyPair, String> kp = getKeyPair(keys, key);
@@ -107,7 +120,7 @@ public class AgentImpl implements SshAgent {
 
     @Override
     public void removeAllIdentities() throws IOException {
-        if (closed) {
+        if (!isOpen()) {
             throw new SshException("Agent closed");
         }
         keys.clear();
@@ -115,8 +128,9 @@ public class AgentImpl implements SshAgent {
 
     @Override
     public void close() throws IOException {
-        closed = true;
-        keys.clear();
+        if (open.getAndSet(false)) {
+            keys.clear();
+        }
     }
 
     protected static SshAgent.Pair<KeyPair, String> getKeyPair(List<SshAgent.Pair<KeyPair, String>> keys, PublicKey key) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentClient.java b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentClient.java
index a8a5271..cd192be 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentClient.java
@@ -22,11 +22,15 @@ import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.util.Queue;
 import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.agent.common.AbstractAgentProxy;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.threads.ThreadUtils;
 import org.apache.tomcat.jni.Local;
 import org.apache.tomcat.jni.Pool;
 import org.apache.tomcat.jni.Socket;
@@ -42,11 +46,20 @@ public class AgentClient extends AbstractAgentProxy implements Runnable {
     private final long handle;
     private final Buffer receiveBuffer;
     private final Queue<Buffer> messages;
-    private boolean closed;
+    private Future<?> pumper;
+    private final AtomicBoolean open = new AtomicBoolean(true);
 
     public AgentClient(String authSocket) throws IOException {
+        this(authSocket, null, false);
+    }
+
+    public AgentClient(String authSocket, ExecutorService executor, boolean shutdownOnExit) throws IOException {
+        this.authSocket = authSocket;
+        
+        setExecutorService((executor == null) ? ThreadUtils.newSingleThreadExecutor("AgentClient[" + authSocket + "]") : executor);
+        setShutdownOnExit((executor == null) ? true : shutdownOnExit);
+
         try {
-            this.authSocket = authSocket;
             pool = Pool.create(AprLibrary.getInstance().getRootPool());
             handle = Local.create(authSocket, pool);
             int result = Local.connect(handle, 0);
@@ -55,7 +68,9 @@ public class AgentClient extends AbstractAgentProxy implements Runnable {
             }
             receiveBuffer = new ByteArrayBuffer();
             messages = new ArrayBlockingQueue<Buffer>(10);
-            new Thread(this).start();
+            
+            ExecutorService service = getExecutorService();
+            pumper = service.submit(this);
         } catch (IOException e) {
             throw e;
         } catch (Exception e) {
@@ -64,10 +79,15 @@ public class AgentClient extends AbstractAgentProxy implements Runnable {
     }
 
     @Override
+    public boolean isOpen() {
+        return open.get();
+    }
+
+    @Override
     public void run() {
         try {
             byte[] buf = new byte[1024];
-            while (!closed) {
+            while (isOpen()) {
                 int result = Socket.recv(handle, buf, 0, buf.length);
                 if (result < Status.APR_SUCCESS) {
                     throwException(result);
@@ -75,14 +95,16 @@ public class AgentClient extends AbstractAgentProxy implements Runnable {
                 messageReceived(new ByteArrayBuffer(buf, 0, result));
             }
         } catch (Exception e) {
-            if (!closed) {
-                e.printStackTrace();
+            if (isOpen()) {
+                log.warn(e.getClass().getSimpleName() + " while still open: " + e.getMessage());
             }
         } finally {
             try {
                 close();
             } catch(IOException e) {
-                e.printStackTrace();
+                if (log.isDebugEnabled()) {
+                    log.debug(e.getClass().getSimpleName() + " while closing: " + e.getMessage());
+                }
             }
         }
     }
@@ -111,10 +133,15 @@ public class AgentClient extends AbstractAgentProxy implements Runnable {
 
     @Override
     public void close() throws IOException {
-        if (!closed) {
-            closed = true;
+        if (open.getAndSet(false)) {
             Socket.close(handle);
         }
+        
+        if ((pumper != null) && isShutdownOnExit() && (!pumper.isDone())) {
+            pumper.cancel(true);
+        }
+
+        super.close();
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServer.java b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServer.java
index 52146da..f176790 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServer.java
@@ -20,13 +20,19 @@ package org.apache.sshd.agent.unix;
 
 import java.io.Closeable;
 import java.io.IOException;
+import java.util.Collection;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.common.AbstractAgentClient;
 import org.apache.sshd.agent.local.AgentImpl;
 import org.apache.sshd.common.util.AbstractLoggingBean;
+import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.threads.ExecutorServiceCarrier;
+import org.apache.sshd.common.util.threads.ThreadUtils;
 import org.apache.tomcat.jni.Local;
 import org.apache.tomcat.jni.Pool;
 import org.apache.tomcat.jni.Socket;
@@ -36,26 +42,44 @@ import org.apache.tomcat.jni.Status;
 /**
  * A server for an SSH Agent
  */
-public class AgentServer extends AbstractLoggingBean implements Closeable {
+public class AgentServer extends AbstractLoggingBean implements Closeable, ExecutorServiceCarrier {
 
     private final SshAgent agent;
+    private final ExecutorService service;
+    private final boolean shutdownExecutor;
+    private Future<?> agentThread;
     private String authSocket;
     private long pool;
     private long handle;
-    private Thread thread;
 
     public AgentServer() {
-        this(new AgentImpl());
+        this(null, false);
     }
 
-    public AgentServer(SshAgent agent) {
+    public AgentServer(ExecutorService executor, boolean shutdownOnExit) {
+        this(new AgentImpl(), executor, shutdownOnExit);
+    }
+
+    public AgentServer(SshAgent agent, ExecutorService executor, boolean shutdownOnExit) {
         this.agent = agent;
+        this.service = (executor == null) ? ThreadUtils.newSingleThreadExecutor("AgentServer[" + agent + "]") : executor;
+        this.shutdownExecutor = (service == executor) ?  shutdownOnExit : true;
     }
 
     public SshAgent getAgent() {
         return agent;
     }
 
+    @Override
+    public ExecutorService getExecutorService() {
+        return service;
+    }
+
+    @Override
+    public boolean isShutdownOnExit() {
+        return shutdownExecutor;
+    }
+
     public String start() throws Exception {
         authSocket = AprLibrary.createLocalSocketAddress();
         pool = Pool.create(AprLibrary.getInstance().getRootPool());
@@ -69,29 +93,56 @@ public class AgentServer extends AbstractLoggingBean implements Closeable {
         if (result != Status.APR_SUCCESS) {
             throwException(result);
         }
-        thread = new Thread() {
-            @SuppressWarnings("synthetic-access")
-            @Override
-            public void run() {
-                try {
-                    while (true) {
-                        long clientSock = Local.accept(handle);
-                        Socket.timeoutSet(clientSock, 10000000);
-                        new SshAgentSession(clientSock, agent);
+        
+        ExecutorService executor = getExecutorService();
+        agentThread = executor.submit(new Runnable() {
+                @SuppressWarnings("synthetic-access")
+                @Override
+                public void run() {
+                    try {
+                        while (true) {
+                            long clientSock = Local.accept(handle);
+                            Socket.timeoutSet(clientSock, 10000000);    // TODO make this configurable
+                            new SshAgentSession(clientSock, agent).run();
+                        }
+                    } catch (Exception e) {
+                        log.error("Failed to run session", e);
                     }
-                } catch (Exception e) {
-                    log.error("Failed to run session", e);
                 }
-            }
-        };
-        thread.start();
+            });
         return authSocket;
     }
 
     @Override
     public void close() throws IOException {
-        agent.close();
+        IOException err = null;
+        try {
+            agent.close();
+        } catch(IOException e) {
+            err = e;
+        }
+
         Socket.close(handle);
+        
+        try {
+            if ((agentThread != null) && (!agentThread.isDone())) {
+                agentThread.cancel(true);
+            }
+        } finally {
+            agentThread = null;
+        }
+        
+        ExecutorService executor = getExecutorService();
+        if ((executor != null) && isShutdownOnExit() && (!executor.isShutdown())) {
+            Collection<?> runners = executor.shutdownNow();
+            if (log.isDebugEnabled()) {
+                log.debug("Shut down runners count=" + GenericUtils.size(runners));
+            }
+        }
+        
+        if (err != null) {
+            throw err;
+        }
     }
 
     protected static class SshAgentSession extends AbstractAgentClient implements Runnable {
@@ -101,7 +152,6 @@ public class AgentServer extends AbstractLoggingBean implements Closeable {
         public SshAgentSession(long socket, SshAgent agent) {
             super(agent);
             this.socket = socket;
-            new Thread(this).start();
         }
 
         @SuppressWarnings("synthetic-access")

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
index aa40241..ab84cee 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
@@ -20,13 +20,21 @@ package org.apache.sshd.agent.unix;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.channels.Channel;
+import java.util.Collection;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.agent.SshAgentServer;
 import org.apache.sshd.client.future.OpenFuture;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.util.AbstractLoggingBean;
+import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.OsUtils;
+import org.apache.sshd.common.util.threads.ExecutorServiceCarrier;
+import org.apache.sshd.common.util.threads.ThreadUtils;
 import org.apache.tomcat.jni.Local;
 import org.apache.tomcat.jni.Pool;
 import org.apache.tomcat.jni.Socket;
@@ -35,19 +43,25 @@ import org.apache.tomcat.jni.Status;
 /**
  * The server side fake agent, acting as an agent, but actually forwarding the requests to the auth channel on the client side.
  */
-public class AgentServerProxy extends AbstractLoggingBean implements SshAgentServer {
+public class AgentServerProxy extends AbstractLoggingBean implements SshAgentServer, ExecutorServiceCarrier, Channel {
     private final ConnectionService service;
     private final String authSocket;
     private final long pool;
     private final long handle;
-    private final Thread thread;
-    private volatile boolean closed;
-    private volatile boolean innerFinished;
+    private Future<?> piper;
+    private final ExecutorService pipeService;
+    private final boolean pipeCloseOnExit;
+    private final AtomicBoolean open = new AtomicBoolean(true);
+    private final AtomicBoolean innerFinished = new AtomicBoolean(false);
 
     //used to wake the Local.listen() JNI call
     private static final byte[] END_OF_STREAM_MESSAGE = new byte[] { "END_OF_STREAM".getBytes()[0] };
 
     public AgentServerProxy(ConnectionService service) throws IOException {
+        this(service, null, false);
+    }
+
+    public AgentServerProxy(ConnectionService service, ExecutorService executor, boolean shutdownOnExit) throws IOException {
         this.service = service;
         try {
             String authSocket = AprLibrary.createLocalSocketAddress();
@@ -66,40 +80,41 @@ public class AgentServerProxy extends AbstractLoggingBean implements SshAgentSer
             if (result != Status.APR_SUCCESS) {
                 throwException(result);
             }
-            thread = new Thread("sshd-AgentServerProxy-PIPE-" + authSocket) {
-                @SuppressWarnings("synthetic-access")
-                @Override
-                public void run() {
-                    try {
-                        while (!closed) {
-                            try {
-                                long clientSock = Local.accept(handle);
-                                if (closed) {
-                                    break;
-                                }
-                                Socket.timeoutSet(clientSock, 10000000);
-                                AgentForwardedChannel channel = new AgentForwardedChannel(clientSock);
-                                AgentServerProxy.this.service.registerChannel(channel);
-                                OpenFuture future = channel.open().await();
-                                Throwable t = future.getException();
-                                if (t instanceof Exception) {
-                                    throw (Exception) t;
-                                } else if (t != null) {
-                                    throw new Exception(t);
-                                }
-                            } catch (Exception e) {
-                                if (!closed) {
-                                    log.info("Exchange caught in authentication forwarding", e);
+            
+            pipeService = (executor == null) ? ThreadUtils.newSingleThreadExecutor("sshd-AgentServerProxy-PIPE-" + authSocket) : executor;
+            pipeCloseOnExit = (executor == pipeService) ? shutdownOnExit : true;
+            piper = pipeService.submit(new Runnable() {
+                    @SuppressWarnings("synthetic-access")
+                    @Override
+                    public void run() {
+                        try {
+                            while (isOpen()) {
+                                try {
+                                    long clientSock = Local.accept(handle);
+                                    if (!isOpen()) {
+                                        break;
+                                    }
+                                    Socket.timeoutSet(clientSock, 10000000);    // TODO allow to configure this
+                                    AgentForwardedChannel channel = new AgentForwardedChannel(clientSock);
+                                    AgentServerProxy.this.service.registerChannel(channel);
+                                    OpenFuture future = channel.open().await();
+                                    Throwable t = future.getException();
+                                    if (t instanceof Exception) {
+                                        throw (Exception) t;
+                                    } else if (t != null) {
+                                        throw new Exception(t);
+                                    }
+                                } catch (Exception e) {
+                                    if (isOpen()) {
+                                        log.info(e.getClass().getSimpleName() + " while authentication forwarding: " + e.getMessage(), e);
+                                    }
                                 }
                             }
+                        } finally {
+                            innerFinished.set(true);
                         }
-                    } finally {
-                        innerFinished = true;
                     }
-                }
-            };
-            thread.setDaemon(true);
-            thread.start();
+                });
         } catch (IOException e) {
             throw e;
         } catch (Exception e) {
@@ -108,25 +123,40 @@ public class AgentServerProxy extends AbstractLoggingBean implements SshAgentSer
     }
 
     @Override
+    public boolean isOpen() {
+        return open.get();
+    }
+
+    @Override
+    public ExecutorService getExecutorService() {
+        return pipeService;
+    }
+
+    @Override
+    public boolean isShutdownOnExit() {
+        return pipeCloseOnExit;
+    }
+
+    @Override
     public String getId() {
         return authSocket;
     }
 
     @Override
     public synchronized void close() throws IOException {
-        if (closed) {
-            return;
+        if (!open.getAndSet(false)) {
+            return; // already closed (or closing)
         }
-        closed = true;
+
         final boolean isDebug = log.isDebugEnabled();
 
         if (handle != 0) {
-            if (!innerFinished) {
+            if (!innerFinished.get()) {
                 try {
 
                     final long tmpPool = Pool.create(AprLibrary.getInstance().getRootPool());
                     final long tmpSocket = Local.create(authSocket, tmpPool);
-                    long connectResult = Local.connect(tmpSocket, 0);
+                    long connectResult = Local.connect(tmpSocket, 0L);
 
                     if (connectResult != Status.APR_SUCCESS) {
                         if (isDebug) {
@@ -157,7 +187,6 @@ public class AgentServerProxy extends AbstractLoggingBean implements SshAgentSer
 
         try {
             if (authSocket != null) {
-
                 final File socketFile = new File(authSocket);
                 if (socketFile.exists()) {
                     if (socketFile.delete()) {
@@ -182,6 +211,22 @@ public class AgentServerProxy extends AbstractLoggingBean implements SshAgentSer
                 log.debug("Exception deleting the PIPE socket: " + authSocket, e);
             }
         }
+        
+        try {
+            if ((piper != null) && (!piper.isDone())) {
+                piper.cancel(true);
+            }
+        } finally {
+            piper = null;
+        }
+        
+        ExecutorService executor = getExecutorService();
+        if ((executor != null) && isShutdownOnExit() && (!executor.isShutdown())) {
+            Collection<?>   runners = executor.shutdownNow();
+            if (log.isDebugEnabled()) {
+                log.debug("Shut down runners count=" + GenericUtils.size(runners));
+            }
+        }
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwarding.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwarding.java b/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwarding.java
index 1913652..5f7cb15 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwarding.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/ChannelAgentForwarding.java
@@ -20,6 +20,9 @@ package org.apache.sshd.agent.unix;
 
 import java.io.IOException;
 import java.io.OutputStream;
+import java.util.Collection;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.client.future.DefaultOpenFuture;
@@ -31,7 +34,10 @@ import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.channel.ChannelOutputStream;
 import org.apache.sshd.common.future.CloseFuture;
 import org.apache.sshd.common.future.SshFutureListener;
+import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.threads.ExecutorServiceCarrier;
+import org.apache.sshd.common.util.threads.ThreadUtils;
 import org.apache.sshd.server.channel.AbstractServerChannel;
 import org.apache.tomcat.jni.Local;
 import org.apache.tomcat.jni.Pool;
@@ -43,7 +49,7 @@ import org.apache.tomcat.jni.Status;
  */
 public class ChannelAgentForwarding extends AbstractServerChannel {
 
-    public static class ChannelAgentForwardingFactory implements NamedFactory<Channel> {
+    public static class ChannelAgentForwardingFactory implements NamedFactory<Channel>, ExecutorServiceCarrier {
         public static final ChannelAgentForwardingFactory INSTANCE = new ChannelAgentForwardingFactory();
         
         public ChannelAgentForwardingFactory() {
@@ -55,19 +61,35 @@ public class ChannelAgentForwarding extends AbstractServerChannel {
             return "auth-agent@openssh.com";
         }
 
+        @Override   // user can override to provide an alternative
+        public ExecutorService getExecutorService() {
+            return null;
+        }
+
+        @Override
+        public boolean isShutdownOnExit() {
+            return false;
+        }
+
         @Override
         public Channel create() {
-            return new ChannelAgentForwarding();
+            ChannelAgentForwarding  channel = new ChannelAgentForwarding();
+            channel.setExecutorService(getExecutorService());
+            channel.setShutdownOnExit(isShutdownOnExit());
+            return channel;
         }
     }
 
     private String authSocket;
     private long pool;
     private long handle;
-    private Thread thread;
     private OutputStream out;
+    private ExecutorService forwardService;
+    private Future<?> forwarder;
+    private boolean shutdownForwarder;
 
     public ChannelAgentForwarding() {
+        super();
     }
 
     @Override
@@ -82,25 +104,28 @@ public class ChannelAgentForwarding extends AbstractServerChannel {
             if (result != Status.APR_SUCCESS) {
                 throwException(result);
             }
-            thread = new Thread() {
-                @SuppressWarnings("synthetic-access")
-                @Override
-                public void run() {
-                    try {
-                        byte[] buf = new byte[1024];
-                        while (true) {
-                            int len = Socket.recv(handle, buf, 0, buf.length);
-                            if (len > 0) {
-                                out.write(buf, 0, len);
-                                out.flush();
+            
+            ExecutorService service = getExecutorService();
+            forwardService = (service == null) ? ThreadUtils.newSingleThreadExecutor("ChannelAgentForwarding[" + authSocket + "]") : service;
+            shutdownForwarder = (service == forwardService) ? isShutdownOnExit() : true;
+            forwarder = forwardService.submit(new Runnable() {
+                    @SuppressWarnings("synthetic-access")
+                    @Override
+                    public void run() {
+                        try {
+                            byte[] buf = new byte[1024];
+                            while (true) {
+                                int len = Socket.recv(handle, buf, 0, buf.length);
+                                if (len > 0) {
+                                    out.write(buf, 0, len);
+                                    out.flush();
+                                }
                             }
+                        } catch (IOException e) {
+                            close(true);
                         }
-                    } catch (IOException e) {
-                        close(true);
                     }
-                }
-            };
-            thread.start();
+                });
             f.setOpened();
 
         } catch (Exception e) {
@@ -118,8 +143,27 @@ public class ChannelAgentForwarding extends AbstractServerChannel {
         super.close(true);
 
         // We also need to close the socket.
-        //
         Socket.close(handle);
+        
+        try {
+            if ((forwarder != null) && (!forwarder.isDone())) {
+                forwarder.cancel(true);
+            }
+        } finally {
+            forwarder = null;
+        }
+        
+        try {
+            if  ((forwardService != null) && shutdownForwarder) {
+                Collection<?> runners = forwardService.shutdownNow();
+                if (log.isDebugEnabled()) {
+                    log.debug("Shut down runners count=" + GenericUtils.size(runners));
+                }
+            }
+        } finally {
+            forwardService = null;
+            shutdownForwarder = false;
+        }
     }
 
     @Override
@@ -157,9 +201,7 @@ public class ChannelAgentForwarding extends AbstractServerChannel {
      * @param code APR error code
      * @throws java.io.IOException the produced exception for the given APR error number
      */
-    private void throwException(int code) throws IOException {
-        throw new IOException(
-                org.apache.tomcat.jni.Error.strerror(-code) +
-                " (code: " + code + ")");
+    private static void throwException(int code) throws IOException {
+        throw new IOException(org.apache.tomcat.jni.Error.strerror(-code) + " (code: " + code + ")");
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java b/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java
index 17e8160..61d5a28 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/UnixAgentFactory.java
@@ -19,6 +19,7 @@
 package org.apache.sshd.agent.unix;
 
 import java.io.IOException;
+import java.util.concurrent.ExecutorService;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentFactory;
@@ -31,13 +32,57 @@ import org.apache.sshd.common.Session;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.threads.ExecutorServiceConfigurer;
 import org.apache.sshd.server.session.ServerSession;
 
-public class UnixAgentFactory implements SshAgentFactory {
+public class UnixAgentFactory implements SshAgentFactory, ExecutorServiceConfigurer {
+    private ExecutorService executor;
+    private boolean shutdownExecutor;
+    private final NamedFactory<Channel> factory = new ChannelAgentForwarding.ChannelAgentForwardingFactory() {
+        @Override
+        public ExecutorService getExecutorService() {
+            return UnixAgentFactory.this.getExecutorService();
+        }
+
+        @Override
+        public boolean isShutdownOnExit() {
+            return UnixAgentFactory.this.isShutdownOnExit();
+        }
+        
+    };
+
+    public UnixAgentFactory() {
+        super();
+    }
+
+    public UnixAgentFactory(ExecutorService service, boolean shutdown) {
+        executor = service;
+        shutdownExecutor = shutdown;
+    }
+
+    @Override
+    public ExecutorService getExecutorService() {
+        return executor;
+    }
+
+    @Override
+    public void setExecutorService(ExecutorService service) {
+        executor = service;
+    }
+
+    @Override
+    public boolean isShutdownOnExit() {
+        return shutdownExecutor;
+    }
+
+    @Override
+    public void setShutdownOnExit(boolean shutdown) {
+        shutdownExecutor = shutdown;
+    }
 
     @Override
     public NamedFactory<Channel> getChannelForwardingFactory() {
-        return ChannelAgentForwarding.ChannelAgentForwardingFactory.INSTANCE;
+        return factory;
     }
 
     @Override
@@ -46,7 +91,8 @@ public class UnixAgentFactory implements SshAgentFactory {
         if (GenericUtils.isEmpty(authSocket)) {
             throw new SshException("No " + SshAgent.SSH_AUTHSOCKET_ENV_NAME + " value");
         }
-        return new AgentClient(authSocket);
+
+        return new AgentClient(authSocket, getExecutorService(), isShutdownOnExit());
     }
 
     @Override
@@ -55,6 +101,6 @@ public class UnixAgentFactory implements SshAgentFactory {
         if (!(session instanceof ServerSession)) {
             throw new IllegalStateException("The session used to create an agent server proxy must be a server session");
         }
-        return new AgentServerProxy(service);
+        return new AgentServerProxy(service, getExecutorService(), isShutdownOnExit());
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java
index 1f434b0..e690667 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/AbstractClientChannel.java
@@ -212,8 +212,7 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
                 }
                 try {
                     if (log.isTraceEnabled()) {
-                        log.trace("Waiting for lock on channel {}, mask={}, cond={}",
-                                  new Object[] { this, Integer.valueOf(mask), Integer.valueOf(cond) });
+                        log.trace("Waiting for lock on channel {}, mask={}, cond={}", this, Integer.valueOf(mask), Integer.valueOf(cond));
                     }
                     if (timeout > 0) {
                         lock.wait(timeout);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java
index 91d6153..102e85f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSession.java
@@ -20,14 +20,17 @@ package org.apache.sshd.client.channel;
 
 import java.io.IOException;
 import java.io.InputStream;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
 
 import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.channel.ChannelAsyncInputStream;
+import org.apache.sshd.common.channel.ChannelAsyncOutputStream;
 import org.apache.sshd.common.channel.ChannelOutputStream;
 import org.apache.sshd.common.channel.ChannelPipedInputStream;
 import org.apache.sshd.common.channel.ChannelPipedOutputStream;
-import org.apache.sshd.common.channel.ChannelAsyncInputStream;
-import org.apache.sshd.common.channel.ChannelAsyncOutputStream;
 import org.apache.sshd.common.future.CloseFuture;
+import org.apache.sshd.common.util.threads.ThreadUtils;
 
 /**
  * TODO Add javadoc
@@ -35,8 +38,9 @@ import org.apache.sshd.common.future.CloseFuture;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class ChannelSession extends AbstractClientChannel {
-
-    private Thread streamPumper;
+    private ExecutorService pumperService;
+    private Future<?> pumper;
+    private boolean shutdownPumper;
 
     public ChannelSession() {
         super("session");
@@ -73,28 +77,50 @@ public class ChannelSession extends AbstractClientChannel {
                 err = pos;
                 invertedErr = pis;
             }
+
             if (in != null) {
-                streamPumper = new Thread("ClientInputStreamPump") {
-                    @Override
-                    public void run() {
-                        pumpInputStream();
-                    }
-                };
+                // allocate a temporary executor service if none provided
+                ExecutorService service = getExecutorService();
+                if ((pumperService = service) == null) {
+                    pumperService = ThreadUtils.newSingleThreadExecutor("ClientInputStreamPump[" + this.toString() + "]");
+                }
+                
+                // shutdown the temporary executor service if had to create it
+                shutdownPumper = (pumperService == service) ? isShutdownOnExit() : true;
+
                 // Interrupt does not really work and the thread will only exit when
                 // the call to read() will return.  So ensure this thread is a daemon
                 // to avoid blocking the whole app
-                streamPumper.setDaemon(true);
-                streamPumper.start();
+                pumper = pumperService.submit(new Runnable() {
+                        @Override
+                        public void run() {
+                            pumpInputStream();
+                        }
+                    });
             }
         }
     }
 
     @Override
     protected void doCloseImmediately() {
-        if (streamPumper != null) {
-            streamPumper.interrupt();
-            streamPumper = null;
+        if ((pumper != null) && (pumperService != null) && shutdownPumper && (!pumperService.isShutdown())) {
+            try {
+                if (!pumper.isDone()) {
+                    pumper.cancel(true);
+                }
+                
+                pumperService.shutdownNow();
+            } catch(Exception e) {
+                // we log it as DEBUG since it is relatively harmless
+                if (log.isDebugEnabled()) {
+                    log.debug("Failed (" + e.getClass().getSimpleName() + ") to shutdown stream pumper: " + e.getMessage());
+                }
+            } finally {
+                pumper = null;
+                pumperService = null;
+            }
         }
+
         super.doCloseImmediately();
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java
index 9250847..73b132a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelSubsystem.java
@@ -23,6 +23,8 @@ import java.io.IOException;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.future.CloseFuture;
 import org.apache.sshd.common.future.SshFutureListener;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
@@ -35,10 +37,7 @@ public class ChannelSubsystem extends ChannelSession {
     private final String subsystem;
 
     public ChannelSubsystem(String subsystem) {
-        if (subsystem == null) {
-            throw new IllegalArgumentException("subsystem must not be null");
-        }
-        this.subsystem = subsystem;
+        this.subsystem = ValidateUtils.checkNotNullAndNotEmpty(subsystem, "Subsystem may not be null/empty", GenericUtils.EMPTY_OBJECT_ARRAY);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
index 6387cac..6abe007 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
@@ -20,7 +20,9 @@ package org.apache.sshd.common.channel;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
@@ -37,16 +39,20 @@ import org.apache.sshd.common.future.SshFutureListener;
 import org.apache.sshd.common.io.IoWriteFuture;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.util.CloseableUtils;
+import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.BufferUtils;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.threads.ExecutorServiceConfigurer;
 
 /**
  * TODO Add javadoc
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public abstract class AbstractChannel extends CloseableUtils.AbstractInnerCloseable implements Channel {
+public abstract class AbstractChannel
+                extends CloseableUtils.AbstractInnerCloseable
+                implements Channel, ExecutorServiceConfigurer {
 
     public static final int DEFAULT_WINDOW_SIZE = 0x200000;
     public static final int DEFAULT_PACKET_SIZE = 0x8000;
@@ -57,6 +63,8 @@ public abstract class AbstractChannel extends CloseableUtils.AbstractInnerClosea
         Opened, CloseSent, CloseReceived, Closed
     }
 
+    private ExecutorService executor;
+    private boolean shutdownExecutor;
     protected final Window localWindow = new Window(this, null, getClass().getName().contains(".client."), true);
     protected final Window remoteWindow = new Window(this, null, getClass().getName().contains(".client."), false);
     protected ConnectionService service;
@@ -106,6 +114,26 @@ public abstract class AbstractChannel extends CloseableUtils.AbstractInnerClosea
     }
 
     @Override
+    public ExecutorService getExecutorService() {
+        return executor;
+    }
+
+    @Override
+    public void setExecutorService(ExecutorService service) {
+        executor = service;
+    }
+
+    @Override
+    public boolean isShutdownOnExit() {
+        return shutdownExecutor;
+    }
+
+    @Override
+    public void setShutdownOnExit(boolean shutdown) {
+        shutdownExecutor = shutdown;
+    }
+
+    @Override
     public void handleRequest(Buffer buffer) throws IOException {
         String req = buffer.getString();
         boolean wantReply = buffer.getBoolean();
@@ -189,10 +217,12 @@ public abstract class AbstractChannel extends CloseableUtils.AbstractInnerClosea
         public boolean isClosing() {
             return closing;
         }
+
         @Override
         public boolean isClosed() {
             return gracefulFuture.isClosed();
         }
+
         @Override
         public CloseFuture close(boolean immediately) {
             closing = true;
@@ -226,6 +256,15 @@ public abstract class AbstractChannel extends CloseableUtils.AbstractInnerClosea
                     AbstractChannel.this.close(true);
                 }
             }
+            
+            ExecutorService service = getExecutorService();
+            if ((service != null) && isShutdownOnExit() && (!service.isShutdown())) {
+                Collection<?>   running = service.shutdownNow();
+                if (log.isDebugEnabled()) {
+                    log.debug("Shutdown executor service on close - running count=" + GenericUtils.size(running));
+                }
+            }
+
             return gracefulFuture;
         }
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java
index 21e60df..255bfe3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java
@@ -21,6 +21,8 @@ package org.apache.sshd.common.forward;
 import java.io.IOException;
 import java.io.OutputStream;
 import java.net.ConnectException;
+import java.util.Collection;
+import java.util.concurrent.ExecutorService;
 
 import org.apache.sshd.client.future.DefaultOpenFuture;
 import org.apache.sshd.client.future.OpenFuture;
@@ -40,6 +42,8 @@ import org.apache.sshd.common.io.IoWriteFuture;
 import org.apache.sshd.common.util.Readable;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.threads.ExecutorServiceCarrier;
+import org.apache.sshd.common.util.threads.ThreadUtils;
 import org.apache.sshd.server.channel.AbstractServerChannel;
 import org.apache.sshd.server.channel.OpenChannelException;
 
@@ -49,7 +53,7 @@ import org.apache.sshd.server.channel.OpenChannelException;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class TcpipServerChannel extends AbstractServerChannel {
-    public abstract static class TcpipFactory implements NamedFactory<Channel> {
+    public abstract static class TcpipFactory implements NamedFactory<Channel>, ExecutorServiceCarrier {
         private final Type type;
 
         protected TcpipFactory(Type type) {
@@ -60,9 +64,22 @@ public class TcpipServerChannel extends AbstractServerChannel {
             return type;
         }
         
+        @Override   // user can override to provide an alternative
+        public ExecutorService getExecutorService() {
+            return null;
+        }
+
+        @Override
+        public boolean isShutdownOnExit() {
+            return false;
+        }
+
         @Override
         public Channel create() {
-            return new TcpipServerChannel(getType());
+            TcpipServerChannel  channel = new TcpipServerChannel(getType());
+            channel.setExecutorService(getExecutorService());
+            channel.setShutdownOnExit(isShutdownOnExit());
+            return channel;
         }
     }
 
@@ -132,7 +149,7 @@ public class TcpipServerChannel extends AbstractServerChannel {
         }
 
         final ForwardingFilter filter = getSession().getFactoryManager().getTcpipForwardingFilter();
-        if (address == null || filter == null || !filter.canConnect(address, getSession())) {
+        if ((address == null) || (filter == null) || (!filter.canConnect(address, getSession()))) {
             super.close(true);
             f.setException(new OpenChannelException(SshConstants.SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, "Connection denied"));
             return f;
@@ -205,16 +222,33 @@ public class TcpipServerChannel extends AbstractServerChannel {
         // We also need to dispose of the connector, but unfortunately we
         // are being invoked by the connector thread or the connector's
         // own processor thread.  Disposing of the connector within either
-        // causes deadlock.  Instead create a new thread to dispose of the
+        // causes deadlock.  Instead create a thread to dispose of the
         // connector in the background.
-        //
-        new Thread("TcpIpServerChannel-ConnectorCleanup") {
-            @SuppressWarnings("synthetic-access")
-            @Override
-            public void run() {
-                connector.close(true);
-            }
-        }.start();
+
+        ExecutorService service = getExecutorService();
+        // allocate a temporary executor service if none provided
+        final ExecutorService executors = (service == null)
+                                        ? ThreadUtils.newSingleThreadExecutor("TcpIpServerChannel-ConnectorCleanup[" + getSession() + "]")
+                                        : service
+                                        ;
+        // shutdown the temporary executor service if had to create it
+        final boolean shutdown = (executors == service) ? isShutdownOnExit() : true;
+        executors.submit(new Runnable() {
+                @SuppressWarnings("synthetic-access")
+                @Override
+                public void run() {
+                    try {
+                        connector.close(true);
+                    } finally {
+                        if ((executors != null) && (!executors.isShutdown()) && shutdown) {
+                            Collection<Runnable> runners = executors.shutdownNow();
+                            if (log.isDebugEnabled()) {
+                                log.debug("destroy() - shutdown executor service - runners count=" + ((runners == null) ? 0 : runners.size()));
+                            }
+                        }
+                    }
+                }
+            });
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
index cffa5c2..5b79870 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/threads/ThreadUtils.java
@@ -90,22 +90,23 @@ public class ThreadUtils {
     /**
      * Attempts to find the most suitable {@link ClassLoader} as follows:</BR>
      * <UL>
-     * <LI>
-     * Check the {@link Thread#getContextClassLoader()} value
-     * </LI>
-     * <p/>
-     * <LI>
-     * If no thread context class loader then check the anchor
-     * class (if given) for its class loader
-     * </LI>
-     * <p/>
-     * <LI>
-     * If still no loader available, then use {@link ClassLoader#getSystemClassLoader()}
-     * </LI>
+     *      <LI>
+     *      Check the {@link Thread#getContextClassLoader()} value
+     *      </LI>
+     *      
+     *      <LI>
+     *      If no thread context class loader then check the anchor
+     *      class (if given) for its class loader
+     *      </LI>
+     *      
+     *      <LI>
+     *      If still no loader available, then use {@link ClassLoader#getSystemClassLoader()}
+     *      </LI>
      * </UL>
-     *
-     * @param anchor
-     * @return
+     * @param anchor The anchor {@link Class} to use if no current thread
+     * - ignored if {@code null}
+     * context class loader
+     * @return The resolver {@link ClassLoader}
      */
     public static ClassLoader resolveDefaultClassLoader(Class<?> anchor) {
         Thread thread = Thread.currentThread();
@@ -125,38 +126,27 @@ public class ThreadUtils {
         return cl;
     }
 
-    public static ExecutorService newFixedThreadPool(
-            String poolName,
-            int nThreads
-    ) {
+    public static ExecutorService newFixedThreadPool(String poolName, int nThreads) {
         return new ThreadPoolExecutor(nThreads, nThreads,
-                0L, TimeUnit.MILLISECONDS,
-                new LinkedBlockingQueue<Runnable>(),
-                new SshdThreadFactory(poolName),
-                new ThreadPoolExecutor.CallerRunsPolicy());
+                                      0L, TimeUnit.MILLISECONDS,
+                                      new LinkedBlockingQueue<Runnable>(),
+                                      new SshdThreadFactory(poolName),
+                                      new ThreadPoolExecutor.CallerRunsPolicy());
     }
 
-    public static ExecutorService newCachedThreadPool(
-            String poolName
-    ) {
+    public static ExecutorService newCachedThreadPool(String poolName) {
         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
-                60L, TimeUnit.SECONDS,
-                new SynchronousQueue<Runnable>(),
-                new SshdThreadFactory(poolName),
-                new ThreadPoolExecutor.CallerRunsPolicy());
+                                      60L, TimeUnit.SECONDS,
+                                      new SynchronousQueue<Runnable>(),
+                                      new SshdThreadFactory(poolName),
+                                      new ThreadPoolExecutor.CallerRunsPolicy());
     }
 
-    public static ScheduledExecutorService newSingleThreadScheduledExecutor(
-            String poolName
-    ) {
-        return new ScheduledThreadPoolExecutor(
-                1,
-                new SshdThreadFactory(poolName));
+    public static ScheduledExecutorService newSingleThreadScheduledExecutor(String poolName) {
+        return new ScheduledThreadPoolExecutor(1, new SshdThreadFactory(poolName));
     }
 
-    public static ExecutorService newSingleThreadExecutor(
-            String poolName
-    ) {
+    public static ExecutorService newSingleThreadExecutor(String poolName) {
         return newFixedThreadPool(poolName, 1);
     }
 
@@ -168,18 +158,21 @@ public class ThreadUtils {
 
         public SshdThreadFactory(String name) {
             SecurityManager s = System.getSecurityManager();
-            group = (s != null) ? s.getThreadGroup() :
-                    Thread.currentThread().getThreadGroup();
-            namePrefix = "sshd-" + name + "-thread-";
+            ThreadGroup parentGroup = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
+            String effectiveName = name.replace(' ', '-');
+            group = new ThreadGroup(parentGroup, "sshd-" + effectiveName + "-group");
+            namePrefix = "sshd-" + effectiveName + "-thread-";
         }
 
         @Override
         public Thread newThread(Runnable r) {
             Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
-            if (t.isDaemon())
-                t.setDaemon(false);
-            if (t.getPriority() != Thread.NORM_PRIORITY)
+            if (!t.isDaemon()) {
+                t.setDaemon(true);
+            }
+            if (t.getPriority() != Thread.NORM_PRIORITY) {
                 t.setPriority(Thread.NORM_PRIORITY);
+            }
             return t;
         }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java b/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java
index 2cd4638..baf6ca2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java
@@ -194,7 +194,7 @@ public class ScpCommand extends AbstractLoggingBean implements Command, Runnable
 
         pendingFuture = null;
 
-        if ((executors != null) && shutdownExecutor) {
+        if ((executors != null) && (!executors.isShutdown()) && shutdownExecutor) {
             Collection<Runnable> runners = executors.shutdownNow();
             if (log.isDebugEnabled()) {
                 log.debug("destroy() - shutdown executor service - runners count=" + ((runners == null) ? 0 : runners.size()));

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
index b57705d..ecc8d29 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/sftp/SftpSubsystem.java
@@ -2139,7 +2139,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
 
             pendingFuture = null;
 
-            if ((executors != null) && shutdownExecutor) {
+            if ((executors != null) && (!executors.isShutdown()) && shutdownExecutor) {
                 Collection<Runnable> runners = executors.shutdownNow();
                 if (log.isDebugEnabled()) {
                     log.debug("destroy() - shutdown executor service - runners count=" + ((runners == null) ? 0 : runners.size()));

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-core/src/test/java/org/apache/sshd/AgentTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/AgentTest.java b/sshd-core/src/test/java/org/apache/sshd/AgentTest.java
index d21828e..d7e4fbc 100644
--- a/sshd-core/src/test/java/org/apache/sshd/AgentTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/AgentTest.java
@@ -19,8 +19,6 @@
 package org.apache.sshd;
 
 import static org.apache.sshd.util.Utils.createTestKeyPairProvider;
-import static org.hamcrest.CoreMatchers.notNullValue;
-import static org.junit.Assume.assumeThat;
 
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
@@ -49,11 +47,14 @@ import org.junit.Assume;
 import org.junit.Test;
 
 public class AgentTest extends BaseTestSupport {
+    public AgentTest() {
+        super();
+    }
 
     @Test
-    public void testAgent() throws Exception {
+    public void testAgentServer() throws Exception {
         // TODO: revisit this test to work without BC
-        Assume.assumeTrue("BoncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
+        Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
 
         try(AgentServer agent = new AgentServer()) {
             String authSocket;
@@ -63,23 +64,23 @@ public class AgentTest extends BaseTestSupport {
                 // the native library is not available, so these tests should be skipped
                 authSocket = null;
             }
-            assumeThat(authSocket, notNullValue());
+            Assume.assumeTrue("Native library N/A", authSocket != null);
     
             try(SshAgent client = new AgentClient(authSocket)) {
                 List<SshAgent.Pair<PublicKey, String>> keys = client.getIdentities();
-                assertNotNull(keys);
-                assertEquals(0, keys.size());
+                assertNotNull("No initial identities", keys);
+                assertEquals("Unexpected initial identities size", 0, keys.size());
         
                 KeyPair k = Utils.createTestHostKeyProvider().loadKey(KeyPairProvider.SSH_RSA);
                 client.addIdentity(k, "");
                 keys = client.getIdentities();
-                assertNotNull(keys);
-                assertEquals(1, keys.size());
+                assertNotNull("No registered identities after add", keys);
+                assertEquals("Mismatched registered keys size", 1, keys.size());
         
                 client.removeIdentity(k.getPublic());
                 keys = client.getIdentities();
-                assertNotNull(keys);
-                assertEquals(0, keys.size());
+                assertNotNull("No registered identities after remove", keys);
+                assertEquals("Registered keys size not empty", 0, keys.size());
         
                 client.removeAllIdentities();
             }    
@@ -89,14 +90,14 @@ public class AgentTest extends BaseTestSupport {
     @Test
     public void testAgentForwarding() throws Exception {
         // TODO: revisit this test to work without BC
-        Assume.assumeTrue("BoncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
+        Assume.assumeTrue("BouncyCastle not registered", SecurityUtils.isBouncyCastleRegistered());
 
         TestEchoShellFactory shellFactory = new TestEchoShellFactory();
         ProxyAgentFactory agentFactory = new ProxyAgentFactory();
         LocalAgentFactory localAgentFactory = new LocalAgentFactory();
-
+        String username = getCurrentTestName();
         KeyPair pair = createTestKeyPairProvider("dsaprivkey.pem").loadKey(KeyPairProvider.SSH_DSS);
-        localAgentFactory.getAgent().addIdentity(pair, "smx");
+        localAgentFactory.getAgent().addIdentity(pair, username);
 
         try(SshServer sshd1 = SshServer.setUpDefaultServer()) {
             sshd1.setKeyPairProvider(Utils.createTestHostKeyProvider());
@@ -120,8 +121,8 @@ public class AgentTest extends BaseTestSupport {
                     client1.setAgentFactory(localAgentFactory);
                     client1.start();
                     
-                    try(ClientSession session1 = client1.connect("smx", "localhost", port1).await().getSession()) {
-                        session1.auth().verify(5L, TimeUnit.SECONDS);
+                    try(ClientSession session1 = client1.connect(username, "localhost", port1).await().getSession()) {
+                        session1.auth().verify(10L, TimeUnit.SECONDS);
 
                         try(ChannelShell channel1 = session1.createShellChannel();
                             ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -145,7 +146,7 @@ public class AgentTest extends BaseTestSupport {
                                     client2.getProperties().putAll(shellFactory.shell.getEnvironment().getEnv());
                                     client2.start();
                                     
-                                    try(ClientSession session2 = client2.connect("smx", "localhost", port2).await().getSession()) {
+                                    try(ClientSession session2 = client2.connect(username, "localhost", port2).await().getSession()) {
                                         session2.auth().verify(5L, TimeUnit.SECONDS);
 
                                         try(ChannelShell channel2 = session2.createShellChannel()) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommand.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommand.java b/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommand.java
index d8b4c80..6f09d34 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommand.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommand.java
@@ -54,10 +54,12 @@ public class GitPackCommand implements Command, Runnable {
         this.command = command;
     }
 
+    @Override
     public void setInputStream(InputStream in) {
         this.in = in;
     }
 
+    @Override
     public void setOutputStream(OutputStream out) {
         this.out = out;
         if (out instanceof ChannelOutputStream) {
@@ -65,6 +67,7 @@ public class GitPackCommand implements Command, Runnable {
         }
     }
 
+    @Override
     public void setErrorStream(OutputStream err) {
         this.err = err;
         if (err instanceof ChannelOutputStream) {
@@ -72,14 +75,19 @@ public class GitPackCommand implements Command, Runnable {
         }
     }
 
+    @Override
     public void setExitCallback(ExitCallback callback) {
         this.callback = callback;
     }
 
+    @Override
     public void start(Environment env) throws IOException {
-        new Thread(this).start();
+        Thread  thread=new Thread(this);
+        thread.setDaemon(true);
+        thread.start();
     }
 
+    @Override
     public void run() {
         try {
             List<String> strs = parseDelimitedString(command, " ", true);
@@ -114,6 +122,7 @@ public class GitPackCommand implements Command, Runnable {
         }
     }
 
+    @Override
     public void destroy() {
         //To change body of implemented methods use File | Settings | File Templates.
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/009d832d/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommand.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommand.java b/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommand.java
index 22a2f11..210a7cf 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommand.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommand.java
@@ -48,10 +48,12 @@ public class GitPgmCommand implements Command, Runnable {
         this.command = command;
     }
 
+    @Override
     public void setInputStream(InputStream in) {
         this.in = in;
     }
 
+    @Override
     public void setOutputStream(OutputStream out) {
         this.out = out;
         if (out instanceof ChannelOutputStream) {
@@ -59,6 +61,7 @@ public class GitPgmCommand implements Command, Runnable {
         }
     }
 
+    @Override
     public void setErrorStream(OutputStream err) {
         this.err = err;
         if (err instanceof ChannelOutputStream) {
@@ -66,14 +69,19 @@ public class GitPgmCommand implements Command, Runnable {
         }
     }
 
+    @Override
     public void setExitCallback(ExitCallback callback) {
         this.callback = callback;
     }
 
+    @Override
     public void start(Environment env) throws IOException {
-        new Thread(this).start();
+        Thread  thread=new Thread(this);
+        thread.setDaemon(true);
+        thread.start();
     }
 
+    @Override
     public void run() {
         try {
             List<String> strs = parseDelimitedString(command, " ", true);
@@ -104,6 +112,7 @@ public class GitPgmCommand implements Command, Runnable {
         }
     }
 
+    @Override
     public void destroy() {
         //To change body of implemented methods use File | Settings | File Templates.
     }


[2/4] mina-sshd git commit: [SSHD-481] Avoid (re-)creation of bogus test class instances

Posted by lg...@apache.org.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
new file mode 100644
index 0000000..fedc1ed
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
@@ -0,0 +1,982 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sshd.client.scp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.channels.FileChannel;
+import java.nio.file.FileSystem;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.nio.file.attribute.PosixFilePermission;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Properties;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.SshClient;
+import org.apache.sshd.SshServer;
+import org.apache.sshd.client.scp.ScpClient;
+import org.apache.sshd.common.Session;
+import org.apache.sshd.common.file.FileSystemFactory;
+import org.apache.sshd.common.file.root.RootedFileSystemProvider;
+import org.apache.sshd.common.scp.ScpHelper;
+import org.apache.sshd.common.scp.ScpTransferEventListener;
+import org.apache.sshd.common.util.OsUtils;
+import org.apache.sshd.server.command.ScpCommandFactory;
+import org.apache.sshd.util.BaseTestSupport;
+import org.apache.sshd.util.BogusPasswordAuthenticator;
+import org.apache.sshd.util.EchoShellFactory;
+import org.apache.sshd.util.JSchLogger;
+import org.apache.sshd.util.SimpleUserInfo;
+import org.apache.sshd.util.Utils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import ch.ethz.ssh2.Connection;
+import ch.ethz.ssh2.SCPClient;
+
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+
+/**
+ * Test for SCP support.
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class ScpTest extends BaseTestSupport {
+
+    private SshServer sshd;
+    private int port;
+    private com.jcraft.jsch.Session session;
+    private final FileSystemFactory fileSystemFactory;
+
+    public ScpTest() throws IOException {
+        Path targetPath = detectTargetFolder().toPath();
+        Path parentPath = targetPath.getParent();
+        final FileSystem fileSystem = new RootedFileSystemProvider().newFileSystem(parentPath, Collections.<String,Object>emptyMap());
+        fileSystemFactory = new FileSystemFactory() {
+            @Override
+            public FileSystem createFileSystem(Session session) throws IOException {
+                return fileSystem;
+            }
+        };
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        sshd = SshServer.setUpDefaultServer();
+        sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
+        sshd.setCommandFactory(new ScpCommandFactory());
+        sshd.setShellFactory(new EchoShellFactory());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
+        sshd.setFileSystemFactory(fileSystemFactory);
+        sshd.start();
+        port = sshd.getPort();
+    }
+
+    protected com.jcraft.jsch.Session getJschSession() throws JSchException {
+        JSchLogger.init();
+        JSch sch = new JSch();
+        session = sch.getSession("sshd", "localhost", port);
+        session.setUserInfo(new SimpleUserInfo("sshd"));
+        session.connect();
+        return session;
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (session != null) {
+            session.disconnect();
+        }
+        
+        if (sshd != null) {
+            sshd.stop(true);
+        }
+    }
+
+    @Test
+    @Ignore
+    public void testExternal() throws Exception {
+        System.out.println("Scp available on port " + port);
+        Thread.sleep(5 * 60000);
+    }
+
+    @Test
+    public void testUploadAbsoluteDriveLetter() throws Exception {
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            client.start();
+
+            try {
+                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                    session.addPasswordIdentity(getCurrentTestName());
+                    session.auth().verify(5L, TimeUnit.SECONDS);
+
+                    ScpClient scp = createScpClient(session);
+                    Path targetPath = detectTargetFolder().toPath();
+                    Path parentPath = targetPath.getParent();
+                    Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+                    Utils.deleteRecursive(scpRoot);
+
+                    Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+                    Path localFile = localDir.resolve(getCurrentTestName() + "-1.txt");
+                    byte[] data = writeFile(localFile, (getCurrentTestName() + "\n"));
+
+                    Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+                    Path remoteFile = remoteDir.resolve(localFile.getFileName().toString());
+                    String localPath = localFile.toString();
+                    String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
+                    scp.upload(localPath, remotePath);
+                    assertFileLength(remoteFile, data.length, 5000);
+
+                    Path secondRemote = remoteDir.resolve(getCurrentTestName() + "-2.txt");
+                    String secondPath = Utils.resolveRelativeRemotePath(parentPath, secondRemote);
+                    scp.upload(localPath, secondPath);
+                    assertFileLength(secondRemote, data.length, 5000);
+                    
+                    Path pathRemote = remoteDir.resolve(getCurrentTestName() + "-path.txt");
+                    String pathPath = Utils.resolveRelativeRemotePath(parentPath, pathRemote);
+                    scp.upload(localFile, pathPath);
+                    assertFileLength(pathRemote, data.length, 5000);
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testScpUploadOverwrite() throws Exception {
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            client.start();
+
+            try {
+                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                    session.addPasswordIdentity(getCurrentTestName());
+                    session.auth().verify(5L, TimeUnit.SECONDS);
+
+                    ScpClient scp = createScpClient(session);
+                    String data = getCurrentTestName() + "\n";
+
+                    Path targetPath = detectTargetFolder().toPath();
+                    Path parentPath = targetPath.getParent();
+                    Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+                    Utils.deleteRecursive(scpRoot);
+
+                    Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+                    Path localFile = localDir.resolve(getCurrentTestName() + ".txt");
+                    writeFile(localFile, data);
+
+                    Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+                    Path remoteFile = remoteDir.resolve(localFile.getFileName());
+                    writeFile(remoteFile, data + data);
+
+                    String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
+                    scp.upload(localFile.toString(), remotePath);
+                    assertFileLength(remoteFile, data.length(), 5000);
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testScpUploadZeroLengthFile() throws Exception {
+        Path targetPath = detectTargetFolder().toPath();
+        Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+        Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+        Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+        Path zeroLocal = localDir.resolve(getCurrentTestName());
+
+        try (FileChannel fch = FileChannel.open(zeroLocal, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
+            if (fch.size() > 0L) {
+                fch.truncate(0L);
+            }
+        }
+        assertEquals("Non-zero size for local file=" + zeroLocal, 0L, Files.size(zeroLocal));
+
+        Path zeroRemote = remoteDir.resolve(zeroLocal.getFileName());
+        if (Files.exists(zeroRemote)) {
+            Files.delete(zeroRemote);
+        }
+
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            try {
+                client.start();
+
+                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                    session.addPasswordIdentity(getCurrentTestName());
+                    session.auth().verify(5L, TimeUnit.SECONDS);
+
+                    ScpClient scp = createScpClient(session);
+                    String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), zeroRemote);
+                    scp.upload(zeroLocal.toString(), remotePath);
+                    assertFileLength(zeroRemote, 0L, TimeUnit.SECONDS.toMillis(5L));
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testScpDownloadZeroLengthFile() throws Exception {
+        Path targetPath = detectTargetFolder().toPath();
+        Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+        Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+        Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+        Path zeroLocal = localDir.resolve(getCurrentTestName());
+        if (Files.exists(zeroLocal)) {
+            Files.delete(zeroLocal);
+        }
+
+        Path zeroRemote = remoteDir.resolve(zeroLocal.getFileName());
+        try (FileChannel fch = FileChannel.open(zeroRemote, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
+            if (fch.size() > 0L) {
+                fch.truncate(0L);
+            }
+        }
+        assertEquals("Non-zero size for remote file=" + zeroRemote, 0L, Files.size(zeroRemote));
+
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            try {
+                client.start();
+
+                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                    session.addPasswordIdentity(getCurrentTestName());
+                    session.auth().verify(5L, TimeUnit.SECONDS);
+
+                    ScpClient scp = createScpClient(session);
+                    String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), zeroRemote);
+                    scp.download(remotePath, zeroLocal.toString());
+                    assertFileLength(zeroLocal, 0L, TimeUnit.SECONDS.toMillis(5L));
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testScpNativeOnSingleFile() throws Exception {
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            client.start();
+
+            try {
+                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                    session.addPasswordIdentity(getCurrentTestName());
+                    session.auth().verify(5L, TimeUnit.SECONDS);
+
+                    ScpClient scp = createScpClient(session);
+                    String data = getCurrentTestName() + "\n";
+
+                    Path targetPath = detectTargetFolder().toPath();
+                    Path parentPath = targetPath.getParent();
+                    Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+                    Utils.deleteRecursive(scpRoot);
+
+                    Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+                    Path localOutFile = localDir.resolve(getCurrentTestName() + "-1.txt");
+                    writeFile(localOutFile, data);
+
+                    Path remoteDir = scpRoot.resolve("remote");
+                    Path remoteOutFile = remoteDir.resolve(localOutFile.getFileName());
+                    assertFalse("Remote folder already exists: " + remoteDir, Files.exists(remoteDir));
+                    
+                    String localOutPath = localOutFile.toString();
+                    String remoteOutPath = Utils.resolveRelativeRemotePath(parentPath, remoteOutFile);
+                    try {
+                        scp.upload(localOutPath, remoteOutPath);
+                        fail("Expected IOException for 1st time " + remoteOutPath);
+                    } catch(IOException e) {
+                        // ok
+                    }
+                    
+                    Files.createDirectories(remoteDir);
+                    scp.upload(localOutPath, remoteOutPath);
+                    assertFileLength(remoteOutFile, data.length(), 5000);
+
+                    Path secondLocal = localDir.resolve(localOutFile.getFileName());
+                    scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, secondLocal));
+                    assertFileLength(secondLocal, data.length(), 5000);
+                    
+                    Path localPath = localDir.resolve(getCurrentTestName() + "-path.txt");
+                    scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, localPath));
+                    assertFileLength(localPath, data.length(), 5000);
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testScpNativeOnMultipleFiles() throws Exception {
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            client.start();
+
+            try {
+                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                    session.addPasswordIdentity(getCurrentTestName());
+                    session.auth().verify(5L, TimeUnit.SECONDS);
+
+                    ScpClient scp = createScpClient(session);
+                    Path targetPath = detectTargetFolder().toPath();
+                    Path parentPath = targetPath.getParent();
+                    Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+                    Utils.deleteRecursive(scpRoot);
+
+                    Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+                    Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
+                    byte[] data = writeFile(local1, getCurrentTestName() + "\n");
+
+                    Path local2 = localDir.resolve(getCurrentTestName() + "-2.txt");
+                    Files.write(local2, data);
+
+                    Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+                    Path remote1 = remoteDir.resolve(local1.getFileName());
+                    String remote1Path = Utils.resolveRelativeRemotePath(parentPath, remote1);
+                    String[] locals = { local1.toString(), local2.toString() };
+                    try {
+                        scp.upload(locals, remote1Path);
+                        fail("Unexpected upload success to missing remote file: " + remote1Path);
+                    } catch (IOException e) {
+                        // Ok
+                    }
+                    
+                    Files.write(remote1, data);
+                    try {
+                        scp.upload(locals, remote1Path);
+                        fail("Unexpected upload success to existing remote file: " + remote1Path);
+                    } catch (IOException e) {
+                        // Ok
+                    }
+
+                    Path remoteSubDir = assertHierarchyTargetFolderExists(remoteDir.resolve("dir"));
+                    scp.upload(locals, Utils.resolveRelativeRemotePath(parentPath, remoteSubDir));
+                    
+                    Path remoteSub1 = remoteSubDir.resolve(local1.getFileName());
+                    assertFileLength(remoteSub1, data.length, 5000);
+
+                    Path remoteSub2 = remoteSubDir.resolve(local2.getFileName());
+                    assertFileLength(remoteSub2, data.length, 5000);
+
+                    String[] remotes = {
+                            Utils.resolveRelativeRemotePath(parentPath, remoteSub1),
+                            Utils.resolveRelativeRemotePath(parentPath, remoteSub2),
+                        };
+
+                    try {
+                        scp.download(remotes, Utils.resolveRelativeRemotePath(parentPath, local1));
+                        fail("Unexpected download success to existing local file: " + local1);
+                    } catch (IOException e) {
+                        // Ok
+                    }
+                    
+                    Path localSubDir = localDir.resolve("dir");
+                    try {
+                        scp.download(remotes, localSubDir);
+                        fail("Unexpected download success to non-existing folder: " + localSubDir);
+                    } catch (IOException e) {
+                        // Ok
+                    }
+
+                    Files.createDirectories(localSubDir);
+                    scp.download(remotes, localSubDir);
+
+                    assertFileLength(localSubDir.resolve(remoteSub1.getFileName()), data.length, 5000);
+                    assertFileLength(localSubDir.resolve(remoteSub2.getFileName()), data.length, 5000);
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testScpNativeOnRecursiveDirs() throws Exception {
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                ScpClient scp = createScpClient(session);
+                Path targetPath = detectTargetFolder().toPath();
+                Path parentPath = targetPath.getParent();
+                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+                Utils.deleteRecursive(scpRoot);
+
+                Path localDir = scpRoot.resolve("local");
+                Path localSubDir = assertHierarchyTargetFolderExists(localDir.resolve("dir"));
+                Path localSub1 = localSubDir.resolve(getCurrentTestName() + "-1.txt");
+                byte[] data = writeFile(localSub1, getCurrentTestName() + "\n");
+                Path localSub2 = localSubDir.resolve(getCurrentTestName() + "-2.txt");
+                Files.write(localSub2, data);
+
+                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+                scp.upload(localSubDir, Utils.resolveRelativeRemotePath(parentPath, remoteDir), ScpClient.Option.Recursive);
+                
+                Path remoteSubDir = remoteDir.resolve(localSubDir.getFileName());
+                assertFileLength(remoteSubDir.resolve(localSub1.getFileName()), data.length, 5000);
+                assertFileLength(remoteSubDir.resolve(localSub2.getFileName()), data.length, 5000);
+
+                Utils.deleteRecursive(localSubDir);
+
+                scp.download(Utils.resolveRelativeRemotePath(parentPath, remoteSubDir), localDir, ScpClient.Option.Recursive);
+                assertFileLength(localSub1, data.length, 5000);
+                assertFileLength(localSub2, data.length, 5000);
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testScpNativeOnDirWithPattern() throws Exception {
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                ScpClient scp = createScpClient(session);
+                Path targetPath = detectTargetFolder().toPath();
+                Path parentPath = targetPath.getParent();
+                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+                Utils.deleteRecursive(scpRoot);
+
+                Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
+                Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
+                byte[] data = writeFile(local1, getCurrentTestName() + "\n");
+                Path local2 = localDir.resolve(getCurrentTestName() + "-2.txt");
+                Files.write(local2, data);
+
+                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+                String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteDir);
+                scp.upload(localDir.toString() + File.separator + "*", remotePath);
+                assertFileLength(remoteDir.resolve(local1.getFileName()), data.length, 5000);
+                assertFileLength(remoteDir.resolve(local2.getFileName()), data.length, 5000);
+
+                Files.delete(local1);
+                Files.delete(local2);
+                scp.download(remotePath + "/*", localDir);
+                assertFileLength(local1, data.length, 5000);
+                assertFileLength(local2, data.length, 5000);
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testScpNativeOnMixedDirAndFiles() throws Exception {
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                ScpClient scp = createScpClient(session);
+                Path targetPath = detectTargetFolder().toPath();
+                Path parentPath = targetPath.getParent();
+                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+                Utils.deleteRecursive(scpRoot);
+
+                Path localDir = scpRoot.resolve("local");
+                Path localSubDir = assertHierarchyTargetFolderExists(localDir.resolve("dir"));
+                Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
+                byte[] data = writeFile(local1, getCurrentTestName() + "\n");
+                Path localSub2 = localSubDir.resolve(getCurrentTestName() + "-2.txt");
+                Files.write(localSub2, data);
+
+                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+                String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteDir);
+                scp.upload(localDir.toString() + File.separator + "*", remotePath, ScpClient.Option.Recursive);
+                assertFileLength(remoteDir.resolve(local1.getFileName()), data.length, 5000);
+
+                Path remoteSubDir = remoteDir.resolve(localSubDir.getFileName());
+                assertFileLength(remoteSubDir.resolve(localSub2.getFileName()), data.length, 5000);
+
+                Files.delete(local1);
+                Utils.deleteRecursive(localSubDir);
+
+                scp.download(remotePath + "/*", localDir);
+                assertFileLength(local1, data.length, 5000);
+                assertFalse("Unexpected recursive local file: " + localSub2, Files.exists(localSub2));
+
+                Files.delete(local1);
+                scp.download(remotePath + "/*", localDir, ScpClient.Option.Recursive);
+                assertFileLength(local1, data.length, 5000);
+                assertFileLength(localSub2, data.length, 5000);
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testScpNativePreserveAttributes() throws Exception {
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                ScpClient scp = createScpClient(session);
+                Path targetPath = detectTargetFolder().toPath();
+                Path parentPath = targetPath.getParent();
+                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+                Utils.deleteRecursive(scpRoot);
+
+                Path localDir = scpRoot.resolve("local");
+                Path localSubDir = assertHierarchyTargetFolderExists(localDir.resolve("dir"));
+                // convert everything to seconds since this is the SCP timestamps granularity
+                long lastMod = TimeUnit.MILLISECONDS.toSeconds(Files.getLastModifiedTime(localSubDir).toMillis() - TimeUnit.DAYS.toMillis(1));
+                Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
+                byte[] data = writeFile(local1, getCurrentTestName() + "\n");
+                File lclFile1 = local1.toFile();
+                lclFile1.setLastModified(lastMod);
+                lclFile1.setExecutable(true, true);
+                lclFile1.setWritable(false, false);
+
+                Path localSub2 = localSubDir.resolve(getCurrentTestName() + "-2.txt");
+                Files.write(localSub2, data);
+                File lclSubFile2 = localSub2.toFile();
+                lclSubFile2.setLastModified(lastMod);
+
+                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+                String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteDir);
+                scp.upload(localDir.toString() + File.separator + "*", remotePath, ScpClient.Option.Recursive, ScpClient.Option.PreserveAttributes);
+
+                Path remote1 = remoteDir.resolve(local1.getFileName());
+                assertFileLength(remote1, data.length, 5000);
+                
+                File remFile1 = remote1.toFile();
+                assertLastModifiedTimeEquals(remFile1, lastMod);
+
+                Path remoteSubDir = remoteDir.resolve(localSubDir.getFileName());
+                Path remoteSub2 = remoteSubDir.resolve(localSub2.getFileName());
+                assertFileLength(remoteSub2, data.length, 5000);
+
+                File remSubFile2 = remoteSub2.toFile();
+                assertLastModifiedTimeEquals(remSubFile2, lastMod);
+
+                Utils.deleteRecursive(localDir);
+                Files.createDirectories(localDir);
+
+                scp.download(remotePath + "/*", localDir, ScpClient.Option.Recursive, ScpClient.Option.PreserveAttributes);
+                assertFileLength(local1, data.length, 5000);
+                assertLastModifiedTimeEquals(lclFile1, lastMod);
+                assertFileLength(localSub2, data.length, 5000);
+                assertLastModifiedTimeEquals(lclSubFile2, lastMod);
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    @Test
+    public void testStreamsUploadAndDownload() throws Exception {
+        try (SshClient client = SshClient.setUpDefaultClient()) {
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                ScpClient scp = createScpClient(session);
+                Path targetPath = detectTargetFolder().toPath();
+                Path parentPath = targetPath.getParent();
+                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
+                Utils.deleteRecursive(scpRoot);
+
+                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
+                Path remoteFile = remoteDir.resolve(getCurrentTestName() + ".txt");
+                String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
+                byte[] data = (getClass().getName() + "#" + getCurrentTestName()).getBytes();
+                scp.upload(data, remotePath, EnumSet.allOf(PosixFilePermission.class), null);
+
+                byte[] uploaded = Files.readAllBytes(remoteFile);
+                assertArrayEquals("Mismatched uploaded data", data, uploaded);
+
+                byte[] downloaded = scp.downloadBytes(remotePath);
+                assertArrayEquals("Mismatched downloaded data", uploaded, downloaded);
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    // see http://stackoverflow.com/questions/2717936/file-createnewfile-creates-files-with-last-modified-time-before-actual-creatio
+    // See https://msdn.microsoft.com/en-us/library/ms724290(VS.85).aspx
+    // The NTFS file system delays updates to the last access time for a file by up to 1 hour after the last access
+    private static void assertLastModifiedTimeEquals(File file, long expectedSeconds) {
+        long actualSeconds = TimeUnit.MILLISECONDS.toSeconds(file.lastModified());
+        if (OsUtils.isWin32()) {
+            if (expectedSeconds != actualSeconds) {
+                System.err.append("Mismatched last modified time for ").append(file.getAbsolutePath())
+                          .append(" - expected=").append(String.valueOf(expectedSeconds))
+                          .append(", actual=").println(actualSeconds);
+            }
+        } else {
+            assertEquals("Mismatched last modified time for " + file.getAbsolutePath(), expectedSeconds, actualSeconds);
+        }
+    }
+
+    private static byte[] writeFile(Path path, String data) throws IOException {
+        try(OutputStream fos = Files.newOutputStream(path)) {
+            byte[]  bytes = data.getBytes();
+            fos.write(bytes);
+            return bytes;
+        }
+    }
+
+    @Test
+    public void testJschScp() throws Exception {
+        session = getJschSession();
+        try {
+            String data = getCurrentTestName() + "\n";
+    
+            String unixDir = "target/scp";
+            String fileName = getCurrentTestName() + ".txt";
+            String unixPath = unixDir + "/" + fileName;
+            File root = new File(unixDir);
+            File target = new File(unixPath);
+            Utils.deleteRecursive(root);
+            root.mkdirs();
+            assertTrue(root.exists());
+    
+            target.delete();
+            assertFalse(target.exists());
+            sendFile(unixPath, fileName, data);
+            assertFileLength(target, data.length(), 5000);
+    
+            target.delete();
+            assertFalse(target.exists());
+            sendFile(unixDir, fileName, data);
+            assertFileLength(target, data.length(), 5000);
+    
+            sendFileError("target", ScpHelper.SCP_COMMAND_PREFIX, data);
+    
+            readFileError(unixDir);
+    
+            assertEquals("Mismatched file data", data, readFile(unixPath, target.length()));
+            assertEquals("Mismatched dir data", data, readDir(unixDir, fileName, target.length()));
+    
+            target.delete();
+            root.delete();
+    
+            sendDir("target", ScpHelper.SCP_COMMAND_PREFIX, fileName, data);
+            assertFileLength(target, data.length(), 5000);
+        } finally {
+            session.disconnect();
+        }
+    }
+
+    @Test
+    public void testWithGanymede() throws Exception {
+        // begin client config
+        final Connection conn = new Connection("localhost", port);
+        try {
+            conn.connect(null, 5000, 0);
+            conn.authenticateWithPassword("sshd", "sshd");
+            final SCPClient scp_client = new SCPClient(conn);
+            final Properties props = new Properties();
+            props.setProperty("test", "test-passed");
+            File f = new File("target/scp/gan");
+            Utils.deleteRecursive(f);
+            f.mkdirs();
+            assertTrue(f.exists());
+    
+            String name = "test.properties";
+            scp_client.put(toBytes(props, ""), name, "target/scp/gan");
+            assertTrue(new File(f, name).exists());
+            assertTrue(new File(f, name).delete());
+    
+            name = "test2.properties";
+            scp_client.put(toBytes(props, ""), name, "target/scp/gan");
+            assertTrue(new File(f, name).exists());
+            assertTrue(new File(f, name).delete());
+    
+            assertTrue(f.delete());
+        } finally {
+            conn.close();
+        }
+    }
+
+    private byte[] toBytes(final Properties properties, final String comments) {
+        try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+            properties.store(baos, comments);
+            baos.close();
+            return baos.toByteArray();
+        } catch(IOException cause) {
+            throw new RuntimeException("Failed to output properties to byte[]", cause);
+        }
+    }
+
+    protected String readFile(String path, long expectedSize) throws Exception {
+        ChannelExec c = (ChannelExec) session.openChannel("exec");
+        c.setCommand("scp -f " + path);
+        c.connect();
+
+        int namePos = path.lastIndexOf('/');
+        String fileName = (namePos >= 0) ? path.substring(namePos + 1) : path;
+        try(OutputStream os = c.getOutputStream();
+            InputStream is = c.getInputStream()) {
+
+            os.write(0);
+            os.flush();
+            String header = readLine(is);
+            assertEquals("Mismatched header for " + path, "C0644 " + expectedSize + " " + fileName, header);
+
+            int length = Integer.parseInt(header.substring(6, header.indexOf(' ', 6)));
+            os.write(0);
+            os.flush();
+    
+            byte[] buffer = new byte[length];
+            length = is.read(buffer, 0, buffer.length);
+            assertEquals("Mismatched read data length for " + path, length, buffer.length);
+            assertAckReceived(is, "Read data of " + path);
+
+            os.write(0);
+            os.flush();
+
+            return new String(buffer);
+        } finally {
+            c.disconnect();
+        }
+    }
+
+    protected String readDir(String path, String fileName, long expectedSize) throws Exception {
+        ChannelExec c = (ChannelExec) session.openChannel("exec");
+        c.setCommand("scp -r -f " + path);
+        c.connect();
+
+        try(OutputStream os = c.getOutputStream();
+            InputStream is = c.getInputStream()) {
+            os.write(0);
+            os.flush();
+
+            String header = readLine(is);
+            assertTrue("Bad header prefix for " + path + ": " + header, header.startsWith("D0755 0 "));
+            os.write(0);
+            os.flush();
+
+            header = readLine(is);
+            assertEquals("Mismatched dir header for " + path, "C0644 " + expectedSize + " " + fileName, header);
+            int length = Integer.parseInt(header.substring(6, header.indexOf(' ', 6)));
+            os.write(0);
+            os.flush();
+
+            byte[] buffer = new byte[length];
+            length = is.read(buffer, 0, buffer.length);
+            assertEquals("Mismatched read buffer size for " + path, length, buffer.length);
+            assertAckReceived(is, "Read date of " + path);
+
+            os.write(0);
+            os.flush();
+
+            header = readLine(is);
+            assertEquals("Mismatched end value for " + path, "E", header);
+            os.write(0);
+            os.flush();
+
+            return new String(buffer);
+        } finally {
+            c.disconnect();
+        }
+    }
+
+    protected String readFileError(String path) throws Exception {
+        ChannelExec c = (ChannelExec) session.openChannel("exec");
+        String command = "scp -f " + path; 
+        c.setCommand(command);
+        c.connect();
+
+        try(OutputStream os = c.getOutputStream();
+            InputStream is = c.getInputStream()) {
+        
+            os.write(0);
+            os.flush();
+            assertEquals("Mismatched response for command: " + command, 2, is.read());
+            return null;
+        } finally {
+            c.disconnect();
+        }
+    }
+
+    protected void sendFile(String path, String name, String data) throws Exception {
+        ChannelExec c = (ChannelExec) session.openChannel("exec");
+        String command = "scp -t " + path;
+        c.setCommand(command);
+        c.connect();
+
+        try(OutputStream os = c.getOutputStream();
+            InputStream is = c.getInputStream()) {
+
+            assertAckReceived(is, command);
+            assertAckReceived(os, is, "C7777 " + data.length() + " " + name); 
+
+            os.write(data.getBytes());
+            os.flush();
+            assertAckReceived(is, "Sent data (length=" + data.length() + ") for " + path + "[" + name + "]");
+
+            os.write(0);
+            os.flush();
+
+            Thread.sleep(100);
+        } finally {
+            c.disconnect();
+        }
+    }
+
+    protected void assertAckReceived(OutputStream os, InputStream is, String command) throws IOException {
+        os.write((command + "\n").getBytes());
+        os.flush();
+        assertAckReceived(is, command);
+    }
+
+    protected void assertAckReceived(InputStream is, String command) throws IOException {
+        assertEquals("No ACK for command=" + command, 0, is.read());
+    }
+
+    protected void sendFileError(String path, String name, String data) throws Exception {
+        ChannelExec c = (ChannelExec) session.openChannel("exec");
+        String command = "scp -t " + path; 
+        c.setCommand(command);
+        c.connect();
+
+        try(OutputStream os = c.getOutputStream();
+            InputStream is = c.getInputStream()) {
+
+            assertAckReceived(is, command);
+
+            command = "C7777 " + data.length() + " " + name;
+            os.write((command + "\n").getBytes());
+            os.flush();
+            assertEquals("Mismatched response for command=" + command, 2, is.read());
+        } finally {
+            c.disconnect();
+        }
+    }
+
+    protected void sendDir(String path, String dirName, String fileName, String data) throws Exception {
+        ChannelExec c = (ChannelExec) session.openChannel("exec");
+        String command = "scp -t -r " + path;
+        c.setCommand(command);
+        c.connect();
+        
+        try(OutputStream os = c.getOutputStream();
+            InputStream is = c.getInputStream()) {
+
+            assertAckReceived(is, command);
+            assertAckReceived(os, is, "D0755 0 " + dirName);
+            assertAckReceived(os, is, "C7777 " + data.length() + " " + fileName);
+
+            os.write(data.getBytes());
+            os.flush();
+            assertAckReceived(is, "Send data of " + path);
+
+            os.write(0);
+            os.flush();
+            
+            os.write("E\n".getBytes());
+            os.flush();
+            assertAckReceived(is, "Signal end of " + path);
+        } finally {
+            c.disconnect();
+        }
+    }
+
+    private static String readLine(InputStream in) throws IOException {
+        OutputStream baos = new ByteArrayOutputStream();
+        try {
+            for (; ; ) {
+                int c = in.read();
+                if (c == '\n') {
+                    return baos.toString();
+                } else if (c == -1) {
+                    throw new IOException("End of stream");
+                } else {
+                    baos.write(c);
+                }
+            }
+        } finally {
+            baos.close();
+        }
+    }
+
+    private ScpClient createScpClient(ClientSession session) {
+        final Logger logger = LoggerFactory.getLogger(getClass().getName() + "[" + getCurrentTestName() + "]");
+        return session.createScpClient(new ScpTransferEventListener() {
+            @Override
+            public void startFolderEvent(FileOperation op, Path file, Set<PosixFilePermission> perms) {
+                logEvent("starFolderEvent", op, file, false, -1L, perms, null);
+            }
+
+            @Override
+            public void startFileEvent(FileOperation op, Path file, long length, Set<PosixFilePermission> perms) {
+                logEvent("startFileEvent", op, file, true, length, perms, null);
+
+            }
+
+            @Override
+            public void endFolderEvent(FileOperation op, Path file, Set<PosixFilePermission> perms, Throwable thrown) {
+                logEvent("endFolderEvent", op, file, false, -1L, perms, thrown);
+            }
+
+            @Override
+            public void endFileEvent(FileOperation op, Path file, long length, Set<PosixFilePermission> perms, Throwable thrown) {
+                logEvent("endFileEvent", op, file, true, length, perms, thrown);
+            }
+
+            private void logEvent(String type, FileOperation op, Path path, boolean isFile, long length, Collection<PosixFilePermission> perms, Throwable t) {
+                StringBuilder sb = new StringBuilder(Byte.MAX_VALUE);
+                sb.append('\t').append(type)
+                        .append('[').append(op).append(']')
+                        .append(' ').append(isFile ? "File" : "Directory").append('=').append(path)
+                        .append(' ').append("length=").append(length)
+                        .append(' ').append("perms=").append(perms)
+                ;
+                if (t != null) {
+                    sb.append(' ').append("ERROR=").append(t.getClass().getSimpleName()).append(": ").append(t.getMessage());
+                }
+                logger.info(sb.toString());
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpFileSystemTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpFileSystemTest.java b/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpFileSystemTest.java
index b7dc9a1..5d5ca94 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpFileSystemTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpFileSystemTest.java
@@ -86,7 +86,7 @@ public class SftpFileSystemTest extends BaseTestSupport {
         sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setCommandFactory(new ScpCommandFactory());
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.setFileSystemFactory(fileSystemFactory);
         sshd.start();
         port = sshd.getPort();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpTest.java
index 6bdffea..c125bf2 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/sftp/SftpTest.java
@@ -96,7 +96,7 @@ public class SftpTest extends BaseTestSupport {
         sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setCommandFactory(new ScpCommandFactory());
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.setFileSystemFactory(fileSystemFactory);
         sshd.start();
         port = sshd.getPort();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/common/compression/CompressionTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/compression/CompressionTest.java b/sshd-core/src/test/java/org/apache/sshd/common/compression/CompressionTest.java
index 2fa32b2..5289fb1 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/compression/CompressionTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/compression/CompressionTest.java
@@ -68,7 +68,7 @@ public class CompressionTest extends BaseTestSupport {
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setCompressionFactories(Arrays.<NamedFactory<org.apache.sshd.common.compression.Compression>>asList(compression));
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.start();
         JSch.setConfig("compression.s2c",  "zlib@openssh.com,zlib,none");
         JSch.setConfig("compression.c2s",  "zlib@openssh.com,zlib,none");
@@ -88,8 +88,8 @@ public class CompressionTest extends BaseTestSupport {
     protected void runTest() throws Exception {
         JSchLogger.init();
         JSch sch = new JSch();
-        com.jcraft.jsch.Session s = sch.getSession("smx", "localhost", sshd.getPort());
-        s.setUserInfo(new SimpleUserInfo("smx"));
+        com.jcraft.jsch.Session s = sch.getSession(getCurrentTestName(), "localhost", sshd.getPort());
+        s.setUserInfo(new SimpleUserInfo(getCurrentTestName()));
 
         s.connect();
         try {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java b/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java
index eff59e5..c6ec293 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/BaseTestSupport.java
@@ -152,7 +152,9 @@ public abstract class BaseTestSupport extends Assert {
     }
 
     public static Path assertHierarchyTargetFolderExists(Path folder, LinkOption ... options) throws IOException {
-        if (!Files.exists(folder, options)) {
+        if (Files.exists(folder, options)) {
+            assertTrue("Target is an existing file instead of a folder: " + folder, Files.isDirectory(folder, options));
+        } else {
             Files.createDirectories(folder);
         }
         
@@ -160,7 +162,9 @@ public abstract class BaseTestSupport extends Assert {
     }
 
     public static File assertHierarchyTargetFolderExists(File folder) {
-        if (!folder.exists()) {
+        if (folder.exists()) {
+            assertTrue("Target is an existing file instead of a folder: " + folder.getAbsolutePath(), folder.isDirectory());
+        } else {
             assertTrue("Failed to create hierarchy of " + folder.getAbsolutePath(), folder.mkdirs());
         }
         

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/util/BogusPasswordAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/BogusPasswordAuthenticator.java b/sshd-core/src/test/java/org/apache/sshd/util/BogusPasswordAuthenticator.java
index 7008bd8..40a3162 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/BogusPasswordAuthenticator.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/BogusPasswordAuthenticator.java
@@ -18,6 +18,7 @@
  */
 package org.apache.sshd.util;
 
+import org.apache.sshd.common.util.AbstractLoggingBean;
 import org.apache.sshd.server.PasswordAuthenticator;
 import org.apache.sshd.server.session.ServerSession;
 
@@ -26,10 +27,20 @@ import org.apache.sshd.server.session.ServerSession;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public class BogusPasswordAuthenticator implements PasswordAuthenticator {
+public class BogusPasswordAuthenticator extends AbstractLoggingBean implements PasswordAuthenticator {
+    public static final BogusPasswordAuthenticator INSTANCE = new BogusPasswordAuthenticator();
+
+    public BogusPasswordAuthenticator() {
+        super();
+    }
 
     @Override
     public boolean authenticate(String username, String password, ServerSession session) {
-        return username != null && username.equals(password);
+        boolean result = (username != null) && username.equals(password);
+        if (log.isDebugEnabled()) {
+            log.debug("authenticate({}) {} / {} - sucess = {}", session, username, password, Boolean.valueOf(result));
+        }
+        
+        return result;
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/util/BogusPublickeyAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/BogusPublickeyAuthenticator.java b/sshd-core/src/test/java/org/apache/sshd/util/BogusPublickeyAuthenticator.java
deleted file mode 100644
index 15a649a..0000000
--- a/sshd-core/src/test/java/org/apache/sshd/util/BogusPublickeyAuthenticator.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.util;
-
-import java.security.PublicKey;
-
-import org.apache.sshd.server.PublickeyAuthenticator;
-import org.apache.sshd.server.session.ServerSession;
-
-/**
- * TODO Add javadoc
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class BogusPublickeyAuthenticator implements PublickeyAuthenticator {
-
-    @Override
-    public boolean authenticate(String username, PublicKey key, ServerSession session) {
-        return true;
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/util/Utils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/Utils.java b/sshd-core/src/test/java/org/apache/sshd/util/Utils.java
index fd42e38..a7d8185 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/Utils.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/Utils.java
@@ -31,36 +31,81 @@ import java.nio.file.DirectoryStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.security.CodeSource;
+import java.security.KeyPair;
 import java.security.ProtectionDomain;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
 import org.apache.sshd.common.keyprovider.KeyPairProvider;
 import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
 
 public class Utils {
-
+    // uses a cached instance to avoid re-creating the keys as it is a time-consuming effort
+    private static final AtomicReference<KeyPairProvider> keyPairProviderHolder = new AtomicReference<KeyPairProvider>();
+    public static final String DEFAULT_TEST_HOST_KEY_PROVIDER_ALGORITHM="RSA";
     public static KeyPairProvider createTestHostKeyProvider() {
-        return new SimpleGeneratorHostKeyProvider("target/hostkey.rsa", "RSA");
-//        return createTestKeyPairProvider("hostkey.pem");
+        KeyPairProvider provider = keyPairProviderHolder.get();
+        if (provider != null) {
+            return provider;
+        }
+
+        
+        File targetFolder = ValidateUtils.checkNotNull(detectTargetFolder(Utils.class), "Failed to detect target folder", GenericUtils.EMPTY_OBJECT_ARRAY);
+        File file = new File(targetFolder, "hostkey." + DEFAULT_TEST_HOST_KEY_PROVIDER_ALGORITHM.toLowerCase());
+        provider = validateKeyPairProvider(new SimpleGeneratorHostKeyProvider(file.getAbsolutePath(), DEFAULT_TEST_HOST_KEY_PROVIDER_ALGORITHM.toUpperCase()));
+        
+        KeyPairProvider prev = keyPairProviderHolder.getAndSet(provider);
+        if (prev != null) { // check if somebody else beat us to it
+            return prev;
+        } else {
+            return provider;
+        }
     }
 
+    // uses a cached instance to avoid re-creating the keys as it is a time-consuming effort
+    private static final Map<String, FileKeyPairProvider> providersMap = new ConcurrentHashMap<String, FileKeyPairProvider>(); 
     public static FileKeyPairProvider createTestKeyPairProvider(String resource) {
-        return new FileKeyPairProvider(new String[] { getFile(resource) });
+        String file = getFile(resource);
+        FileKeyPairProvider provider = providersMap.get(file);
+        if (provider != null) {
+            return provider;
+        }
+
+        provider = validateKeyPairProvider(new FileKeyPairProvider(file));
+            
+        FileKeyPairProvider prev = providersMap.put(file, provider);
+        if (prev != null) { // check if somebody else beat us to it
+            return prev;
+        } else {
+            return provider;
+        }
+    }
+
+    private static <P extends KeyPairProvider> P validateKeyPairProvider(P provider) {
+        ValidateUtils.checkNotNull(provider, "No provider", GenericUtils.EMPTY_OBJECT_ARRAY);
+
+        // get the I/O out of the way
+        Iterable<KeyPair>   keys=ValidateUtils.checkNotNull(provider.loadKeys(), "No keys loaded", GenericUtils.EMPTY_OBJECT_ARRAY);
+        if (keys instanceof Collection<?>) {
+            ValidateUtils.checkNotNullAndNotEmpty((Collection<?>) keys, "Empty keys loaded", GenericUtils.EMPTY_OBJECT_ARRAY);
+        }
+        
+        return provider;
     }
 
     public static int getFreePort() throws Exception {
-        ServerSocket s = new ServerSocket();
-        try {
+        try(ServerSocket s = new ServerSocket()) {
             s.setReuseAddress(true);
             s.bind(new InetSocketAddress((InetAddress) null, 0));
             return s.getLocalPort();
-        } finally {
-            s.close();
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/resources/spring.xml
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/resources/spring.xml b/sshd-core/src/test/resources/spring.xml
index f00638c..4daa11e 100644
--- a/sshd-core/src/test/resources/spring.xml
+++ b/sshd-core/src/test/resources/spring.xml
@@ -41,7 +41,7 @@
             <bean class="org.apache.sshd.util.BogusPasswordAuthenticator" />
         </property>
         <property name="publickeyAuthenticator">
-            <bean class="org.apache.sshd.util.BogusPublickeyAuthenticator" />
+            <bean class="org.apache.sshd.server.PublickeyAuthenticator.AcceptAllPublickeyAuthenticator" />
         </property>
         <!-- Standard properties -->
         <!--

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java b/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java
index 87bfc65..d36cbbb 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/pack/GitPackCommandFactory.java
@@ -41,6 +41,7 @@ public class GitPackCommandFactory implements CommandFactory {
         this.delegate = delegate;
     }
 
+    @Override
     public Command createCommand(String command) {
         if (command.startsWith("git-")) {
             return new GitPackCommand(rootDir, command);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-git/src/main/java/org/apache/sshd/git/pgm/EmbeddedCommandRunner.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/main/java/org/apache/sshd/git/pgm/EmbeddedCommandRunner.java b/sshd-git/src/main/java/org/apache/sshd/git/pgm/EmbeddedCommandRunner.java
index fc1958d..58d565d 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/pgm/EmbeddedCommandRunner.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/pgm/EmbeddedCommandRunner.java
@@ -32,7 +32,6 @@ import java.util.List;
 
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.lib.Repository;
-import org.eclipse.jgit.lib.RepositoryBuilder;
 import org.eclipse.jgit.pgm.CommandCatalog;
 import org.eclipse.jgit.pgm.CommandRef;
 import org.eclipse.jgit.pgm.Die;
@@ -151,7 +150,9 @@ public class EmbeddedCommandRunner {
         set(cmd, "ins", in);
         set(cmd, "outs", out);
         set(cmd, "errs", err);
-        if ((Boolean) call(cmd, "requiresRepository")) {
+        
+        Boolean success = (Boolean) call(cmd, "requiresRepository"); 
+        if (success.booleanValue()) {
             call(cmd, "init", new Class[] { Repository.class, String.class }, new Object[] { openGitDir(gitdir), gitdir });
         } else {
             call(cmd, "init", new Class[] { Repository.class, String.class }, new Object[] { null, gitdir });
@@ -167,7 +168,7 @@ public class EmbeddedCommandRunner {
     }
 
     private Object get(Object obj, String name) throws IllegalAccessException, NoSuchFieldException {
-        Class clazz = obj.getClass();
+        Class<?> clazz = obj.getClass();
         while (clazz != null) {
             try {
                 Field field = clazz.getDeclaredField(name);
@@ -181,7 +182,7 @@ public class EmbeddedCommandRunner {
     }
 
     private void set(Object obj, String name, Object val) throws IllegalAccessException, NoSuchFieldException {
-        Class clazz = obj.getClass();
+        Class<?> clazz = obj.getClass();
         while (clazz != null) {
             try {
                 Field field = clazz.getDeclaredField(name);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java b/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java
index e3741a4..06e0f37 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/pgm/GitPgmCommandFactory.java
@@ -41,6 +41,7 @@ public class GitPgmCommandFactory implements CommandFactory {
         this.delegate = delegate;
     }
 
+    @Override
     public Command createCommand(String command) {
         if (command.startsWith("git ")) {
             return new GitPgmCommand(rootDir, command.substring("git ".length()));

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java
index aca4e3c..ce739d8 100644
--- a/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java
+++ b/sshd-git/src/main/java/org/apache/sshd/git/transport/GitSshdSessionFactory.java
@@ -26,6 +26,8 @@ import org.apache.sshd.ClientChannel;
 import org.apache.sshd.ClientSession;
 import org.apache.sshd.SshClient;
 import org.apache.sshd.client.channel.ChannelExec;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
 import org.eclipse.jgit.errors.TransportException;
 import org.eclipse.jgit.transport.CredentialItem;
 import org.eclipse.jgit.transport.CredentialsProvider;
@@ -92,6 +94,7 @@ public class GitSshdSessionFactory extends SshSessionFactory {
 
         }
 
+        @Override
         public Process exec(String commandName, int timeout) throws IOException {
             final ChannelExec channel = session.createExecChannel(commandName);
             channel.open().verify();
@@ -118,7 +121,8 @@ public class GitSshdSessionFactory extends SshSessionFactory {
 
                 @Override
                 public int exitValue() {
-                    return channel.getExitStatus();
+                    Integer status = ValidateUtils.checkNotNull(channel.getExitStatus(), "No channel status available", GenericUtils.EMPTY_OBJECT_ARRAY);
+                    return status.intValue();
                 }
 
                 @Override
@@ -128,6 +132,7 @@ public class GitSshdSessionFactory extends SshSessionFactory {
             };
         }
 
+        @Override
         public void disconnect() {
             client.close(true);
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java b/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
index fa3c5ec..f0a2eb5 100644
--- a/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
+++ b/sshd-git/src/test/java/org/apache/sshd/git/pack/GitPackCommandTest.java
@@ -21,7 +21,6 @@ package org.apache.sshd.git.pack;
 import java.io.File;
 import java.util.Arrays;
 
-import com.jcraft.jsch.JSch;
 import org.apache.sshd.SshServer;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.git.transport.GitSshdSessionFactory;
@@ -29,13 +28,15 @@ import org.apache.sshd.git.util.BogusPasswordAuthenticator;
 import org.apache.sshd.git.util.EchoShellFactory;
 import org.apache.sshd.git.util.Utils;
 import org.apache.sshd.server.Command;
-import org.apache.sshd.server.sftp.SftpSubsystem;
 import org.apache.sshd.server.sftp.SftpSubsystemFactory;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.SshSessionFactory;
 import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
 import org.junit.Test;
 
+import com.jcraft.jsch.JSch;
+
 /**
  */
 public class GitPackCommandTest {
@@ -48,7 +49,7 @@ public class GitPackCommandTest {
         sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setShellFactory(new EchoShellFactory());
         sshd.setCommandFactory(new GitPackCommandFactory("target/git/server"));
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.start();
 
         File serverDir = new File("target/git/server/test.git");
@@ -57,7 +58,7 @@ public class GitPackCommandTest {
 
         JSch.setConfig("StrictHostKeyChecking", "no");
         CredentialsProvider.setDefault(new UsernamePasswordCredentialsProvider("sshd", "sshd"));
-        GitSshdSessionFactory.setInstance(new GitSshdSessionFactory());
+        SshSessionFactory.setInstance(new GitSshdSessionFactory());
 
         File dir = new File("target/git/local/test.git");
         Utils.deleteRecursive(dir);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java b/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
index 3d13af1..81a7ba5 100644
--- a/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
+++ b/sshd-git/src/test/java/org/apache/sshd/git/pgm/GitPgmCommandTest.java
@@ -31,7 +31,6 @@ import org.apache.sshd.git.util.BogusPasswordAuthenticator;
 import org.apache.sshd.git.util.EchoShellFactory;
 import org.apache.sshd.git.util.Utils;
 import org.apache.sshd.server.Command;
-import org.apache.sshd.server.sftp.SftpSubsystem;
 import org.apache.sshd.server.sftp.SftpSubsystemFactory;
 import org.eclipse.jgit.api.Git;
 import org.junit.Test;
@@ -54,7 +53,7 @@ public class GitPgmCommandTest {
         sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setShellFactory(new EchoShellFactory());
         sshd.setCommandFactory(new GitPgmCommandFactory("target/git/pgm"));
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.start();
 
         File serverDir = new File("target/git/pgm");
@@ -88,10 +87,11 @@ public class GitPgmCommandTest {
         channel.setErr(System.err);
         channel.open().verify();
         channel.waitFor(ClientChannel.CLOSED, 0);
-        if (channel.getExitStatus() != null) {
-            int s = channel.getExitStatus();
-            if (s != 0) {
-                throw new Exception("Command failed with status " + s);
+        
+        Integer status = channel.getExitStatus();
+        if (status != null) {
+            if (status.intValue() != 0) {
+                throw new Exception("Command failed with status " + status);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-git/src/test/java/org/apache/sshd/git/util/BogusPasswordAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/test/java/org/apache/sshd/git/util/BogusPasswordAuthenticator.java b/sshd-git/src/test/java/org/apache/sshd/git/util/BogusPasswordAuthenticator.java
index 8cc3de3..3963ab0 100644
--- a/sshd-git/src/test/java/org/apache/sshd/git/util/BogusPasswordAuthenticator.java
+++ b/sshd-git/src/test/java/org/apache/sshd/git/util/BogusPasswordAuthenticator.java
@@ -27,7 +27,13 @@ import org.apache.sshd.server.session.ServerSession;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class BogusPasswordAuthenticator implements PasswordAuthenticator {
+    public static final BogusPasswordAuthenticator INSTANCE = new BogusPasswordAuthenticator();
 
+    public BogusPasswordAuthenticator() {
+        super();
+    }
+
+    @Override
     public boolean authenticate(String username, String password, ServerSession session) {
         return username != null && username.equals(password);
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-git/src/test/java/org/apache/sshd/git/util/EchoShellFactory.java
----------------------------------------------------------------------
diff --git a/sshd-git/src/test/java/org/apache/sshd/git/util/EchoShellFactory.java b/sshd-git/src/test/java/org/apache/sshd/git/util/EchoShellFactory.java
index 2faa6eb..9e9b2c2 100644
--- a/sshd-git/src/test/java/org/apache/sshd/git/util/EchoShellFactory.java
+++ b/sshd-git/src/test/java/org/apache/sshd/git/util/EchoShellFactory.java
@@ -36,6 +36,7 @@ import org.apache.sshd.server.ExitCallback;
  */
 public class EchoShellFactory implements Factory<Command> {
 
+    @Override
     public Command create() {
         return new EchoShell();
     }
@@ -65,32 +66,39 @@ public class EchoShellFactory implements Factory<Command> {
             return environment;
         }
 
+        @Override
         public void setInputStream(InputStream in) {
             this.in = in;
         }
 
+        @Override
         public void setOutputStream(OutputStream out) {
             this.out = out;
         }
 
+        @Override
         public void setErrorStream(OutputStream err) {
             this.err = err;
         }
 
+        @Override
         public void setExitCallback(ExitCallback callback) {
             this.callback = callback;
         }
 
+        @Override
         public void start(Environment env) throws IOException {
             environment = env;
             thread = new Thread(this, "EchoShell");
             thread.start();
         }
 
+        @Override
         public void destroy() {
             thread.interrupt();
         }
 
+        @Override
         public void run() {
             BufferedReader r = new BufferedReader(new InputStreamReader(in));
             try {


[3/4] mina-sshd git commit: [SSHD-481] Avoid (re-)creation of bogus test class instances

Posted by lg...@apache.org.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/client/ScpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/ScpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/ScpTest.java
deleted file mode 100644
index a170ad5..0000000
--- a/sshd-core/src/test/java/org/apache/sshd/client/ScpTest.java
+++ /dev/null
@@ -1,982 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sshd.client;
-
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.nio.channels.FileChannel;
-import java.nio.file.FileSystem;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import java.nio.file.attribute.PosixFilePermission;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.Properties;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.sshd.ClientSession;
-import org.apache.sshd.SshClient;
-import org.apache.sshd.SshServer;
-import org.apache.sshd.client.scp.ScpClient;
-import org.apache.sshd.common.Session;
-import org.apache.sshd.common.file.FileSystemFactory;
-import org.apache.sshd.common.file.root.RootedFileSystemProvider;
-import org.apache.sshd.common.scp.ScpHelper;
-import org.apache.sshd.common.scp.ScpTransferEventListener;
-import org.apache.sshd.common.util.OsUtils;
-import org.apache.sshd.server.command.ScpCommandFactory;
-import org.apache.sshd.util.BaseTestSupport;
-import org.apache.sshd.util.BogusPasswordAuthenticator;
-import org.apache.sshd.util.EchoShellFactory;
-import org.apache.sshd.util.JSchLogger;
-import org.apache.sshd.util.SimpleUserInfo;
-import org.apache.sshd.util.Utils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import ch.ethz.ssh2.Connection;
-import ch.ethz.ssh2.SCPClient;
-
-import com.jcraft.jsch.ChannelExec;
-import com.jcraft.jsch.JSch;
-import com.jcraft.jsch.JSchException;
-
-/**
- * Test for SCP support.
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class ScpTest extends BaseTestSupport {
-
-    private SshServer sshd;
-    private int port;
-    private com.jcraft.jsch.Session session;
-    private final FileSystemFactory fileSystemFactory;
-
-    public ScpTest() throws IOException {
-        Path targetPath = detectTargetFolder().toPath();
-        Path parentPath = targetPath.getParent();
-        final FileSystem fileSystem = new RootedFileSystemProvider().newFileSystem(parentPath, Collections.<String,Object>emptyMap());
-        fileSystemFactory = new FileSystemFactory() {
-            @Override
-            public FileSystem createFileSystem(Session session) throws IOException {
-                return fileSystem;
-            }
-        };
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        sshd = SshServer.setUpDefaultServer();
-        sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setCommandFactory(new ScpCommandFactory());
-        sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
-        sshd.setFileSystemFactory(fileSystemFactory);
-        sshd.start();
-        port = sshd.getPort();
-    }
-
-    protected com.jcraft.jsch.Session getJschSession() throws JSchException {
-        JSchLogger.init();
-        JSch sch = new JSch();
-        session = sch.getSession("sshd", "localhost", port);
-        session.setUserInfo(new SimpleUserInfo("sshd"));
-        session.connect();
-        return session;
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (session != null) {
-            session.disconnect();
-        }
-        
-        if (sshd != null) {
-            sshd.stop(true);
-        }
-    }
-
-    @Test
-    @Ignore
-    public void testExternal() throws Exception {
-        System.out.println("Scp available on port " + port);
-        Thread.sleep(5 * 60000);
-    }
-
-    @Test
-    public void testUploadAbsoluteDriveLetter() throws Exception {
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            client.start();
-
-            try {
-                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                    session.addPasswordIdentity(getCurrentTestName());
-                    session.auth().verify(5L, TimeUnit.SECONDS);
-
-                    ScpClient scp = createScpClient(session);
-                    Path targetPath = detectTargetFolder().toPath();
-                    Path parentPath = targetPath.getParent();
-                    Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-                    Utils.deleteRecursive(scpRoot);
-
-                    Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
-                    Path localFile = localDir.resolve(getCurrentTestName() + "-1.txt");
-                    byte[] data = writeFile(localFile, (getCurrentTestName() + "\n"));
-
-                    Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-                    Path remoteFile = remoteDir.resolve(localFile.getFileName().toString());
-                    String localPath = localFile.toString();
-                    String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
-                    scp.upload(localPath, remotePath);
-                    assertFileLength(remoteFile, data.length, 5000);
-
-                    Path secondRemote = remoteDir.resolve(getCurrentTestName() + "-2.txt");
-                    String secondPath = Utils.resolveRelativeRemotePath(parentPath, secondRemote);
-                    scp.upload(localPath, secondPath);
-                    assertFileLength(secondRemote, data.length, 5000);
-                    
-                    Path pathRemote = remoteDir.resolve(getCurrentTestName() + "-path.txt");
-                    String pathPath = Utils.resolveRelativeRemotePath(parentPath, pathRemote);
-                    scp.upload(localFile, pathPath);
-                    assertFileLength(pathRemote, data.length, 5000);
-                }
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testScpUploadOverwrite() throws Exception {
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            client.start();
-
-            try {
-                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                    session.addPasswordIdentity(getCurrentTestName());
-                    session.auth().verify(5L, TimeUnit.SECONDS);
-
-                    ScpClient scp = createScpClient(session);
-                    String data = getCurrentTestName() + "\n";
-
-                    Path targetPath = detectTargetFolder().toPath();
-                    Path parentPath = targetPath.getParent();
-                    Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-                    Utils.deleteRecursive(scpRoot);
-
-                    Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
-                    Path localFile = localDir.resolve(getCurrentTestName() + ".txt");
-                    writeFile(localFile, data);
-
-                    Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-                    Path remoteFile = remoteDir.resolve(localFile.getFileName());
-                    writeFile(remoteFile, data + data);
-
-                    String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
-                    scp.upload(localFile.toString(), remotePath);
-                    assertFileLength(remoteFile, data.length(), 5000);
-                }
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testScpUploadZeroLengthFile() throws Exception {
-        Path targetPath = detectTargetFolder().toPath();
-        Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-        Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
-        Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-        Path zeroLocal = localDir.resolve(getCurrentTestName());
-
-        try (FileChannel fch = FileChannel.open(zeroLocal, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
-            if (fch.size() > 0L) {
-                fch.truncate(0L);
-            }
-        }
-        assertEquals("Non-zero size for local file=" + zeroLocal, 0L, Files.size(zeroLocal));
-
-        Path zeroRemote = remoteDir.resolve(zeroLocal.getFileName());
-        if (Files.exists(zeroRemote)) {
-            Files.delete(zeroRemote);
-        }
-
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            try {
-                client.start();
-
-                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                    session.addPasswordIdentity(getCurrentTestName());
-                    session.auth().verify(5L, TimeUnit.SECONDS);
-
-                    ScpClient scp = createScpClient(session);
-                    String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), zeroRemote);
-                    scp.upload(zeroLocal.toString(), remotePath);
-                    assertFileLength(zeroRemote, 0L, TimeUnit.SECONDS.toMillis(5L));
-                }
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testScpDownloadZeroLengthFile() throws Exception {
-        Path targetPath = detectTargetFolder().toPath();
-        Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-        Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
-        Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-        Path zeroLocal = localDir.resolve(getCurrentTestName());
-        if (Files.exists(zeroLocal)) {
-            Files.delete(zeroLocal);
-        }
-
-        Path zeroRemote = remoteDir.resolve(zeroLocal.getFileName());
-        try (FileChannel fch = FileChannel.open(zeroRemote, StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)) {
-            if (fch.size() > 0L) {
-                fch.truncate(0L);
-            }
-        }
-        assertEquals("Non-zero size for remote file=" + zeroRemote, 0L, Files.size(zeroRemote));
-
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            try {
-                client.start();
-
-                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                    session.addPasswordIdentity(getCurrentTestName());
-                    session.auth().verify(5L, TimeUnit.SECONDS);
-
-                    ScpClient scp = createScpClient(session);
-                    String remotePath = Utils.resolveRelativeRemotePath(targetPath.getParent(), zeroRemote);
-                    scp.download(remotePath, zeroLocal.toString());
-                    assertFileLength(zeroLocal, 0L, TimeUnit.SECONDS.toMillis(5L));
-                }
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testScpNativeOnSingleFile() throws Exception {
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            client.start();
-
-            try {
-                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                    session.addPasswordIdentity(getCurrentTestName());
-                    session.auth().verify(5L, TimeUnit.SECONDS);
-
-                    ScpClient scp = createScpClient(session);
-                    String data = getCurrentTestName() + "\n";
-
-                    Path targetPath = detectTargetFolder().toPath();
-                    Path parentPath = targetPath.getParent();
-                    Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-                    Utils.deleteRecursive(scpRoot);
-
-                    Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
-                    Path localOutFile = localDir.resolve(getCurrentTestName() + "-1.txt");
-                    writeFile(localOutFile, data);
-
-                    Path remoteDir = scpRoot.resolve("remote");
-                    Path remoteOutFile = remoteDir.resolve(localOutFile.getFileName());
-                    assertFalse("Remote folder already exists: " + remoteDir, Files.exists(remoteDir));
-                    
-                    String localOutPath = localOutFile.toString();
-                    String remoteOutPath = Utils.resolveRelativeRemotePath(parentPath, remoteOutFile);
-                    try {
-                        scp.upload(localOutPath, remoteOutPath);
-                        fail("Expected IOException for 1st time " + remoteOutPath);
-                    } catch(IOException e) {
-                        // ok
-                    }
-                    
-                    Files.createDirectories(remoteDir);
-                    scp.upload(localOutPath, remoteOutPath);
-                    assertFileLength(remoteOutFile, data.length(), 5000);
-
-                    Path secondLocal = localDir.resolve(localOutFile.getFileName());
-                    scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, secondLocal));
-                    assertFileLength(secondLocal, data.length(), 5000);
-                    
-                    Path localPath = localDir.resolve(getCurrentTestName() + "-path.txt");
-                    scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, localPath));
-                    assertFileLength(localPath, data.length(), 5000);
-                }
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testScpNativeOnMultipleFiles() throws Exception {
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            client.start();
-
-            try {
-                try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                    session.addPasswordIdentity(getCurrentTestName());
-                    session.auth().verify(5L, TimeUnit.SECONDS);
-
-                    ScpClient scp = createScpClient(session);
-                    Path targetPath = detectTargetFolder().toPath();
-                    Path parentPath = targetPath.getParent();
-                    Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-                    Utils.deleteRecursive(scpRoot);
-
-                    Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
-                    Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
-                    byte[] data = writeFile(local1, getCurrentTestName() + "\n");
-
-                    Path local2 = localDir.resolve(getCurrentTestName() + "-2.txt");
-                    Files.write(local2, data);
-
-                    Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-                    Path remote1 = remoteDir.resolve(local1.getFileName());
-                    String remote1Path = Utils.resolveRelativeRemotePath(parentPath, remote1);
-                    String[] locals = { local1.toString(), local2.toString() };
-                    try {
-                        scp.upload(locals, remote1Path);
-                        fail("Unexpected upload success to missing remote file: " + remote1Path);
-                    } catch (IOException e) {
-                        // Ok
-                    }
-                    
-                    Files.write(remote1, data);
-                    try {
-                        scp.upload(locals, remote1Path);
-                        fail("Unexpected upload success to existing remote file: " + remote1Path);
-                    } catch (IOException e) {
-                        // Ok
-                    }
-
-                    Path remoteSubDir = assertHierarchyTargetFolderExists(remoteDir.resolve("dir"));
-                    scp.upload(locals, Utils.resolveRelativeRemotePath(parentPath, remoteSubDir));
-                    
-                    Path remoteSub1 = remoteSubDir.resolve(local1.getFileName());
-                    assertFileLength(remoteSub1, data.length, 5000);
-
-                    Path remoteSub2 = remoteSubDir.resolve(local2.getFileName());
-                    assertFileLength(remoteSub2, data.length, 5000);
-
-                    String[] remotes = {
-                            Utils.resolveRelativeRemotePath(parentPath, remoteSub1),
-                            Utils.resolveRelativeRemotePath(parentPath, remoteSub2),
-                        };
-
-                    try {
-                        scp.download(remotes, Utils.resolveRelativeRemotePath(parentPath, local1));
-                        fail("Unexpected download success to existing local file: " + local1);
-                    } catch (IOException e) {
-                        // Ok
-                    }
-                    
-                    Path localSubDir = localDir.resolve("dir");
-                    try {
-                        scp.download(remotes, localSubDir);
-                        fail("Unexpected download success to non-existing folder: " + localSubDir);
-                    } catch (IOException e) {
-                        // Ok
-                    }
-
-                    Files.createDirectories(localSubDir);
-                    scp.download(remotes, localSubDir);
-
-                    assertFileLength(localSubDir.resolve(remoteSub1.getFileName()), data.length, 5000);
-                    assertFileLength(localSubDir.resolve(remoteSub2.getFileName()), data.length, 5000);
-                }
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testScpNativeOnRecursiveDirs() throws Exception {
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            client.start();
-
-            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                session.addPasswordIdentity(getCurrentTestName());
-                session.auth().verify(5L, TimeUnit.SECONDS);
-
-                ScpClient scp = createScpClient(session);
-                Path targetPath = detectTargetFolder().toPath();
-                Path parentPath = targetPath.getParent();
-                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-                Utils.deleteRecursive(scpRoot);
-
-                Path localDir = scpRoot.resolve("local");
-                Path localSubDir = assertHierarchyTargetFolderExists(localDir.resolve("dir"));
-                Path localSub1 = localSubDir.resolve(getCurrentTestName() + "-1.txt");
-                byte[] data = writeFile(localSub1, getCurrentTestName() + "\n");
-                Path localSub2 = localSubDir.resolve(getCurrentTestName() + "-2.txt");
-                Files.write(localSub2, data);
-
-                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-                scp.upload(localSubDir, Utils.resolveRelativeRemotePath(parentPath, remoteDir), ScpClient.Option.Recursive);
-                
-                Path remoteSubDir = remoteDir.resolve(localSubDir.getFileName());
-                assertFileLength(remoteSubDir.resolve(localSub1.getFileName()), data.length, 5000);
-                assertFileLength(remoteSubDir.resolve(localSub2.getFileName()), data.length, 5000);
-
-                Utils.deleteRecursive(localSubDir);
-
-                scp.download(Utils.resolveRelativeRemotePath(parentPath, remoteSubDir), localDir, ScpClient.Option.Recursive);
-                assertFileLength(localSub1, data.length, 5000);
-                assertFileLength(localSub2, data.length, 5000);
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testScpNativeOnDirWithPattern() throws Exception {
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            client.start();
-
-            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                session.addPasswordIdentity(getCurrentTestName());
-                session.auth().verify(5L, TimeUnit.SECONDS);
-
-                ScpClient scp = createScpClient(session);
-                Path targetPath = detectTargetFolder().toPath();
-                Path parentPath = targetPath.getParent();
-                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-                Utils.deleteRecursive(scpRoot);
-
-                Path localDir = assertHierarchyTargetFolderExists(scpRoot.resolve("local"));
-                Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
-                byte[] data = writeFile(local1, getCurrentTestName() + "\n");
-                Path local2 = localDir.resolve(getCurrentTestName() + "-2.txt");
-                Files.write(local2, data);
-
-                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-                String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteDir);
-                scp.upload(localDir.toString() + File.separator + "*", remotePath);
-                assertFileLength(remoteDir.resolve(local1.getFileName()), data.length, 5000);
-                assertFileLength(remoteDir.resolve(local2.getFileName()), data.length, 5000);
-
-                Files.delete(local1);
-                Files.delete(local2);
-                scp.download(remotePath + "/*", localDir);
-                assertFileLength(local1, data.length, 5000);
-                assertFileLength(local2, data.length, 5000);
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testScpNativeOnMixedDirAndFiles() throws Exception {
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            client.start();
-
-            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                session.addPasswordIdentity(getCurrentTestName());
-                session.auth().verify(5L, TimeUnit.SECONDS);
-
-                ScpClient scp = createScpClient(session);
-                Path targetPath = detectTargetFolder().toPath();
-                Path parentPath = targetPath.getParent();
-                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-                Utils.deleteRecursive(scpRoot);
-
-                Path localDir = scpRoot.resolve("local");
-                Path localSubDir = assertHierarchyTargetFolderExists(localDir.resolve("dir"));
-                Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
-                byte[] data = writeFile(local1, getCurrentTestName() + "\n");
-                Path localSub2 = localSubDir.resolve(getCurrentTestName() + "-2.txt");
-                Files.write(localSub2, data);
-
-                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-                String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteDir);
-                scp.upload(localDir.toString() + File.separator + "*", remotePath, ScpClient.Option.Recursive);
-                assertFileLength(remoteDir.resolve(local1.getFileName()), data.length, 5000);
-
-                Path remoteSubDir = remoteDir.resolve(localSubDir.getFileName());
-                assertFileLength(remoteSubDir.resolve(localSub2.getFileName()), data.length, 5000);
-
-                Files.delete(local1);
-                Utils.deleteRecursive(localSubDir);
-
-                scp.download(remotePath + "/*", localDir);
-                assertFileLength(local1, data.length, 5000);
-                assertFalse("Unexpected recursive local file: " + localSub2, Files.exists(localSub2));
-
-                Files.delete(local1);
-                scp.download(remotePath + "/*", localDir, ScpClient.Option.Recursive);
-                assertFileLength(local1, data.length, 5000);
-                assertFileLength(localSub2, data.length, 5000);
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testScpNativePreserveAttributes() throws Exception {
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            client.start();
-
-            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                session.addPasswordIdentity(getCurrentTestName());
-                session.auth().verify(5L, TimeUnit.SECONDS);
-
-                ScpClient scp = createScpClient(session);
-                Path targetPath = detectTargetFolder().toPath();
-                Path parentPath = targetPath.getParent();
-                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-                Utils.deleteRecursive(scpRoot);
-
-                Path localDir = scpRoot.resolve("local");
-                Path localSubDir = assertHierarchyTargetFolderExists(localDir.resolve("dir"));
-                // convert everything to seconds since this is the SCP timestamps granularity
-                long lastMod = TimeUnit.MILLISECONDS.toSeconds(Files.getLastModifiedTime(localSubDir).toMillis() - TimeUnit.DAYS.toMillis(1));
-                Path local1 = localDir.resolve(getCurrentTestName() + "-1.txt");
-                byte[] data = writeFile(local1, getCurrentTestName() + "\n");
-                File lclFile1 = local1.toFile();
-                lclFile1.setLastModified(lastMod);
-                lclFile1.setExecutable(true, true);
-                lclFile1.setWritable(false, false);
-
-                Path localSub2 = localSubDir.resolve(getCurrentTestName() + "-2.txt");
-                Files.write(localSub2, data);
-                File lclSubFile2 = localSub2.toFile();
-                lclSubFile2.setLastModified(lastMod);
-
-                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-                String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteDir);
-                scp.upload(localDir.toString() + File.separator + "*", remotePath, ScpClient.Option.Recursive, ScpClient.Option.PreserveAttributes);
-
-                Path remote1 = remoteDir.resolve(local1.getFileName());
-                assertFileLength(remote1, data.length, 5000);
-                
-                File remFile1 = remote1.toFile();
-                assertLastModifiedTimeEquals(remFile1, lastMod);
-
-                Path remoteSubDir = remoteDir.resolve(localSubDir.getFileName());
-                Path remoteSub2 = remoteSubDir.resolve(localSub2.getFileName());
-                assertFileLength(remoteSub2, data.length, 5000);
-
-                File remSubFile2 = remoteSub2.toFile();
-                assertLastModifiedTimeEquals(remSubFile2, lastMod);
-
-                Utils.deleteRecursive(localDir);
-                Files.createDirectories(localDir);
-
-                scp.download(remotePath + "/*", localDir, ScpClient.Option.Recursive, ScpClient.Option.PreserveAttributes);
-                assertFileLength(local1, data.length, 5000);
-                assertLastModifiedTimeEquals(lclFile1, lastMod);
-                assertFileLength(localSub2, data.length, 5000);
-                assertLastModifiedTimeEquals(lclSubFile2, lastMod);
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    @Test
-    public void testStreamsUploadAndDownload() throws Exception {
-        try (SshClient client = SshClient.setUpDefaultClient()) {
-            client.start();
-
-            try (ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
-                session.addPasswordIdentity(getCurrentTestName());
-                session.auth().verify(5L, TimeUnit.SECONDS);
-
-                ScpClient scp = createScpClient(session);
-                Path targetPath = detectTargetFolder().toPath();
-                Path parentPath = targetPath.getParent();
-                Path scpRoot = Utils.resolve(targetPath, ScpHelper.SCP_COMMAND_PREFIX, getClass().getSimpleName());
-                Utils.deleteRecursive(scpRoot);
-
-                Path remoteDir = assertHierarchyTargetFolderExists(scpRoot.resolve("remote"));
-                Path remoteFile = remoteDir.resolve(getCurrentTestName() + ".txt");
-                String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
-                byte[] data = (getClass().getName() + "#" + getCurrentTestName()).getBytes();
-                scp.upload(data, remotePath, EnumSet.allOf(PosixFilePermission.class), null);
-
-                byte[] uploaded = Files.readAllBytes(remoteFile);
-                assertArrayEquals("Mismatched uploaded data", data, uploaded);
-
-                byte[] downloaded = scp.downloadBytes(remotePath);
-                assertArrayEquals("Mismatched downloaded data", uploaded, downloaded);
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    // see http://stackoverflow.com/questions/2717936/file-createnewfile-creates-files-with-last-modified-time-before-actual-creatio
-    // See https://msdn.microsoft.com/en-us/library/ms724290(VS.85).aspx
-    // The NTFS file system delays updates to the last access time for a file by up to 1 hour after the last access
-    private static void assertLastModifiedTimeEquals(File file, long expectedSeconds) {
-        long actualSeconds = TimeUnit.MILLISECONDS.toSeconds(file.lastModified());
-        if (OsUtils.isWin32()) {
-            if (expectedSeconds != actualSeconds) {
-                System.err.append("Mismatched last modified time for ").append(file.getAbsolutePath())
-                          .append(" - expected=").append(String.valueOf(expectedSeconds))
-                          .append(", actual=").println(actualSeconds);
-            }
-        } else {
-            assertEquals("Mismatched last modified time for " + file.getAbsolutePath(), expectedSeconds, actualSeconds);
-        }
-    }
-
-    private static byte[] writeFile(Path path, String data) throws IOException {
-        try(OutputStream fos = Files.newOutputStream(path)) {
-            byte[]  bytes = data.getBytes();
-            fos.write(bytes);
-            return bytes;
-        }
-    }
-
-    @Test
-    public void testJschScp() throws Exception {
-        session = getJschSession();
-        try {
-            String data = getCurrentTestName() + "\n";
-    
-            String unixDir = "target/scp";
-            String fileName = getCurrentTestName() + ".txt";
-            String unixPath = unixDir + "/" + fileName;
-            File root = new File(unixDir);
-            File target = new File(unixPath);
-            Utils.deleteRecursive(root);
-            root.mkdirs();
-            assertTrue(root.exists());
-    
-            target.delete();
-            assertFalse(target.exists());
-            sendFile(unixPath, fileName, data);
-            assertFileLength(target, data.length(), 5000);
-    
-            target.delete();
-            assertFalse(target.exists());
-            sendFile(unixDir, fileName, data);
-            assertFileLength(target, data.length(), 5000);
-    
-            sendFileError("target", ScpHelper.SCP_COMMAND_PREFIX, data);
-    
-            readFileError(unixDir);
-    
-            assertEquals("Mismatched file data", data, readFile(unixPath, target.length()));
-            assertEquals("Mismatched dir data", data, readDir(unixDir, fileName, target.length()));
-    
-            target.delete();
-            root.delete();
-    
-            sendDir("target", ScpHelper.SCP_COMMAND_PREFIX, fileName, data);
-            assertFileLength(target, data.length(), 5000);
-        } finally {
-            session.disconnect();
-        }
-    }
-
-    @Test
-    public void testWithGanymede() throws Exception {
-        // begin client config
-        final Connection conn = new Connection("localhost", port);
-        try {
-            conn.connect(null, 5000, 0);
-            conn.authenticateWithPassword("sshd", "sshd");
-            final SCPClient scp_client = new SCPClient(conn);
-            final Properties props = new Properties();
-            props.setProperty("test", "test-passed");
-            File f = new File("target/scp/gan");
-            Utils.deleteRecursive(f);
-            f.mkdirs();
-            assertTrue(f.exists());
-    
-            String name = "test.properties";
-            scp_client.put(toBytes(props, ""), name, "target/scp/gan");
-            assertTrue(new File(f, name).exists());
-            assertTrue(new File(f, name).delete());
-    
-            name = "test2.properties";
-            scp_client.put(toBytes(props, ""), name, "target/scp/gan");
-            assertTrue(new File(f, name).exists());
-            assertTrue(new File(f, name).delete());
-    
-            assertTrue(f.delete());
-        } finally {
-            conn.close();
-        }
-    }
-
-    private byte[] toBytes(final Properties properties, final String comments) {
-        try(ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
-            properties.store(baos, comments);
-            baos.close();
-            return baos.toByteArray();
-        } catch(IOException cause) {
-            throw new RuntimeException("Failed to output properties to byte[]", cause);
-        }
-    }
-
-    protected String readFile(String path, long expectedSize) throws Exception {
-        ChannelExec c = (ChannelExec) session.openChannel("exec");
-        c.setCommand("scp -f " + path);
-        c.connect();
-
-        int namePos = path.lastIndexOf('/');
-        String fileName = (namePos >= 0) ? path.substring(namePos + 1) : path;
-        try(OutputStream os = c.getOutputStream();
-            InputStream is = c.getInputStream()) {
-
-            os.write(0);
-            os.flush();
-            String header = readLine(is);
-            assertEquals("Mismatched header for " + path, "C0644 " + expectedSize + " " + fileName, header);
-
-            int length = Integer.parseInt(header.substring(6, header.indexOf(' ', 6)));
-            os.write(0);
-            os.flush();
-    
-            byte[] buffer = new byte[length];
-            length = is.read(buffer, 0, buffer.length);
-            assertEquals("Mismatched read data length for " + path, length, buffer.length);
-            assertAckReceived(is, "Read data of " + path);
-
-            os.write(0);
-            os.flush();
-
-            return new String(buffer);
-        } finally {
-            c.disconnect();
-        }
-    }
-
-    protected String readDir(String path, String fileName, long expectedSize) throws Exception {
-        ChannelExec c = (ChannelExec) session.openChannel("exec");
-        c.setCommand("scp -r -f " + path);
-        c.connect();
-
-        try(OutputStream os = c.getOutputStream();
-            InputStream is = c.getInputStream()) {
-            os.write(0);
-            os.flush();
-
-            String header = readLine(is);
-            assertTrue("Bad header prefix for " + path + ": " + header, header.startsWith("D0755 0 "));
-            os.write(0);
-            os.flush();
-
-            header = readLine(is);
-            assertEquals("Mismatched dir header for " + path, "C0644 " + expectedSize + " " + fileName, header);
-            int length = Integer.parseInt(header.substring(6, header.indexOf(' ', 6)));
-            os.write(0);
-            os.flush();
-
-            byte[] buffer = new byte[length];
-            length = is.read(buffer, 0, buffer.length);
-            assertEquals("Mismatched read buffer size for " + path, length, buffer.length);
-            assertAckReceived(is, "Read date of " + path);
-
-            os.write(0);
-            os.flush();
-
-            header = readLine(is);
-            assertEquals("Mismatched end value for " + path, "E", header);
-            os.write(0);
-            os.flush();
-
-            return new String(buffer);
-        } finally {
-            c.disconnect();
-        }
-    }
-
-    protected String readFileError(String path) throws Exception {
-        ChannelExec c = (ChannelExec) session.openChannel("exec");
-        String command = "scp -f " + path; 
-        c.setCommand(command);
-        c.connect();
-
-        try(OutputStream os = c.getOutputStream();
-            InputStream is = c.getInputStream()) {
-        
-            os.write(0);
-            os.flush();
-            assertEquals("Mismatched response for command: " + command, 2, is.read());
-            return null;
-        } finally {
-            c.disconnect();
-        }
-    }
-
-    protected void sendFile(String path, String name, String data) throws Exception {
-        ChannelExec c = (ChannelExec) session.openChannel("exec");
-        String command = "scp -t " + path;
-        c.setCommand(command);
-        c.connect();
-
-        try(OutputStream os = c.getOutputStream();
-            InputStream is = c.getInputStream()) {
-
-            assertAckReceived(is, command);
-            assertAckReceived(os, is, "C7777 " + data.length() + " " + name); 
-
-            os.write(data.getBytes());
-            os.flush();
-            assertAckReceived(is, "Sent data (length=" + data.length() + ") for " + path + "[" + name + "]");
-
-            os.write(0);
-            os.flush();
-
-            Thread.sleep(100);
-        } finally {
-            c.disconnect();
-        }
-    }
-
-    protected void assertAckReceived(OutputStream os, InputStream is, String command) throws IOException {
-        os.write((command + "\n").getBytes());
-        os.flush();
-        assertAckReceived(is, command);
-    }
-
-    protected void assertAckReceived(InputStream is, String command) throws IOException {
-        assertEquals("No ACK for command=" + command, 0, is.read());
-    }
-
-    protected void sendFileError(String path, String name, String data) throws Exception {
-        ChannelExec c = (ChannelExec) session.openChannel("exec");
-        String command = "scp -t " + path; 
-        c.setCommand(command);
-        c.connect();
-
-        try(OutputStream os = c.getOutputStream();
-            InputStream is = c.getInputStream()) {
-
-            assertAckReceived(is, command);
-
-            command = "C7777 " + data.length() + " " + name;
-            os.write((command + "\n").getBytes());
-            os.flush();
-            assertEquals("Mismatched response for command=" + command, 2, is.read());
-        } finally {
-            c.disconnect();
-        }
-    }
-
-    protected void sendDir(String path, String dirName, String fileName, String data) throws Exception {
-        ChannelExec c = (ChannelExec) session.openChannel("exec");
-        String command = "scp -t -r " + path;
-        c.setCommand(command);
-        c.connect();
-        
-        try(OutputStream os = c.getOutputStream();
-            InputStream is = c.getInputStream()) {
-
-            assertAckReceived(is, command);
-            assertAckReceived(os, is, "D0755 0 " + dirName);
-            assertAckReceived(os, is, "C7777 " + data.length() + " " + fileName);
-
-            os.write(data.getBytes());
-            os.flush();
-            assertAckReceived(is, "Send data of " + path);
-
-            os.write(0);
-            os.flush();
-            
-            os.write("E\n".getBytes());
-            os.flush();
-            assertAckReceived(is, "Signal end of " + path);
-        } finally {
-            c.disconnect();
-        }
-    }
-
-    private static String readLine(InputStream in) throws IOException {
-        OutputStream baos = new ByteArrayOutputStream();
-        try {
-            for (; ; ) {
-                int c = in.read();
-                if (c == '\n') {
-                    return baos.toString();
-                } else if (c == -1) {
-                    throw new IOException("End of stream");
-                } else {
-                    baos.write(c);
-                }
-            }
-        } finally {
-            baos.close();
-        }
-    }
-
-    private ScpClient createScpClient(ClientSession session) {
-        final Logger logger = LoggerFactory.getLogger(getClass().getName() + "[" + getCurrentTestName() + "]");
-        return session.createScpClient(new ScpTransferEventListener() {
-            @Override
-            public void startFolderEvent(FileOperation op, Path file, Set<PosixFilePermission> perms) {
-                logEvent("starFolderEvent", op, file, false, -1L, perms, null);
-            }
-
-            @Override
-            public void startFileEvent(FileOperation op, Path file, long length, Set<PosixFilePermission> perms) {
-                logEvent("startFileEvent", op, file, true, length, perms, null);
-
-            }
-
-            @Override
-            public void endFolderEvent(FileOperation op, Path file, Set<PosixFilePermission> perms, Throwable thrown) {
-                logEvent("endFolderEvent", op, file, false, -1L, perms, thrown);
-            }
-
-            @Override
-            public void endFileEvent(FileOperation op, Path file, long length, Set<PosixFilePermission> perms, Throwable thrown) {
-                logEvent("endFileEvent", op, file, true, length, perms, thrown);
-            }
-
-            private void logEvent(String type, FileOperation op, Path path, boolean isFile, long length, Collection<PosixFilePermission> perms, Throwable t) {
-                StringBuilder sb = new StringBuilder(Byte.MAX_VALUE);
-                sb.append('\t').append(type)
-                        .append('[').append(op).append(']')
-                        .append(' ').append(isFile ? "File" : "Directory").append('=').append(path)
-                        .append(' ').append("length=").append(length)
-                        .append(' ').append("perms=").append(perms)
-                ;
-                if (t != null) {
-                    sb.append(' ').append("ERROR=").append(t.getClass().getSimpleName()).append(": ").append(t.getMessage());
-                }
-                logger.info(sb.toString());
-            }
-        });
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/client/kex/KexTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/kex/KexTest.java b/sshd-core/src/test/java/org/apache/sshd/client/kex/KexTest.java
index 1edc936..588cca1 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/kex/KexTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/kex/KexTest.java
@@ -62,7 +62,7 @@ public class KexTest extends BaseTestSupport {
         sshd = SshServer.setUpDefaultServer();
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.start();
         port  = sshd.getPort();
     }
@@ -111,8 +111,8 @@ public class KexTest extends BaseTestSupport {
                 client.setKeyExchangeFactories(Collections.singletonList(kex));
                 client.start();
                 
-                try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-                    session.addPasswordIdentity("smx");
+                try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                    session.addPasswordIdentity(getCurrentTestName());
                     session.auth().verify(5L, TimeUnit.SECONDS);
                     
                     try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);


[4/4] mina-sshd git commit: [SSHD-481] Avoid (re-)creation of bogus test class instances

Posted by lg...@apache.org.
[SSHD-481] Avoid (re-)creation of bogus test class instances


Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/330d17c8
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/330d17c8
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/330d17c8

Branch: refs/heads/master
Commit: 330d17c815458ba87e62e4e3e25df222a3aadec9
Parents: 009d832
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Mon Jun 1 16:02:46 2015 +0300
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Mon Jun 1 16:02:46 2015 +0300

----------------------------------------------------------------------
 .../java/org/apache/sshd/client/UserAuth.java   |   4 +-
 .../auth/UserAuthKeyboardInteractive.java       |   3 +-
 .../sshd/client/auth/UserAuthPassword.java      |   3 +-
 .../sshd/client/auth/UserAuthPublicKey.java     |  14 +-
 .../sshd/client/future/DefaultAuthFuture.java   |   3 +-
 .../client/session/ClientUserAuthService.java   |   5 +-
 .../session/AbstractConnectionService.java      |   2 +-
 .../sshd/server/PasswordAuthenticator.java      |   7 +-
 .../sshd/server/PublickeyAuthenticator.java     |   8 +-
 .../AbstractGeneratorHostKeyProvider.java       |   4 +-
 .../test/java/org/apache/sshd/AgentTest.java    |  10 +-
 .../org/apache/sshd/AuthenticationTest.java     |  24 +-
 .../test/java/org/apache/sshd/CipherTest.java   |   6 +-
 .../test/java/org/apache/sshd/ClientTest.java   | 105 +-
 .../test/java/org/apache/sshd/EcdsaTest.java    |  20 +-
 .../java/org/apache/sshd/KeepAliveTest.java     |  30 +-
 .../java/org/apache/sshd/KeyReExchangeTest.java |  14 +-
 .../src/test/java/org/apache/sshd/LoadTest.java |   2 +-
 .../src/test/java/org/apache/sshd/MacTest.java  |   6 +-
 .../org/apache/sshd/PortForwardingLoadTest.java |   2 +-
 .../org/apache/sshd/PortForwardingTest.java     |   2 +-
 .../test/java/org/apache/sshd/ProxyTest.java    |   2 +-
 .../test/java/org/apache/sshd/ServerTest.java   |   8 +-
 .../apache/sshd/SinglePublicKeyAuthTest.java    |  22 +-
 .../java/org/apache/sshd/SpringConfigTest.java  |   4 +-
 .../java/org/apache/sshd/SshServerTest.java     |   2 +-
 .../java/org/apache/sshd/WelcomeBannerTest.java |  10 +-
 .../java/org/apache/sshd/WindowAdjustTest.java  |   2 +-
 .../test/java/org/apache/sshd/WindowTest.java   |  18 +-
 .../java/org/apache/sshd/client/ScpTest.java    | 982 -------------------
 .../org/apache/sshd/client/kex/KexTest.java     |   6 +-
 .../org/apache/sshd/client/scp/ScpTest.java     | 982 +++++++++++++++++++
 .../sshd/client/sftp/SftpFileSystemTest.java    |   2 +-
 .../org/apache/sshd/client/sftp/SftpTest.java   |   2 +-
 .../common/compression/CompressionTest.java     |   6 +-
 .../org/apache/sshd/util/BaseTestSupport.java   |   8 +-
 .../sshd/util/BogusPasswordAuthenticator.java   |  15 +-
 .../sshd/util/BogusPublickeyAuthenticator.java  |  37 -
 .../test/java/org/apache/sshd/util/Utils.java   |  61 +-
 sshd-core/src/test/resources/spring.xml         |   2 +-
 .../sshd/git/pack/GitPackCommandFactory.java    |   1 +
 .../sshd/git/pgm/EmbeddedCommandRunner.java     |   9 +-
 .../sshd/git/pgm/GitPgmCommandFactory.java      |   1 +
 .../git/transport/GitSshdSessionFactory.java    |   7 +-
 .../sshd/git/pack/GitPackCommandTest.java       |   9 +-
 .../apache/sshd/git/pgm/GitPgmCommandTest.java  |  12 +-
 .../git/util/BogusPasswordAuthenticator.java    |   6 +
 .../apache/sshd/git/util/EchoShellFactory.java  |   8 +
 48 files changed, 1275 insertions(+), 1223 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/client/UserAuth.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/UserAuth.java b/sshd-core/src/main/java/org/apache/sshd/client/UserAuth.java
index 7f864ac..a5dd185 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/UserAuth.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/UserAuth.java
@@ -18,7 +18,7 @@
  */
 package org.apache.sshd.client;
 
-import java.util.List;
+import java.util.Collection;
 
 import org.apache.sshd.ClientSession;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -30,7 +30,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
  */
 public interface UserAuth {
 
-    void init(ClientSession session, String service, List<Object> identities) throws Exception;
+    void init(ClientSession session, String service, Collection<?> identities) throws Exception;
 
     boolean process(Buffer buffer) throws Exception;
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java
index 241381b..ea8815b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java
@@ -23,6 +23,7 @@ import static org.apache.sshd.common.SshConstants.SSH_MSG_USERAUTH_INFO_RESPONSE
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 
@@ -72,7 +73,7 @@ public class UserAuthKeyboardInteractive extends AbstractLoggingBean implements
     }
 
     @Override
-    public void init(ClientSession session, String service, List<Object> identities) throws Exception {
+    public void init(ClientSession session, String service, Collection<?> identities) throws Exception {
         this.session = session;
         this.service = service;
         List<String> pwds = new ArrayList<String>();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java
index 0754014..35844e3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java
@@ -19,6 +19,7 @@
 package org.apache.sshd.client.auth;
 
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 
@@ -63,7 +64,7 @@ public class UserAuthPassword extends AbstractLoggingBean implements UserAuth {
     }
 
     @Override
-    public void init(ClientSession session, String service, List<Object> identities) throws Exception {
+    public void init(ClientSession session, String service, Collection<?> identities) throws Exception {
         this.session = session;
         this.service = service;
         List<String> pwds = new ArrayList<String>();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
index 238fdc5..d3a0279 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
@@ -24,6 +24,7 @@ import java.io.IOException;
 import java.security.KeyPair;
 import java.security.PublicKey;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 
@@ -76,7 +77,7 @@ public class UserAuthPublicKey extends AbstractLoggingBean implements UserAuth {
     }
 
     @Override
-    public void init(ClientSession session, String service, List<Object> identities) throws Exception {
+    public void init(ClientSession session, String service, Collection<?> identities) throws Exception {
         this.session = session;
         this.service = service;
         List<PublicKeyIdentity> ids = new ArrayList<PublicKeyIdentity>();
@@ -85,19 +86,22 @@ public class UserAuthPublicKey extends AbstractLoggingBean implements UserAuth {
                 ids.add(new KeyPairIdentity(session.getFactoryManager(), (KeyPair) o));
             }
         }
-        SshAgentFactory factory = session.getFactoryManager().getAgentFactory();
+        
+        FactoryManager manager = session.getFactoryManager();
+        SshAgentFactory factory = manager.getAgentFactory();
         if (factory != null) {
-            this.agent = factory.createClient(session.getFactoryManager());
+            this.agent = factory.createClient(manager);
             for (SshAgent.Pair<PublicKey, String> pair : agent.getIdentities()) {
                 ids.add(new KeyAgentIdentity(agent, pair.getFirst()));
             }
         } else {
             this.agent = null;
         }
-        KeyPairProvider provider = session.getFactoryManager().getKeyPairProvider();
+
+        KeyPairProvider provider = manager.getKeyPairProvider();
         if (provider != null) {
             for (KeyPair pair : provider.loadKeys()) {
-                ids.add(new KeyPairIdentity(session.getFactoryManager(), pair));
+                ids.add(new KeyPairIdentity(manager, pair));
             }
         }
         this.keys = ids.iterator();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java b/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java
index d79cbb1..a9043d4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java
@@ -30,7 +30,7 @@ import org.apache.sshd.common.future.DefaultSshFuture;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class DefaultAuthFuture extends DefaultSshFuture<AuthFuture> implements AuthFuture {
-    public DefaultAuthFuture( Object lock) {
+    public DefaultAuthFuture(Object lock) {
         super(lock);
     }
 
@@ -93,5 +93,4 @@ public class DefaultAuthFuture extends DefaultSshFuture<AuthFuture> implements A
         }
         setValue(exception);
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
index d36251f..3f955a4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
@@ -221,8 +221,9 @@ public class ClientUserAuthService extends CloseableUtils.AbstractCloseable impl
                 return;
             }
             String method = clientMethods.get(currentMethod);
-            userAuth = NamedFactory.Utils.create(authFactories, method);
-            assert userAuth != null;
+            if ((userAuth = NamedFactory.Utils.create(authFactories, method)) == null) {
+                throw new UnsupportedOperationException("Failed to find a user-auth factory for method=" + method);
+            }
             userAuth.init(session, service, identities);
         }
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
index efab024..9833411 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
@@ -127,7 +127,7 @@ public abstract class AbstractConnectionService extends CloseableUtils.AbstractI
         channel.init(this, session, channelId);
         synchronized (lock) {
             if (isClosing()) {
-                throw new IllegalStateException("Session is being closed");
+                throw new IllegalStateException("Session is being closed: " + toString());
             }
             channels.put(Integer.valueOf(channelId), channel);
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/server/PasswordAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/PasswordAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/PasswordAuthenticator.java
index f1fd0b5..9f44851 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/PasswordAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/PasswordAuthenticator.java
@@ -31,8 +31,6 @@ public interface PasswordAuthenticator {
 
     /**
      * Check the validity of a password.
-     * This method should return null if the authentication fails.
-     *
      * @param username the username
      * @param password the password
      * @param session the server session
@@ -56,11 +54,12 @@ public interface PasswordAuthenticator {
 
         @Override
         public final boolean authenticate(String username, String password, ServerSession session) {
+            boolean accepted = isAccepted();
             if (log.isDebugEnabled()) {
-                log.debug("authenticate({}[{}]: {}", username, session, Boolean.valueOf(isAccepted()));
+                log.debug("authenticate({}[{}]: {}", username, session, Boolean.valueOf(accepted));
             }
             
-            return isAccepted();
+            return accepted;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/server/PublickeyAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/PublickeyAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/PublickeyAuthenticator.java
index 276087e..78c8adf 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/PublickeyAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/PublickeyAuthenticator.java
@@ -34,7 +34,6 @@ public interface PublickeyAuthenticator {
 
     /**
      * Check the validity of a public key.
-     *
      * @param username the username
      * @param key the key
      * @param session the server session
@@ -58,12 +57,13 @@ public interface PublickeyAuthenticator {
 
         @Override
         public final boolean authenticate(String username, PublicKey key, ServerSession session) {
+            boolean accepted = isAccepted();
             if (log.isDebugEnabled()) {
-                log.debug("authenticate({}[{}][[]]: {}",
-                          new Object[] { username, session, key.getAlgorithm(), KeyUtils.getFingerPrint(key), Boolean.valueOf(isAccepted()) });
+                log.debug("authenticate({}[{}][{}][{}]: {}",
+                          username, session, key.getAlgorithm(), KeyUtils.getFingerPrint(key), Boolean.valueOf(accepted));
             }
 
-            return isAccepted();
+            return accepted;
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
index 705f292..c6bafd3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
@@ -128,9 +128,9 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr
 
         if (keyPair == null) {
             return Collections.emptyList();
+        } else {
+            return Collections.singleton(keyPair);
         }
-
-        return Collections.singleton(keyPair);
     }
 
     private KeyPair readKeyPair(File f) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/AgentTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/AgentTest.java b/sshd-core/src/test/java/org/apache/sshd/AgentTest.java
index d7e4fbc..0c6ad20 100644
--- a/sshd-core/src/test/java/org/apache/sshd/AgentTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/AgentTest.java
@@ -38,9 +38,9 @@ import org.apache.sshd.common.keyprovider.KeyPairProvider;
 import org.apache.sshd.common.util.SecurityUtils;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.Environment;
+import org.apache.sshd.server.PublickeyAuthenticator.AcceptAllPublickeyAuthenticator;
 import org.apache.sshd.util.BaseTestSupport;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
-import org.apache.sshd.util.BogusPublickeyAuthenticator;
 import org.apache.sshd.util.EchoShellFactory;
 import org.apache.sshd.util.Utils;
 import org.junit.Assume;
@@ -102,8 +102,8 @@ public class AgentTest extends BaseTestSupport {
         try(SshServer sshd1 = SshServer.setUpDefaultServer()) {
             sshd1.setKeyPairProvider(Utils.createTestHostKeyProvider());
             sshd1.setShellFactory(shellFactory);
-            sshd1.setPasswordAuthenticator(new BogusPasswordAuthenticator());
-            sshd1.setPublickeyAuthenticator(new BogusPublickeyAuthenticator());
+            sshd1.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
+            sshd1.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
             sshd1.setAgentFactory(agentFactory);
             sshd1.start();
             int port1 = sshd1.getPort();
@@ -111,8 +111,8 @@ public class AgentTest extends BaseTestSupport {
             try(SshServer sshd2 = SshServer.setUpDefaultServer()) {
                 sshd2.setKeyPairProvider(Utils.createTestHostKeyProvider());
                 sshd2.setShellFactory(new TestEchoShellFactory());
-                sshd2.setPasswordAuthenticator(new BogusPasswordAuthenticator());
-                sshd2.setPublickeyAuthenticator(new BogusPublickeyAuthenticator());
+                sshd2.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
+                sshd2.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
                 sshd2.setAgentFactory(new ProxyAgentFactory());
                 sshd2.start();
                 int port2 = sshd2.getPort();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/AuthenticationTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/AuthenticationTest.java b/sshd-core/src/test/java/org/apache/sshd/AuthenticationTest.java
index 937d22a..b249bbe 100644
--- a/sshd-core/src/test/java/org/apache/sshd/AuthenticationTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/AuthenticationTest.java
@@ -33,12 +33,12 @@ import org.apache.sshd.deprecated.ClientUserAuthServiceOld;
 import org.apache.sshd.deprecated.UserAuthKeyboardInteractive;
 import org.apache.sshd.deprecated.UserAuthPassword;
 import org.apache.sshd.deprecated.UserAuthPublicKey;
+import org.apache.sshd.server.PublickeyAuthenticator.AcceptAllPublickeyAuthenticator;
 import org.apache.sshd.server.ServerFactoryManager;
 import org.apache.sshd.server.session.ServerSession;
 import org.apache.sshd.server.session.SessionFactory;
 import org.apache.sshd.util.BaseTestSupport;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
-import org.apache.sshd.util.BogusPublickeyAuthenticator;
 import org.apache.sshd.util.Utils;
 import org.junit.After;
 import org.junit.Before;
@@ -55,8 +55,8 @@ public class AuthenticationTest extends BaseTestSupport {
     public void setUp() throws Exception {
         sshd = SshServer.setUpDefaultServer();
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
-        sshd.setPublickeyAuthenticator(new BogusPublickeyAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
+        sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
         sshd.getProperties().put(ServerFactoryManager.WELCOME_BANNER, WELCOME);
         sshd.getProperties().put(ServerFactoryManager.AUTH_METHODS, "publickey,password publickey,keyboard-interactive");
         sshd.setSessionFactory(new SessionFactory() {
@@ -89,12 +89,12 @@ public class AuthenticationTest extends BaseTestSupport {
             try(ClientSession s = client.connect(null, "localhost", port).await().getSession()) {
                 s.waitFor(ClientSession.CLOSED | ClientSession.WAIT_AUTH, 0);
         
-                assertFalse(authPassword(s, "user1", "the-password").await().isSuccess());
-                assertFalse(authPassword(s, "user2", "the-password").await().isSuccess());
+                assertFalse("Unexpected user1 password auth success", authPassword(s, "user1", "the-password").await().isSuccess());
+                assertFalse("Unexpected user2 password auth success", authPassword(s, "user2", "the-password").await().isSuccess());
         
                 // Note that WAIT_AUTH flag should be false, but since the internal
                 // authentication future is not updated, it's still returned
-                assertEquals(ClientSession.CLOSED | ClientSession.WAIT_AUTH, s.waitFor(ClientSession.CLOSED, 1000));
+                assertEquals("Mismatched client session close mask", ClientSession.CLOSED | ClientSession.WAIT_AUTH, s.waitFor(ClientSession.CLOSED, 1000));
             } finally {
                 client.stop();
             }
@@ -113,7 +113,7 @@ public class AuthenticationTest extends BaseTestSupport {
             try(ClientSession s = client.connect(null, "localhost", port).await().getSession()) {
                 s.waitFor(ClientSession.CLOSED | ClientSession.WAIT_AUTH, 0);
         
-                assertFalse(authPassword(s, "smx", "smx").await().isSuccess());
+                assertFalse("Unexpected password auth sucess", authPassword(s, getCurrentTestName(), getCurrentTestName()).await().isSuccess());
         
                 s.close(true);
             } finally {
@@ -135,9 +135,8 @@ public class AuthenticationTest extends BaseTestSupport {
                 s.waitFor(ClientSession.CLOSED | ClientSession.WAIT_AUTH, 0);
         
                 KeyPair pair = Utils.createTestHostKeyProvider().loadKey(KeyPairProvider.SSH_RSA);
-                assertFalse(authPublicKey(s, "smx", pair).await().isSuccess());
-        
-                assertTrue(authPassword(s, "smx", "smx").await().isSuccess());
+                assertFalse("Unexpected pubkey auth success", authPublicKey(s, getCurrentTestName(), pair).await().isSuccess());
+                assertTrue("Failed password auth", authPassword(s, getCurrentTestName(), getCurrentTestName()).await().isSuccess());
                 s.close(true);
             } finally {
                 client.stop();
@@ -158,9 +157,8 @@ public class AuthenticationTest extends BaseTestSupport {
                 s.waitFor(ClientSession.CLOSED | ClientSession.WAIT_AUTH, 0);
         
                 KeyPair pair = Utils.createTestHostKeyProvider().loadKey(KeyPairProvider.SSH_RSA);
-                assertFalse(authPublicKey(s, "smx", pair).await().isSuccess());
-        
-                assertTrue(authInteractive(s, "smx", "smx").await().isSuccess());
+                assertFalse("Unexpected pubkey auth success", authPublicKey(s, getCurrentTestName(), pair).await().isSuccess());
+                assertTrue("Failed password auth", authInteractive(s, getCurrentTestName(), getCurrentTestName()).await().isSuccess());
         
                 s.close(true);
             } finally {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/CipherTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/CipherTest.java b/sshd-core/src/test/java/org/apache/sshd/CipherTest.java
index eb200a9..9eb5d84 100644
--- a/sshd-core/src/test/java/org/apache/sshd/CipherTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/CipherTest.java
@@ -124,7 +124,7 @@ public class CipherTest extends BaseTestSupport {
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setCipherFactories(Arrays.<NamedFactory<org.apache.sshd.common.Cipher>>asList(cipher));
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.start();
         port = sshd.getPort();
     }
@@ -141,8 +141,8 @@ public class CipherTest extends BaseTestSupport {
         JSch sch = new JSch();
         JSch.setConfig("cipher.s2c", "aes128-cbc,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,none");
         JSch.setConfig("cipher.c2s", "aes128-cbc,3des-cbc,blowfish-cbc,aes192-cbc,aes256-cbc,none");
-        com.jcraft.jsch.Session s = sch.getSession("smx", "localhost", port);
-        s.setUserInfo(new SimpleUserInfo("smx"));
+        com.jcraft.jsch.Session s = sch.getSession(getCurrentTestName(), "localhost", port);
+        s.setUserInfo(new SimpleUserInfo(getCurrentTestName()));
         s.connect();
         com.jcraft.jsch.Channel c = s.openChannel("shell");
         c.connect();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/ClientTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/ClientTest.java b/sshd-core/src/test/java/org/apache/sshd/ClientTest.java
index 121de96..4906f2e 100644
--- a/sshd-core/src/test/java/org/apache/sshd/ClientTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/ClientTest.java
@@ -74,6 +74,7 @@ import org.apache.sshd.common.util.io.NoCloseOutputStream;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.CommandFactory;
 import org.apache.sshd.server.PublickeyAuthenticator;
+import org.apache.sshd.server.PublickeyAuthenticator.AcceptAllPublickeyAuthenticator;
 import org.apache.sshd.server.channel.ChannelSession;
 import org.apache.sshd.server.command.UnknownCommand;
 import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
@@ -83,7 +84,6 @@ import org.apache.sshd.server.session.ServerUserAuthService;
 import org.apache.sshd.util.AsyncEchoShellFactory;
 import org.apache.sshd.util.BaseTestSupport;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
-import org.apache.sshd.util.BogusPublickeyAuthenticator;
 import org.apache.sshd.util.EchoShellFactory;
 import org.apache.sshd.util.TeeOutputStream;
 import org.apache.sshd.util.Utils;
@@ -104,6 +104,10 @@ public class ClientTest extends BaseTestSupport {
     private CountDownLatch authLatch;
     private CountDownLatch channelLatch;
 
+    public ClientTest() {
+        super();
+    }
+
     @Before
     public void setUp() throws Exception {
         authLatch = new CountDownLatch(0);
@@ -118,8 +122,8 @@ public class ClientTest extends BaseTestSupport {
                 return new UnknownCommand(command);
             }
         });
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
-        sshd.setPublickeyAuthenticator(new BogusPublickeyAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
+        sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
         sshd.setServiceFactories(Arrays.asList(
                 new ServerUserAuthService.Factory() {
                     @Override
@@ -178,14 +182,14 @@ public class ClientTest extends BaseTestSupport {
 
     @Test
     public void testAsyncClient() throws Exception {
-        sshd.getProperties().put(FactoryManager.WINDOW_SIZE, "1024");
+        FactoryManagerUtils.updateProperty(sshd, FactoryManager.WINDOW_SIZE, 1024);
         sshd.setShellFactory(new AsyncEchoShellFactory());
 
-        client.getProperties().put(FactoryManager.WINDOW_SIZE, "1024");
+        FactoryManagerUtils.updateProperty(client, FactoryManager.WINDOW_SIZE, 1024);
         client.start();
 
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
 
             try(final ChannelShell channel = session.createShellChannel()) {
@@ -275,8 +279,9 @@ public class ClientTest extends BaseTestSupport {
     @Test
     public void testCommandDeadlock() throws Exception {
         client.start();
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
             
             try(ChannelExec channel = session.createExecChannel("test");
@@ -307,8 +312,8 @@ public class ClientTest extends BaseTestSupport {
     public void testClient() throws Exception {
         client.start();
 
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
             
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
@@ -356,8 +361,8 @@ public class ClientTest extends BaseTestSupport {
     public void testClientInverted() throws Exception {
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
             
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
@@ -400,8 +405,8 @@ public class ClientTest extends BaseTestSupport {
     public void testClientWithCustomChannel() throws Exception {
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
     
             try(ChannelShell channel = new ChannelShell();
@@ -424,8 +429,8 @@ public class ClientTest extends BaseTestSupport {
     public void testClientClosingStream() throws Exception {
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
     
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
@@ -473,8 +478,8 @@ public class ClientTest extends BaseTestSupport {
 //        sshd.getProperties().put(SshServer.MAX_PACKET_SIZE, Integer.toString(0x1000));
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
 
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
@@ -528,8 +533,8 @@ public class ClientTest extends BaseTestSupport {
     public void testOpenChannelOnClosedSession() throws Exception {
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
             
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL)) {
@@ -554,8 +559,8 @@ public class ClientTest extends BaseTestSupport {
         authLatch = new CountDownLatch(1);
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
 
             AuthFuture authFuture = session.auth();
             CloseFuture closeFuture = session.close(false);
@@ -573,8 +578,8 @@ public class ClientTest extends BaseTestSupport {
     public void testCloseCleanBeforeChannelOpened() throws Exception {
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
 
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
@@ -603,8 +608,8 @@ public class ClientTest extends BaseTestSupport {
         channelLatch = new CountDownLatch(1);
         client.start();
 
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
 
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
@@ -633,7 +638,7 @@ public class ClientTest extends BaseTestSupport {
     public void testPublicKeyAuth() throws Exception {
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
             KeyPair pair = Utils.createTestHostKeyProvider().loadKey(KeyPairProvider.SSH_RSA);
             session.addPublicKeyIdentity(pair);
             session.auth().verify(5L, TimeUnit.SECONDS);
@@ -647,7 +652,7 @@ public class ClientTest extends BaseTestSupport {
         client.setUserAuthFactories(Arrays.<NamedFactory<UserAuth>>asList(UserAuthPublicKey.UserAuthPublicKeyFactory.INSTANCE));
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
             session.addPublicKeyIdentity(Utils.createTestHostKeyProvider().loadKey(KeyPairProvider.SSH_RSA));
             session.auth().verify(5L, TimeUnit.SECONDS);
         } finally {
@@ -667,7 +672,7 @@ public class ClientTest extends BaseTestSupport {
         client.setUserAuthFactories(Arrays.<NamedFactory<UserAuth>>asList(UserAuthPublicKey.UserAuthPublicKeyFactory.INSTANCE));
         client.start();
 
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
             session.addPublicKeyIdentity(new SimpleGeneratorHostKeyProvider(null, "RSA").loadKey(KeyPairProvider.SSH_RSA));
             session.addPublicKeyIdentity(pair);
             session.auth().verify(5L, TimeUnit.SECONDS);
@@ -681,8 +686,8 @@ public class ClientTest extends BaseTestSupport {
         client.setUserAuthFactories(Arrays.<NamedFactory<UserAuth>>asList(new UserAuthPassword.UserAuthPasswordFactory()));
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
         } finally {
             client.stop();
@@ -694,9 +699,9 @@ public class ClientTest extends BaseTestSupport {
         client.setUserAuthFactories(Arrays.<NamedFactory<UserAuth>>asList(new UserAuthPassword.UserAuthPasswordFactory()));
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("bad");
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getClass().getSimpleName());
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
         } finally {
             client.stop();
@@ -708,8 +713,8 @@ public class ClientTest extends BaseTestSupport {
         client.setUserAuthFactories(Arrays.<NamedFactory<UserAuth>>asList(UserAuthKeyboardInteractive.UserAuthKeyboardInteractiveFactory.INSTANCE));
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
         } finally {
             client.stop();
@@ -721,9 +726,9 @@ public class ClientTest extends BaseTestSupport {
         client.setUserAuthFactories(Arrays.<NamedFactory<UserAuth>>asList(UserAuthKeyboardInteractive.UserAuthKeyboardInteractiveFactory.INSTANCE));
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("bad");
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getClass().getSimpleName());
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
         } finally {
             client.stop();
@@ -750,7 +755,7 @@ public class ClientTest extends BaseTestSupport {
         });
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
             AuthFuture future = session.auth();
             future.await();
             assertTrue("Unexpected authentication success", future.isFailure());
@@ -770,7 +775,7 @@ public class ClientTest extends BaseTestSupport {
                         .<NamedFactory<UserAuth>> asList(UserAuthKeyboardInteractive.UserAuthKeyboardInteractiveFactory.INSTANCE));
         client.start();
 
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
             session.setUserInteraction(new UserInteraction() {
                     @Override
                     public void welcome(String banner) {
@@ -781,7 +786,7 @@ public class ClientTest extends BaseTestSupport {
                     public String[] interactive(String destination, String name, String instruction,
                                                 String[] prompt, boolean[] echo) {
                         count.incrementAndGet();
-                        return new String[] { "smx" };
+                        return new String[] { getCurrentTestName() };
                     }
                 });
             AuthFuture future = session.auth();
@@ -803,7 +808,7 @@ public class ClientTest extends BaseTestSupport {
                         .<NamedFactory<UserAuth>> asList(new UserAuthKeyboardInteractive.UserAuthKeyboardInteractiveFactory()));
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
             session.setUserInteraction(new UserInteraction() {
                 @Override
                 public void welcome(String banner) {
@@ -832,8 +837,8 @@ public class ClientTest extends BaseTestSupport {
         try {
             client.start();
             
-            try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-                session.addPasswordIdentity("smx");
+            try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
                 session.auth().verify(5L, TimeUnit.SECONDS);
                 
                 try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
@@ -886,8 +891,8 @@ public class ClientTest extends BaseTestSupport {
         );
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.waitFor(ClientSession.WAIT_AUTH, 10000);
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.waitFor(ClientSession.WAIT_AUTH, TimeUnit.SECONDS.toMillis(10L));
             assertTrue(ok.get());
         } finally {
             client.stop();
@@ -900,8 +905,8 @@ public class ClientTest extends BaseTestSupport {
         client.getCipherFactories().add(BuiltinCiphers.none);
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
             session.switchToNoneCipher().await();
     

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/EcdsaTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/EcdsaTest.java b/sshd-core/src/test/java/org/apache/sshd/EcdsaTest.java
index 1111d28..c3864db 100644
--- a/sshd-core/src/test/java/org/apache/sshd/EcdsaTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/EcdsaTest.java
@@ -20,7 +20,6 @@ package org.apache.sshd;
 
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
-import java.security.PublicKey;
 import java.security.SecureRandom;
 import java.security.spec.ECGenParameterSpec;
 import java.util.Arrays;
@@ -33,8 +32,7 @@ import org.apache.sshd.common.Signature;
 import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
 import org.apache.sshd.common.signature.BuiltinSignatures;
 import org.apache.sshd.common.util.SecurityUtils;
-import org.apache.sshd.server.PublickeyAuthenticator;
-import org.apache.sshd.server.session.ServerSession;
+import org.apache.sshd.server.PublickeyAuthenticator.AcceptAllPublickeyAuthenticator;
 import org.apache.sshd.util.BaseTestSupport;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
 import org.apache.sshd.util.Utils;
@@ -58,7 +56,7 @@ public class EcdsaTest extends BaseTestSupport {
     public void setUp() throws Exception {
         sshd = SshServer.setUpDefaultServer();
 //        sshd.setShellFactory(new TestEchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.setSessionFactory(new org.apache.sshd.server.session.SessionFactory());
     }
 
@@ -98,8 +96,8 @@ public class EcdsaTest extends BaseTestSupport {
                 BuiltinSignatures.nistp384,
                 BuiltinSignatures.nistp521));
         client.start();
-        try(ClientSession s = client.connect("smx", "localhost", port).await().getSession()) {
-            s.addPasswordIdentity("smx");
+        try(ClientSession s = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            s.addPasswordIdentity(getCurrentTestName());
             s.auth().verify(5L, TimeUnit.SECONDS);
         } finally {
             client.stop();
@@ -114,21 +112,15 @@ public class EcdsaTest extends BaseTestSupport {
         generator.initialize(ecGenSpec, new SecureRandom());
         KeyPair kp = generator.generateKeyPair();
 
-
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setPublickeyAuthenticator(new PublickeyAuthenticator() {
-            @Override
-            public boolean authenticate(String username, PublicKey key, ServerSession session) {
-                return true;
-            }
-        });
+        sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
         sshd.start();
         port  = sshd.getPort();
 
         client = SshClient.setUpDefaultClient();
         client.start();
         
-        try(ClientSession s = client.connect("smx", "localhost", port).await().getSession()) {
+        try(ClientSession s = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
             s.addPublicKeyIdentity(kp);
             s.auth().verify(5L, TimeUnit.SECONDS);
         } finally {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
index 6f9c81c..0bcb7f5 100644
--- a/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/KeepAliveTest.java
@@ -26,9 +26,9 @@ import org.apache.sshd.client.ClientFactoryManager;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.FactoryManagerUtils;
 import org.apache.sshd.server.Command;
+import org.apache.sshd.server.PublickeyAuthenticator.AcceptAllPublickeyAuthenticator;
 import org.apache.sshd.util.BaseTestSupport;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
-import org.apache.sshd.util.BogusPublickeyAuthenticator;
 import org.apache.sshd.util.EchoShellFactory;
 import org.apache.sshd.util.Utils;
 import org.junit.After;
@@ -55,8 +55,8 @@ public class KeepAliveTest extends BaseTestSupport {
         sshd.getProperties().put(FactoryManager.IDLE_TIMEOUT, Integer.toString(timeout));
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setShellFactory(new TestEchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
-        sshd.setPublickeyAuthenticator(new BogusPublickeyAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
+        sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
         sshd.start();
         port  = sshd.getPort();
     }
@@ -73,8 +73,8 @@ public class KeepAliveTest extends BaseTestSupport {
         SshClient client = SshClient.setUpDefaultClient();
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
             
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL)) {
@@ -93,8 +93,8 @@ public class KeepAliveTest extends BaseTestSupport {
         SshClient client = SshClient.setUpDefaultClient();
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
         
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL)) {
@@ -114,8 +114,8 @@ public class KeepAliveTest extends BaseTestSupport {
         FactoryManagerUtils.updateProperty(client, ClientFactoryManager.HEARTBEAT_INTERVAL, heartbeat);
         client.start();
 
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
 
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL)) {
@@ -135,8 +135,8 @@ public class KeepAliveTest extends BaseTestSupport {
         FactoryManagerUtils.updateProperty(client, ClientFactoryManager.HEARTBEAT_INTERVAL, heartbeat);
         client.start();
 
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
             
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL)) {
@@ -157,8 +157,8 @@ public class KeepAliveTest extends BaseTestSupport {
         SshClient client = SshClient.setUpDefaultClient();
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
 
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);
@@ -187,8 +187,8 @@ public class KeepAliveTest extends BaseTestSupport {
         SshClient client = SshClient.setUpDefaultClient();
         client.start();
 
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
             
             try(ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
index be798a5..f99c3d2 100644
--- a/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
@@ -67,7 +67,7 @@ public class KeyReExchangeTest extends BaseTestSupport {
         }
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.start();
         port  = sshd.getPort();
     }
@@ -79,9 +79,9 @@ public class KeyReExchangeTest extends BaseTestSupport {
         JSchLogger.init();
         JSch.setConfig("kex", "diffie-hellman-group-exchange-sha1");
         JSch sch = new JSch();
-        com.jcraft.jsch.Session s = sch.getSession("smx", "localhost", port);
+        com.jcraft.jsch.Session s = sch.getSession(getCurrentTestName(), "localhost", port);
         try {
-            s.setUserInfo(new SimpleUserInfo("smx"));
+            s.setUserInfo(new SimpleUserInfo(getCurrentTestName()));
             s.connect();
 
             com.jcraft.jsch.Channel c = s.openChannel("shell");
@@ -116,8 +116,8 @@ public class KeyReExchangeTest extends BaseTestSupport {
         try(SshClient client = SshClient.setUpDefaultClient()) {
             client.start();
         
-            try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-                session.addPasswordIdentity("smx");
+            try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
                 session.auth().verify(5L, TimeUnit.SECONDS);
                 
                 try(ChannelShell channel = session.createShellChannel();
@@ -170,8 +170,8 @@ public class KeyReExchangeTest extends BaseTestSupport {
         try(SshClient client = SshClient.setUpDefaultClient()) {
             client.start();
             
-            try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-                session.addPasswordIdentity("smx");
+            try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
                 session.auth().verify(5L, TimeUnit.SECONDS);
 
                 try(ChannelShell channel = session.createShellChannel();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/LoadTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/LoadTest.java b/sshd-core/src/test/java/org/apache/sshd/LoadTest.java
index df5686c..e4c7db6 100644
--- a/sshd-core/src/test/java/org/apache/sshd/LoadTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/LoadTest.java
@@ -51,7 +51,7 @@ public class LoadTest extends BaseTestSupport {
         sshd = SshServer.setUpDefaultServer();
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.start();
         port  = sshd.getPort();
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/MacTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/MacTest.java b/sshd-core/src/test/java/org/apache/sshd/MacTest.java
index dfd2dc0..cbf86a1 100644
--- a/sshd-core/src/test/java/org/apache/sshd/MacTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/MacTest.java
@@ -119,7 +119,7 @@ public class MacTest extends BaseTestSupport {
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setMacFactories(Arrays.<NamedFactory<Mac>>asList(mac));
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.start();
         port  = sshd.getPort();
     }
@@ -139,9 +139,9 @@ public class MacTest extends BaseTestSupport {
         JSch.setConfig("mac.s2c", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96,hmac-sha2-512");
         JSch.setConfig("mac.c2s", "hmac-md5,hmac-sha1,hmac-sha2-256,hmac-sha1-96,hmac-md5-96,hmac-sha2-512");
         JSch.setConfig("hmac-sha2-512",  "com.jcraft.jsch.jce.HMACSHA512");
-        com.jcraft.jsch.Session s = sch.getSession("smx", "localhost", port);
+        com.jcraft.jsch.Session s = sch.getSession(getCurrentTestName(), "localhost", port);
         try {
-            s.setUserInfo(new SimpleUserInfo("smx"));
+            s.setUserInfo(new SimpleUserInfo(getCurrentTestName()));
             s.connect();
             com.jcraft.jsch.Channel c = s.openChannel("shell");
             c.connect();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/PortForwardingLoadTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/PortForwardingLoadTest.java b/sshd-core/src/test/java/org/apache/sshd/PortForwardingLoadTest.java
index 649eace..72169e6 100644
--- a/sshd-core/src/test/java/org/apache/sshd/PortForwardingLoadTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/PortForwardingLoadTest.java
@@ -82,7 +82,7 @@ public class PortForwardingLoadTest extends BaseTestSupport {
         sshd = SshServer.setUpDefaultServer();
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.setTcpipForwardingFilter(new BogusForwardingFilter());
         sshd.start();
         sshPort = sshd.getPort();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/PortForwardingTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/PortForwardingTest.java b/sshd-core/src/test/java/org/apache/sshd/PortForwardingTest.java
index b70c973..95c05c2 100644
--- a/sshd-core/src/test/java/org/apache/sshd/PortForwardingTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/PortForwardingTest.java
@@ -72,7 +72,7 @@ public class PortForwardingTest extends BaseTestSupport {
         FactoryManagerUtils.updateProperty(sshd, FactoryManager.MAX_PACKET_SIZE, 256);
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.setTcpipForwardingFilter(new BogusForwardingFilter());
         sshd.start();
         sshPort = sshd.getPort();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/ProxyTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/ProxyTest.java b/sshd-core/src/test/java/org/apache/sshd/ProxyTest.java
index dd1bc2f..b7c185b 100644
--- a/sshd-core/src/test/java/org/apache/sshd/ProxyTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/ProxyTest.java
@@ -59,7 +59,7 @@ public class ProxyTest extends BaseTestSupport {
         sshd.getProperties().put(FactoryManager.MAX_PACKET_SIZE, "256");
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.setTcpipForwardingFilter(new BogusForwardingFilter());
         sshd.start();
         sshPort = sshd.getPort();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/ServerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/ServerTest.java b/sshd-core/src/test/java/org/apache/sshd/ServerTest.java
index 3486b38..718ef09 100644
--- a/sshd-core/src/test/java/org/apache/sshd/ServerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/ServerTest.java
@@ -85,7 +85,7 @@ public class ServerTest extends BaseTestSupport {
         sshd = SshServer.setUpDefaultServer();
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setShellFactory(new TestEchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.setSessionFactory(new org.apache.sshd.server.session.SessionFactory());
         sshd.start();
         port = sshd.getPort();
@@ -117,7 +117,7 @@ public class ServerTest extends BaseTestSupport {
         ));
         client.start();
         
-        try(ClientSession s = client.connect("smx", "localhost", port).await().getSession()) {
+        try(ClientSession s = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
             int nbTrials = 0;
             int res = 0;
             while ((res & ClientSession.CLOSED) == 0) {
@@ -146,7 +146,7 @@ public class ServerTest extends BaseTestSupport {
                 new ClientConnectionService.Factory()
         ));
         client.start();
-        try(ClientSession s = client.connect("smx", "localhost", port).await().getSession()) {
+        try(ClientSession s = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
             int nbTrials = 0;
             AuthFuture authFuture;
             do {
@@ -548,7 +548,7 @@ public class ServerTest extends BaseTestSupport {
         sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
         sshd.setShellFactory(new EchoShellFactory());
         sshd.setCommandFactory(new ScpCommandFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshd.start();
         Thread.sleep(100000);
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/SinglePublicKeyAuthTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/SinglePublicKeyAuthTest.java b/sshd-core/src/test/java/org/apache/sshd/SinglePublicKeyAuthTest.java
index c423a07..e0ce922 100644
--- a/sshd-core/src/test/java/org/apache/sshd/SinglePublicKeyAuthTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/SinglePublicKeyAuthTest.java
@@ -100,7 +100,7 @@ public class SinglePublicKeyAuthTest extends BaseTestSupport {
         try(SshClient client = SshClient.setUpDefaultClient()) {
             client.start();
             
-            try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
+            try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
                 session.addPublicKeyIdentity(pairRsaBad);
                 session.addPublicKeyIdentity(pairRsa);
                 assertTrue(session.auth().await().isSuccess());
@@ -136,20 +136,26 @@ public class SinglePublicKeyAuthTest extends BaseTestSupport {
         try(SshClient client = SshClient.setUpDefaultClient()) {
             client.start();
             
-            try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
+            try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
                 session.addPublicKeyIdentity(pairRsaBad);
                 session.addPublicKeyIdentity(pairRsa);
-                assertTrue(session.auth().await().isSuccess());
+                assertTrue("Failed to authenticate", session.auth().await().isSuccess());
             } finally {
                 client.stop();
             }
         }
 
-        assertEquals(2, count.size());
-        assertTrue(count.containsKey(KeyUtils.getFingerPrint(pairRsaBad.getPublic())));
-        assertTrue(count.containsKey(KeyUtils.getFingerPrint(pairRsa.getPublic())));
-        assertEquals(1, count.get(KeyUtils.getFingerPrint(pairRsaBad.getPublic())).get());
-        assertEquals(2, count.get(KeyUtils.getFingerPrint(pairRsa.getPublic())).get());
+        assertEquals("Mismatched attempted keys count", 2, count.size());
+        
+        String badFingerPrint = KeyUtils.getFingerPrint(pairRsaBad.getPublic());
+        Number badIndex = count.get(badFingerPrint);
+        assertNotNull("Missing bad RSA key", badIndex);
+        assertEquals("Mismatched attempt index for bad key", 1, badIndex.intValue());
+
+        String goodFingerPrint = KeyUtils.getFingerPrint(pairRsa.getPublic());
+        Number goodIndex = count.get(goodFingerPrint);
+        assertNotNull("Missing good RSA key", goodIndex);
+        assertEquals("Mismatched attempt index for good key", 2, goodIndex.intValue());
     }
 
     public static class TestCachingPublicKeyAuthenticator extends CachingPublicKeyAuthenticator {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/SpringConfigTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/SpringConfigTest.java b/sshd-core/src/test/java/org/apache/sshd/SpringConfigTest.java
index cc89709..dad0482 100644
--- a/sshd-core/src/test/java/org/apache/sshd/SpringConfigTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/SpringConfigTest.java
@@ -57,8 +57,8 @@ public class SpringConfigTest extends BaseTestSupport {
 
         JSchLogger.init();
         JSch sch = new JSch();
-        com.jcraft.jsch.Session s = sch.getSession("smx", "localhost", port);
-        s.setUserInfo(new SimpleUserInfo("smx"));
+        com.jcraft.jsch.Session s = sch.getSession(getCurrentTestName(), "localhost", port);
+        s.setUserInfo(new SimpleUserInfo(getCurrentTestName()));
         s.connect();
         
         try {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/SshServerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/SshServerTest.java b/sshd-core/src/test/java/org/apache/sshd/SshServerTest.java
index dbc3614..4e9356f 100644
--- a/sshd-core/src/test/java/org/apache/sshd/SshServerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/SshServerTest.java
@@ -88,7 +88,7 @@ public class SshServerTest extends BaseTestSupport {
         SshServer sshd = SshServer.setUpDefaultServer();
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
         sshd.setShellFactory(new EchoShellFactory());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
 
         return sshd;
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java b/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java
index 9c5ad46..1fa1475 100644
--- a/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java
@@ -22,10 +22,10 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.sshd.client.UserInteraction;
+import org.apache.sshd.server.PublickeyAuthenticator.AcceptAllPublickeyAuthenticator;
 import org.apache.sshd.server.ServerFactoryManager;
 import org.apache.sshd.util.BaseTestSupport;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
-import org.apache.sshd.util.BogusPublickeyAuthenticator;
 import org.apache.sshd.util.Utils;
 import org.junit.After;
 import org.junit.Before;
@@ -42,8 +42,8 @@ public class WelcomeBannerTest extends BaseTestSupport {
     public void setUp() throws Exception {
         sshd = SshServer.setUpDefaultServer();
         sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
-        sshd.setPublickeyAuthenticator(new BogusPublickeyAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
+        sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
         sshd.getProperties().put(ServerFactoryManager.WELCOME_BANNER, WELCOME);
         sshd.start();
         port = sshd.getPort();
@@ -73,8 +73,8 @@ public class WelcomeBannerTest extends BaseTestSupport {
             });
             client.start();
             
-            try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-                session.addPasswordIdentity("smx");
+            try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
                 session.auth().verify(5L, TimeUnit.SECONDS);
                 assertEquals(WELCOME, welcome.get());
                 session.close(true);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java b/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
index f71775e..6c89165 100644
--- a/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/WindowAdjustTest.java
@@ -71,7 +71,7 @@ public class WindowAdjustTest {
             }
         });
 
-        sshServer.setPasswordAuthenticator(new BogusPasswordAuthenticator());
+        sshServer.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
         sshServer.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
         sshServer.start();
         port = sshServer.getPort();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/330d17c8/sshd-core/src/test/java/org/apache/sshd/WindowTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/WindowTest.java b/sshd-core/src/test/java/org/apache/sshd/WindowTest.java
index d04dc1d..1fe5493 100644
--- a/sshd-core/src/test/java/org/apache/sshd/WindowTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/WindowTest.java
@@ -45,6 +45,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 import org.apache.sshd.server.Command;
 import org.apache.sshd.server.CommandFactory;
+import org.apache.sshd.server.PublickeyAuthenticator.AcceptAllPublickeyAuthenticator;
 import org.apache.sshd.server.channel.ChannelSession;
 import org.apache.sshd.server.command.UnknownCommand;
 import org.apache.sshd.server.session.ServerConnectionService;
@@ -52,7 +53,6 @@ import org.apache.sshd.server.session.ServerUserAuthService;
 import org.apache.sshd.util.AsyncEchoShellFactory;
 import org.apache.sshd.util.BaseTestSupport;
 import org.apache.sshd.util.BogusPasswordAuthenticator;
-import org.apache.sshd.util.BogusPublickeyAuthenticator;
 import org.apache.sshd.util.EchoShellFactory;
 import org.apache.sshd.util.Utils;
 import org.junit.After;
@@ -86,8 +86,8 @@ public class WindowTest extends BaseTestSupport {
                 return new UnknownCommand(command);
             }
         });
-        sshd.setPasswordAuthenticator(new BogusPasswordAuthenticator());
-        sshd.setPublickeyAuthenticator(new BogusPublickeyAuthenticator());
+        sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
+        sshd.setPublickeyAuthenticator(AcceptAllPublickeyAuthenticator.INSTANCE);
         sshd.setServiceFactories(Arrays.asList(
                 new ServerUserAuthService.Factory() {
                     @Override
@@ -151,8 +151,8 @@ public class WindowTest extends BaseTestSupport {
         FactoryManagerUtils.updateProperty(client, FactoryManager.WINDOW_SIZE, 1024);
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
 
             try(ChannelShell channel = session.createShellChannel()) {
@@ -199,8 +199,8 @@ public class WindowTest extends BaseTestSupport {
 
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
             
             try(ChannelShell channel = session.createShellChannel();
@@ -253,8 +253,8 @@ public class WindowTest extends BaseTestSupport {
 
         client.start();
         
-        try(ClientSession session = client.connect("smx", "localhost", port).await().getSession()) {
-            session.addPasswordIdentity("smx");
+        try(ClientSession session = client.connect(getCurrentTestName(), "localhost", port).await().getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
             session.auth().verify(5L, TimeUnit.SECONDS);
 
             try(ChannelShell channel = session.createShellChannel()) {