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/10/06 07:23:01 UTC

[4/4] mina-sshd git commit: [SSHD-566] Allow specific properties overrides per session and channel

[SSHD-566] Allow specific properties overrides per session and channel


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

Branch: refs/heads/master
Commit: a9d975b6dd1857e6e13465bdbbd26b547da85320
Parents: 57c5ed6
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Tue Oct 6 08:22:41 2015 +0300
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Tue Oct 6 08:22:41 2015 +0300

----------------------------------------------------------------------
 pom.xml                                         |   2 +-
 .../sshd/agent/local/AgentServerProxy.java      |   4 +-
 .../agent/local/ChannelAgentForwarding.java     |   5 +-
 .../sshd/agent/local/ProxyAgentFactory.java     |   7 +-
 .../sshd/agent/unix/AgentServerProxy.java       |   6 +-
 .../sshd/agent/unix/ChannelAgentForwarding.java |   6 +-
 .../sshd/agent/unix/UnixAgentFactory.java       |   7 +-
 .../java/org/apache/sshd/client/SshClient.java  |   4 +-
 .../auth/UserAuthKeyboardInteractive.java       |   8 +-
 .../client/channel/AbstractClientChannel.java   |   6 +-
 .../sshd/client/channel/ChannelDirectTcpip.java |   5 +-
 .../apache/sshd/client/channel/ChannelExec.java |   4 +-
 .../sshd/client/channel/ChannelSession.java     |   7 +-
 .../sshd/client/channel/ChannelShell.java       |   5 +-
 .../sshd/client/channel/ChannelSubsystem.java   |   5 +-
 .../channel/PtyCapableChannelSession.java       |  17 +-
 .../sshd/client/scp/AbstractScpClient.java      |   5 +-
 .../client/session/ClientConnectionService.java |   6 +-
 .../client/session/ClientUserAuthService.java   |   4 +-
 .../subsystem/sftp/DefaultSftpClient.java       |   6 +-
 .../client/subsystem/sftp/SftpFileChannel.java  |   4 +-
 .../client/subsystem/sftp/SftpFileSystem.java   |   4 +-
 .../subsystem/sftp/SftpFileSystemProvider.java  |  19 +-
 .../sshd/common/AbstractFactoryManager.java     |  17 +-
 .../org/apache/sshd/common/FactoryManager.java  |  77 ++--
 .../apache/sshd/common/FactoryManagerUtils.java | 343 -----------------
 .../apache/sshd/common/PropertyResolver.java    |  63 ++++
 .../sshd/common/PropertyResolverUtils.java      | 375 +++++++++++++++++++
 .../sshd/common/channel/AbstractChannel.java    |  45 ++-
 .../org/apache/sshd/common/channel/Channel.java |   3 +-
 .../common/channel/ChannelOutputStream.java     |   4 +-
 .../common/channel/ChannelPipedInputStream.java |  13 +-
 .../org/apache/sshd/common/channel/Window.java  |  34 +-
 .../sshd/common/forward/TcpipClientChannel.java |   2 +
 .../common/io/AbstractIoServiceFactory.java     |   4 +-
 .../sshd/common/io/mina/MinaAcceptor.java       |   6 +-
 .../apache/sshd/common/io/mina/MinaService.java |   6 +-
 .../sshd/common/io/nio2/Nio2Acceptor.java       |   4 +-
 .../apache/sshd/common/io/nio2/Nio2Service.java |   4 +-
 .../apache/sshd/common/io/nio2/Nio2Session.java |   4 +-
 .../common/kex/dh/AbstractDHKeyExchange.java    |   3 +-
 .../session/AbstractConnectionService.java      |  44 +--
 .../sshd/common/session/AbstractSession.java    | 157 ++++----
 .../org/apache/sshd/common/session/Session.java |  19 +-
 .../sshd/server/ServerFactoryManager.java       |  12 +-
 .../java/org/apache/sshd/server/SshServer.java  |   4 +-
 ...DefaultKeyboardInteractiveAuthenticator.java |  12 +-
 .../server/channel/AbstractServerChannel.java   |   1 +
 .../sshd/server/channel/ChannelSession.java     |  29 +-
 .../sshd/server/channel/PipeDataReceiver.java   |   5 +-
 .../sshd/server/forward/TcpipServerChannel.java |   1 +
 .../server/kex/AbstractDHServerKeyExchange.java |  12 +-
 .../org/apache/sshd/server/kex/DHGEXServer.java |  35 +-
 .../org/apache/sshd/server/kex/DHGServer.java   |  17 +-
 .../sshd/server/session/ServerSessionImpl.java  |   8 +-
 .../server/session/ServerUserAuthService.java   |  14 +-
 .../server/subsystem/sftp/SftpSubsystem.java    | 349 +++++++----------
 .../sshd/server/x11/X11ForwardSupport.java      |  11 +-
 .../java/org/apache/sshd/KeepAliveTest.java     |   6 +-
 .../java/org/apache/sshd/KeyReExchangeTest.java |   6 +-
 .../src/test/java/org/apache/sshd/LoadTest.java |   8 +-
 .../org/apache/sshd/PortForwardingTest.java     |  10 +-
 .../test/java/org/apache/sshd/ProxyTest.java    |  10 +-
 .../apache/sshd/SinglePublicKeyAuthTest.java    |   4 +-
 .../java/org/apache/sshd/WelcomeBannerTest.java |   4 +-
 .../java/org/apache/sshd/client/ClientTest.java |  90 ++++-
 .../hosts/HostConfigEntryResolverTest.java      |   6 +-
 .../sshd/client/subsystem/sftp/SftpTest.java    |   4 +-
 .../sshd/common/FactoryManagerUtilsTest.java    | 161 --------
 .../sshd/common/PropertyResolverUtilsTest.java  | 178 +++++++++
 .../sshd/common/auth/AuthenticationTest.java    |  24 +-
 .../channel/ChannelPipedInputStreamTest.java    |   8 +-
 .../apache/sshd/common/channel/WindowTest.java  |  14 +-
 .../sshd/common/channel/WindowTimeoutTest.java  |   5 +-
 .../sshd/common/io/nio2/Nio2ServiceTest.java    |  14 +-
 .../java/org/apache/sshd/server/ServerTest.java |  16 +-
 .../sshd/server/channel/ChannelSessionTest.java |   3 +-
 .../java/org/apache/sshd/util/test/Utils.java   |   1 -
 .../sshd/git/transport/GitSshdSession.java      |   8 +-
 79 files changed, 1345 insertions(+), 1118 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 055e923..9ccb397 100644
--- a/pom.xml
+++ b/pom.xml
@@ -928,7 +928,7 @@
                 <executions>
                     <execution>
                         <id>verify-style</id>
-                        <phase>process-classes</phase>
+                        <phase>validate</phase>
                         <goals>
                             <goal>check</goal>
                         </goals>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java
index 9453b87..30bc5ea 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentServerProxy.java
@@ -24,7 +24,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentServer;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.logging.AbstractLoggingBean;
@@ -46,7 +46,7 @@ public class AgentServerProxy extends AbstractLoggingBean implements SshAgentSer
         try {
             AgentForwardedChannel channel = new AgentForwardedChannel();
             this.service.registerChannel(channel);
-            channel.open().verify(FactoryManagerUtils.getLongProperty(this.service.getSession(), CHANNEL_OPEN_TIMEOUT_PROP, DEFAULT_CHANNEL_OPEN_TIMEOUT));
+            channel.open().verify(PropertyResolverUtils.getLongProperty(channel, CHANNEL_OPEN_TIMEOUT_PROP, DEFAULT_CHANNEL_OPEN_TIMEOUT));
             return channel.getAgent();
         } catch (Throwable t) {
             if (log.isDebugEnabled()) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwarding.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwarding.java b/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwarding.java
index 19baa6b..929361f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwarding.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/ChannelAgentForwarding.java
@@ -32,6 +32,7 @@ import org.apache.sshd.common.channel.ChannelListener;
 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.session.Session;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -56,7 +57,9 @@ public class ChannelAgentForwarding extends AbstractServerChannel {
         ChannelListener listener = getChannelListenerProxy();
         try {
             out = new ChannelOutputStream(this, remoteWindow, log, SshConstants.SSH_MSG_CHANNEL_DATA);
-            FactoryManager manager = session.getFactoryManager();
+
+            Session session = getSession();
+            FactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
             SshAgentFactory factory = ValidateUtils.checkNotNull(manager.getAgentFactory(), "No agent factory");
             agent = factory.createClient(manager);
             client = new AgentClient();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java b/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
index bbec50f..39edf4e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/ProxyAgentFactory.java
@@ -27,14 +27,17 @@ import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentFactory;
 import org.apache.sshd.agent.SshAgentServer;
 import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
 import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.server.session.ServerSession;
 
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
 public class ProxyAgentFactory implements SshAgentFactory {
 
     private final Map<String, AgentServerProxy> proxies = new ConcurrentHashMap<>();
@@ -50,7 +53,7 @@ public class ProxyAgentFactory implements SshAgentFactory {
 
     @Override
     public SshAgent createClient(FactoryManager manager) throws IOException {
-        String proxyId = FactoryManagerUtils.getString(manager, SshAgent.SSH_AUTHSOCKET_ENV_NAME);
+        String proxyId = PropertyResolverUtils.getString(manager, SshAgent.SSH_AUTHSOCKET_ENV_NAME);
         if (GenericUtils.isEmpty(proxyId)) {
             throw new IllegalStateException("No " + SshAgent.SSH_AUTHSOCKET_ENV_NAME + " environment variable set");
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 a602824..05e9ccf 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
@@ -27,7 +27,7 @@ import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.sshd.agent.SshAgentServer;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.session.Session;
@@ -105,10 +105,10 @@ public class AgentServerProxy extends AbstractLoggingBean implements SshAgentSer
                                 }
 
                                 Session session = AgentServerProxy.this.service.getSession();
-                                Socket.timeoutSet(clientSock, FactoryManagerUtils.getIntProperty(session, AUTH_SOCKET_TIMEOUT, DEFAULT_AUTH_SOCKET_TIMEOUT));
+                                Socket.timeoutSet(clientSock, PropertyResolverUtils.getIntProperty(session, AUTH_SOCKET_TIMEOUT, DEFAULT_AUTH_SOCKET_TIMEOUT));
                                 AgentForwardedChannel channel = new AgentForwardedChannel(clientSock);
                                 AgentServerProxy.this.service.registerChannel(channel);
-                                channel.open().verify(FactoryManagerUtils.getLongProperty(session, CHANNEL_OPEN_TIMEOUT_PROP, DEFAULT_CHANNEL_OPEN_TIMEOUT));
+                                channel.open().verify(PropertyResolverUtils.getLongProperty(session, CHANNEL_OPEN_TIMEOUT_PROP, DEFAULT_CHANNEL_OPEN_TIMEOUT));
                             } catch (Exception e) {
                                 if (isOpen()) {
                                     log.info(e.getClass().getSimpleName() + " while authentication forwarding: " + e.getMessage(), e);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 113f33d..ab83c1f 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
@@ -27,7 +27,7 @@ import java.util.concurrent.Future;
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.client.future.DefaultOpenFuture;
 import org.apache.sshd.client.future.OpenFuture;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.channel.ChannelListener;
 import org.apache.sshd.common.channel.ChannelOutputStream;
@@ -78,7 +78,7 @@ public class ChannelAgentForwarding extends AbstractServerChannel {
         ChannelListener listener = getChannelListenerProxy();
         try {
             out = new ChannelOutputStream(this, remoteWindow, log, SshConstants.SSH_MSG_CHANNEL_DATA);
-            authSocket = FactoryManagerUtils.getString(session, SshAgent.SSH_AUTHSOCKET_ENV_NAME);
+            authSocket = PropertyResolverUtils.getString(this, SshAgent.SSH_AUTHSOCKET_ENV_NAME);
             pool = Pool.create(AprLibrary.getInstance().getRootPool());
             handle = Local.create(authSocket, pool);
             int result = Local.connect(handle, 0);
@@ -90,7 +90,7 @@ public class ChannelAgentForwarding extends AbstractServerChannel {
             forwardService = (service == null) ? ThreadUtils.newSingleThreadExecutor("ChannelAgentForwarding[" + authSocket + "]") : service;
             shutdownForwarder = (service == forwardService) ? isShutdownOnExit() : true;
 
-            final int copyBufSize = FactoryManagerUtils.getIntProperty(getSession(), FORWARDER_BUFFER_SIZE, DEFAULT_FORWARDER_BUF_SIZE);
+            final int copyBufSize = PropertyResolverUtils.getIntProperty(this, FORWARDER_BUFFER_SIZE, DEFAULT_FORWARDER_BUF_SIZE);
             ValidateUtils.checkTrue(copyBufSize >= MIN_FORWARDER_BUF_SIZE, "Copy buf size below min.: %d", copyBufSize);
             ValidateUtils.checkTrue(copyBufSize <= MAX_FORWARDER_BUF_SIZE, "Copy buf size above max.: %d", copyBufSize);
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 9862ceb..16fc4bd 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
@@ -25,8 +25,8 @@ import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentFactory;
 import org.apache.sshd.agent.SshAgentServer;
 import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
 import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.session.ConnectionService;
@@ -36,6 +36,9 @@ import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.threads.ExecutorServiceConfigurer;
 import org.apache.sshd.server.session.ServerSession;
 
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
 public class UnixAgentFactory implements SshAgentFactory, ExecutorServiceConfigurer {
     private ExecutorService executor;
     private boolean shutdownExecutor;
@@ -88,7 +91,7 @@ public class UnixAgentFactory implements SshAgentFactory, ExecutorServiceConfigu
 
     @Override
     public SshAgent createClient(FactoryManager manager) throws IOException {
-        String authSocket = FactoryManagerUtils.getString(manager, SshAgent.SSH_AUTHSOCKET_ENV_NAME);
+        String authSocket = PropertyResolverUtils.getString(manager, SshAgent.SSH_AUTHSOCKET_ENV_NAME);
         if (GenericUtils.isEmpty(authSocket)) {
             throw new SshException("No " + SshAgent.SSH_AUTHSOCKET_ENV_NAME + " value");
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
index ff0b33c..09e1f38 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
@@ -74,8 +74,8 @@ import org.apache.sshd.client.simple.SimpleClient;
 import org.apache.sshd.common.AbstractFactoryManager;
 import org.apache.sshd.common.Closeable;
 import org.apache.sshd.common.Factory;
-import org.apache.sshd.common.FactoryManagerUtils;
 import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.ServiceFactory;
 import org.apache.sshd.common.SshdSocketAddress;
 import org.apache.sshd.common.channel.Channel;
@@ -402,7 +402,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
         }
 
         List<KeyPair> ids = new ArrayList<>(locations.size());
-        boolean ignoreNonExisting = FactoryManagerUtils.getBooleanProperty(this, IGNORE_INVALID_IDENTITIES, DEFAULT_IGNORE_INVALID_IDENTITIES);
+        boolean ignoreNonExisting = PropertyResolverUtils.getBooleanProperty(this, IGNORE_INVALID_IDENTITIES, DEFAULT_IGNORE_INVALID_IDENTITIES);
         ClientIdentityLoader loader = ValidateUtils.checkNotNull(getClientIdentityLoader(), "No ClientIdentityLoader");
         FilePasswordProvider provider = ValidateUtils.checkNotNull(getFilePasswordProvider(), "No FilePasswordProvider");
         for (String l : locations) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 30f4e45..34ba100 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
@@ -26,7 +26,7 @@ import java.util.List;
 
 import org.apache.sshd.client.ClientFactoryManager;
 import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
@@ -94,7 +94,7 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
             }
         }
         passwords = pwds.iterator();
-        maxTrials = session.getIntProperty(ClientFactoryManager.PASSWORD_PROMPTS, ClientFactoryManager.DEFAULT_PASSWORD_PROMPTS);
+        maxTrials = PropertyResolverUtils.getIntProperty(session, ClientFactoryManager.PASSWORD_PROMPTS, ClientFactoryManager.DEFAULT_PASSWORD_PROMPTS);
         ValidateUtils.checkTrue(maxTrials > 0, "Non-positive max. trials: %d", maxTrials);
     }
 
@@ -188,11 +188,11 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
     }
 
     protected String getExchangeLanguageTag(ClientSession session) {
-        return FactoryManagerUtils.getStringProperty(session, INTERACTIVE_LANGUAGE_TAG, DEFAULT_INTERACTIVE_LANGUAGE_TAG);
+        return PropertyResolverUtils.getStringProperty(session, INTERACTIVE_LANGUAGE_TAG, DEFAULT_INTERACTIVE_LANGUAGE_TAG);
     }
 
     protected String getExchangeSubMethods(ClientSession session) {
-        return FactoryManagerUtils.getStringProperty(session, INTERACTIVE_SUBMETHODS, DEFAULT_INTERACTIVE_SUBMETHODS);
+        return PropertyResolverUtils.getStringProperty(session, INTERACTIVE_SUBMETHODS, DEFAULT_INTERACTIVE_SUBMETHODS);
     }
 
     protected String getCurrentPasswordCandidate() {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 b2130ce..513ca28 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
@@ -278,6 +278,8 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
         }
         openFuture = new DefaultOpenFuture(lock);
         log.debug("Send SSH_MSG_CHANNEL_OPEN on channel {}", this);
+
+        Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_OPEN);
         buffer.putString(type);
         buffer.putInt(id);
@@ -296,8 +298,8 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
     public void handleOpenSuccess(int recipient, int rwSize, int packetSize, Buffer buffer) {
         this.recipient = recipient;
 
-        Session s = getSession();
-        FactoryManager manager = ValidateUtils.checkNotNull(s.getFactoryManager(), "No factory manager");
+        Session session = getSession();
+        FactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
         this.remoteWindow.init(rwSize, packetSize, manager.getProperties());
         ChannelListener listener = getChannelListenerProxy();
         try {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java
index db26589..070c40c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelDirectTcpip.java
@@ -32,6 +32,7 @@ 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.session.Session;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
@@ -66,11 +67,13 @@ public class ChannelDirectTcpip extends AbstractClientChannel {
         if (closeFuture.isClosed()) {
             throw new SshException("Session has been closed");
         }
+
         openFuture = new DefaultOpenFuture(lock);
         if (log.isDebugEnabled()) {
             log.debug("Send SSH_MSG_CHANNEL_OPEN on channel {}", Integer.valueOf(id));
         }
 
+        Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_OPEN);
         buffer.putString(type);
         buffer.putInt(id);
@@ -92,7 +95,7 @@ public class ChannelDirectTcpip extends AbstractClientChannel {
         } else {
             out = new ChannelOutputStream(this, remoteWindow, log, SshConstants.SSH_MSG_CHANNEL_DATA);
             invertedIn = out;
-            ChannelPipedInputStream pis = new ChannelPipedInputStream(localWindow);
+            ChannelPipedInputStream pis = new ChannelPipedInputStream(this, localWindow);
             pipe = new ChannelPipedOutputStream(pis);
             in = pis;
             invertedOut = in;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java
index 0e43672..d33d9e1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelExec.java
@@ -21,6 +21,7 @@ package org.apache.sshd.client.channel;
 import java.io.IOException;
 
 import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 
@@ -42,7 +43,8 @@ public class ChannelExec extends PtyCapableChannelSession {
     protected void doOpen() throws IOException {
         doOpenPty();
 
-        log.debug("Send SSH_MSG_CHANNEL_REQUEST exec");
+        log.debug("Send SSH_MSG_CHANNEL_REQUEST exec on {}", this);
+        Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
         buffer.putInt(recipient);
         buffer.putString("exec");

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 9709f57..6fbae18 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
@@ -30,6 +30,7 @@ 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.future.CloseFuture;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.threads.ThreadUtils;
 
 /**
@@ -57,6 +58,7 @@ public class ChannelSession extends AbstractClientChannel {
                     try {
                         sendEof();
                     } catch (IOException e) {
+                        Session session = getSession();
                         session.exceptionCaught(e);
                     }
                     return super.doCloseGracefully();
@@ -67,13 +69,13 @@ public class ChannelSession extends AbstractClientChannel {
         } else {
             invertedIn = new ChannelOutputStream(this, remoteWindow, log, SshConstants.SSH_MSG_CHANNEL_DATA);
             if (out == null) {
-                ChannelPipedInputStream pis = new ChannelPipedInputStream(localWindow);
+                ChannelPipedInputStream pis = new ChannelPipedInputStream(this, localWindow);
                 ChannelPipedOutputStream pos = new ChannelPipedOutputStream(pis);
                 out = pos;
                 invertedOut = pis;
             }
             if (err == null) {
-                ChannelPipedInputStream pis = new ChannelPipedInputStream(localWindow);
+                ChannelPipedInputStream pis = new ChannelPipedInputStream(this, localWindow);
                 ChannelPipedOutputStream pos = new ChannelPipedOutputStream(pis);
                 err = pos;
                 invertedErr = pis;
@@ -132,6 +134,7 @@ public class ChannelSession extends AbstractClientChannel {
             byte[] buffer = new byte[remoteWindow.getPacketSize()];
             while (!closeFuture.isClosed()) {
                 int len = securedRead(in, buffer, 0, buffer.length);
+                Session session = getSession();
                 session.resetIdleTimeout();
                 if (len > 0) {
                     invertedIn.write(buffer, 0, len);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java
index 7795c6f..a10edc5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/ChannelShell.java
@@ -21,6 +21,7 @@ package org.apache.sshd.client.channel;
 import java.io.IOException;
 
 import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
@@ -38,7 +39,9 @@ public class ChannelShell extends PtyCapableChannelSession {
     protected void doOpen() throws IOException {
         doOpenPty();
 
-        log.debug("Send SSH_MSG_CHANNEL_REQUEST shell");
+        log.debug("Send SSH_MSG_CHANNEL_REQUEST shell on {}", this);
+
+        Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
         buffer.putInt(recipient);
         buffer.putString("shell");

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 e6399eb..c261702 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,7 @@ 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.session.Session;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 
@@ -53,7 +54,9 @@ public class ChannelSubsystem extends ChannelSession {
 
     @Override
     protected void doOpen() throws IOException {
-        log.debug("Send SSH_MSG_CHANNEL_REQUEST exec");
+        log.debug("Send SSH_MSG_CHANNEL_REQUEST exec on {}", this);
+
+        Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
         buffer.putInt(recipient);
         buffer.putString("subsystem");

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
index f038289..ae2862f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
@@ -27,6 +27,7 @@ import java.util.Map;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.channel.PtyMode;
 import org.apache.sshd.common.channel.SttySupport;
+import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.OsUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -203,6 +204,8 @@ public class PtyCapableChannelSession extends ChannelSession {
         ptyLines = lines;
         ptyHeight = height;
         ptyWidth = width;
+
+        Session session = getSession();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
         buffer.putInt(recipient);
         buffer.putString("window-change");
@@ -215,10 +218,12 @@ public class PtyCapableChannelSession extends ChannelSession {
     }
 
     protected void doOpenPty() throws IOException {
+        Session session = getSession();
         if (agentForwarding) {
             if (log.isDebugEnabled()) {
-                log.debug("Send agent forwarding request - recipient={}", Integer.valueOf(recipient));
+                log.debug("Send agent forwarding request on {} - recipient={}", this, Integer.valueOf(recipient));
             }
+
             Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
             buffer.putInt(recipient);
             buffer.putString("auth-agent-req@openssh.com");
@@ -228,9 +233,8 @@ public class PtyCapableChannelSession extends ChannelSession {
 
         if (usePty) {
             if (log.isDebugEnabled()) {
-                log.debug("Send SSH_MSG_CHANNEL_REQUEST pty-req: type={}, cols={}, lines={}, height={}, width={}, modes={}",
-                        ptyType, ptyColumns, ptyLines,
-                        ptyHeight, ptyWidth, ptyModes);
+                log.debug("Send SSH_MSG_CHANNEL_REQUEST pty-req on {}: type={}, cols={}, lines={}, height={}, width={}, modes={}",
+                          this, ptyType, ptyColumns, ptyLines, ptyHeight, ptyWidth, ptyModes);
             }
 
             Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST);
@@ -256,7 +260,10 @@ public class PtyCapableChannelSession extends ChannelSession {
         }
 
         if (GenericUtils.size(env) > 0) {
-            log.debug("Send SSH_MSG_CHANNEL_REQUEST env: {}", env);
+            if (log.isDebugEnabled()) {
+                log.debug("Send SSH_MSG_CHANNEL_REQUEST env on {}: {}", this, env);
+            }
+
             for (Map.Entry<String, String> entry : env.entrySet()) {
                 String key = entry.getKey();
                 String value = entry.getValue();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
index 0a2b646..40030b6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/scp/AbstractScpClient.java
@@ -37,7 +37,7 @@ import java.util.concurrent.TimeUnit;
 import org.apache.sshd.client.channel.ChannelExec;
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.file.FileSystemFactory;
 import org.apache.sshd.common.scp.ScpHelper;
@@ -237,8 +237,7 @@ public abstract class AbstractScpClient extends AbstractLoggingBean implements S
     }
 
     protected ChannelExec openCommandChannel(ClientSession session, String cmd) throws IOException {
-        FactoryManager manager = ValidateUtils.checkNotNull(session, "No session for command: %s", cmd).getFactoryManager();
-        long waitTimeout = FactoryManagerUtils.getLongProperty(manager, SCP_EXEC_CHANNEL_OPEN_TIMEOUT, DEFAULT_EXEC_CHANNEL_OPEN_TIMEOUT);
+        long waitTimeout = PropertyResolverUtils.getLongProperty(session, SCP_EXEC_CHANNEL_OPEN_TIMEOUT, DEFAULT_EXEC_CHANNEL_OPEN_TIMEOUT);
         ChannelExec channel = session.createExecChannel(cmd);
 
         long startTime = System.nanoTime();

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java
index dcddab4..bd8d0db 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientConnectionService.java
@@ -24,7 +24,7 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.sshd.client.ClientFactoryManager;
 import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.session.AbstractConnectionService;
@@ -53,7 +53,7 @@ public class ClientConnectionService extends AbstractConnectionService {
     }
 
     protected void startHeartBeat() {
-        long interval = FactoryManagerUtils.getLongProperty(session, ClientFactoryManager.HEARTBEAT_INTERVAL, ClientFactoryManager.DEFAULT_HEARTBEAT_INTERVAL);
+        long interval = PropertyResolverUtils.getLongProperty(session, ClientFactoryManager.HEARTBEAT_INTERVAL, ClientFactoryManager.DEFAULT_HEARTBEAT_INTERVAL);
         if (interval > 0L) {
             FactoryManager manager = session.getFactoryManager();
             ScheduledExecutorService service = manager.getScheduledExecutorService();
@@ -70,7 +70,7 @@ public class ClientConnectionService extends AbstractConnectionService {
     }
 
     protected void sendHeartBeat() {
-        String request = FactoryManagerUtils.getStringProperty(session, ClientFactoryManager.HEARTBEAT_REQUEST, ClientFactoryManager.DEFAULT_KEEP_ALIVE_HEARTBEAT_STRING);
+        String request = PropertyResolverUtils.getStringProperty(session, ClientFactoryManager.HEARTBEAT_REQUEST, ClientFactoryManager.DEFAULT_KEEP_ALIVE_HEARTBEAT_STRING);
         try {
             Buffer buf = session.createBuffer(SshConstants.SSH_MSG_GLOBAL_REQUEST);
             buf.putString(request);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 dd657fe..8ea0788 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
@@ -28,9 +28,9 @@ import org.apache.sshd.client.auth.UserAuth;
 import org.apache.sshd.client.auth.UserInteraction;
 import org.apache.sshd.client.future.AuthFuture;
 import org.apache.sshd.client.future.DefaultAuthFuture;
-import org.apache.sshd.common.FactoryManagerUtils;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.Service;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
@@ -74,7 +74,7 @@ public class ClientUserAuthService extends AbstractCloseable implements Service,
         authFactories = manager.getUserAuthFactories();
         clientMethods = new ArrayList<>();
 
-        String prefs = FactoryManagerUtils.getString(manager, ClientFactoryManager.PREFERRED_AUTHS);
+        String prefs = PropertyResolverUtils.getString(session, ClientFactoryManager.PREFERRED_AUTHS);
         if (!GenericUtils.isEmpty(prefs)) {
             for (String pref : prefs.split(",")) {
                 NamedFactory<UserAuth> factory = NamedResource.Utils.findByName(pref, String.CASE_INSENSITIVE_ORDER, authFactories);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
index a4cf4a6..aa8aead 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
@@ -36,7 +36,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.sshd.client.channel.ChannelSubsystem;
 import org.apache.sshd.client.channel.ClientChannel;
 import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.subsystem.sftp.SftpConstants;
 import org.apache.sshd.common.subsystem.sftp.extensions.ParserUtils;
@@ -69,7 +69,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
     private final Map<String, byte[]> exposedExtensions = Collections.unmodifiableMap(extensions);
 
     public DefaultSftpClient(ClientSession clientSession) throws IOException {
-        this.clientSession = ValidateUtils.checkNotNull(clientSession, "No client session", GenericUtils.EMPTY_OBJECT_ARRAY);
+        this.clientSession = ValidateUtils.checkNotNull(clientSession, "No client session");
         this.channel = clientSession.createSubsystemChannel(SftpConstants.SFTP_SUBSYSTEM_NAME);
         this.channel.setOut(new OutputStream() {
             @Override
@@ -83,7 +83,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
             }
         });
         this.channel.setErr(new ByteArrayOutputStream(Byte.MAX_VALUE));
-        this.channel.open().verify(FactoryManagerUtils.getLongProperty(clientSession, SFTP_CHANNEL_OPEN_TIMEOUT, DEFAULT_CHANNEL_OPEN_TIMEOUT));
+        this.channel.open().verify(PropertyResolverUtils.getLongProperty(clientSession, SFTP_CHANNEL_OPEN_TIMEOUT, DEFAULT_CHANNEL_OPEN_TIMEOUT));
         this.channel.onClose(new Runnable() {
             @SuppressWarnings("synthetic-access")
             @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java
index 70ca10d..bf69719 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileChannel.java
@@ -39,7 +39,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.io.IoUtils;
@@ -276,7 +276,7 @@ public class SftpFileChannel extends FileChannel {
         }
         ensureOpen(WRITE_MODES);
 
-        int copySize = FactoryManagerUtils.getIntProperty(sftp.getClientSession(), COPY_BUFSIZE_PROP, DEFAULT_TRANSFER_BUFFER_SIZE);
+        int copySize = PropertyResolverUtils.getIntProperty(sftp.getClientSession(), COPY_BUFSIZE_PROP, DEFAULT_TRANSFER_BUFFER_SIZE);
         boolean completed = false;
         long curPos = (position >= 0L) ? position : posTracker.get();
         long totalRead = 0L;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
index 3532e64..a348a98 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystem.java
@@ -40,7 +40,7 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.sshd.client.channel.ClientChannel;
 import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.file.util.BaseFileSystem;
 import org.apache.sshd.common.file.util.ImmutableList;
 import org.apache.sshd.common.util.GenericUtils;
@@ -74,7 +74,7 @@ public class SftpFileSystem extends BaseFileSystem<SftpPath> {
         this.session = session;
         this.selector = ValidateUtils.checkNotNull(selector, "No SFTP version selector provided");
         this.stores = Collections.unmodifiableList(Collections.<FileStore>singletonList(new SftpFileStore(id, this)));
-        this.pool = new LinkedBlockingQueue<>(FactoryManagerUtils.getIntProperty(session, POOL_SIZE_PROP, DEFAULT_POOL_SIZE));
+        this.pool = new LinkedBlockingQueue<>(PropertyResolverUtils.getIntProperty(session, POOL_SIZE_PROP, DEFAULT_POOL_SIZE));
         try (SftpClient client = getClient()) {
             defaultDir = getPath(client.canonicalPath("."));
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
index cd9d842..ad00511 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemProvider.java
@@ -67,8 +67,8 @@ import java.util.concurrent.TimeUnit;
 import org.apache.sshd.client.SshClient;
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.client.subsystem.sftp.SftpClient.Attributes;
-import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolver;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshException;
 import org.apache.sshd.common.config.SshConfigFileReader;
 import org.apache.sshd.common.io.IoSession;
@@ -151,9 +151,11 @@ public class SftpFileSystemProvider extends FileSystemProvider {
         String userInfo = ValidateUtils.checkNotNullAndNotEmpty(uri.getUserInfo(), "UserInfo not provided");
         String[] ui = GenericUtils.split(userInfo, ':');
         ValidateUtils.checkTrue(GenericUtils.length(ui) == 2, "Invalid user info: %s", userInfo);
+
         String username = ui[0];
         String password = ui[1];
         String id = getFileSystemIdentifier(host, port, username);
+        PropertyResolver resolver = PropertyResolverUtils.toPropertyResolver(Collections.unmodifiableMap(env));
 
         SftpFileSystem fileSystem;
         synchronized (fileSystems) {
@@ -165,10 +167,10 @@ public class SftpFileSystemProvider extends FileSystemProvider {
             ClientSession session = null;
             try {
                 session = client.connect(username, host, port)
-                        .verify(FactoryManagerUtils.getLongProperty(env, CONNECT_TIME_PROP_NAME, DEFAULT_CONNECT_TIME))
+                        .verify(PropertyResolverUtils.getLongProperty(resolver, CONNECT_TIME_PROP_NAME, DEFAULT_CONNECT_TIME))
                         .getSession();
                 session.addPasswordIdentity(password);
-                session.auth().verify(FactoryManagerUtils.getLongProperty(env, AUTH_TIME_PROP_NAME, DEFAULT_AUTH_TIME));
+                session.auth().verify(PropertyResolverUtils.getLongProperty(resolver, AUTH_TIME_PROP_NAME, DEFAULT_AUTH_TIME));
 
                 fileSystem = new SftpFileSystem(this, id, session, getSftpVersionSelector());
                 fileSystems.put(id, fileSystem);
@@ -196,8 +198,8 @@ public class SftpFileSystemProvider extends FileSystemProvider {
             }
         }
 
-        fileSystem.setReadBufferSize(FactoryManagerUtils.getIntProperty(env, READ_BUFFER_PROP_NAME, DEFAULT_READ_BUFFER_SIZE));
-        fileSystem.setWriteBufferSize(FactoryManagerUtils.getIntProperty(env, WRITE_BUFFER_PROP_NAME, DEFAULT_WRITE_BUFFER_SIZE));
+        fileSystem.setReadBufferSize(PropertyResolverUtils.getIntProperty(resolver, READ_BUFFER_PROP_NAME, DEFAULT_READ_BUFFER_SIZE));
+        fileSystem.setWriteBufferSize(PropertyResolverUtils.getIntProperty(resolver, WRITE_BUFFER_PROP_NAME, DEFAULT_WRITE_BUFFER_SIZE));
         return fileSystem;
     }
 
@@ -212,9 +214,8 @@ public class SftpFileSystemProvider extends FileSystemProvider {
             fileSystems.put(id, fileSystem);
         }
 
-        FactoryManager manager = session.getFactoryManager();
-        fileSystem.setReadBufferSize(FactoryManagerUtils.getIntProperty(manager, READ_BUFFER_PROP_NAME, DEFAULT_READ_BUFFER_SIZE));
-        fileSystem.setWriteBufferSize(FactoryManagerUtils.getIntProperty(manager, WRITE_BUFFER_PROP_NAME, DEFAULT_WRITE_BUFFER_SIZE));
+        fileSystem.setReadBufferSize(PropertyResolverUtils.getIntProperty(session, READ_BUFFER_PROP_NAME, DEFAULT_READ_BUFFER_SIZE));
+        fileSystem.setWriteBufferSize(PropertyResolverUtils.getIntProperty(session, WRITE_BUFFER_PROP_NAME, DEFAULT_WRITE_BUFFER_SIZE));
         return fileSystem;
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java
index 8ac555d..3cd9a19 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java
@@ -19,9 +19,9 @@
 package org.apache.sshd.common;
 
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
@@ -64,7 +64,6 @@ public abstract class AbstractFactoryManager
         extends AbstractInnerCloseable
         implements FactoryManager, KeyPairProviderHolder {
 
-    protected Map<String, Object> properties = new HashMap<>();
     protected IoServiceFactoryFactory ioServiceFactoryFactory;
     protected IoServiceFactory ioServiceFactory;
     protected List<NamedFactory<KeyExchange>> keyExchangeFactories;
@@ -89,6 +88,7 @@ public abstract class AbstractFactoryManager
     protected final Collection<ChannelListener> channelListeners = new CopyOnWriteArraySet<>();
     protected final ChannelListener channelListenerProxy;
 
+    private final Map<String, Object> properties = new ConcurrentHashMap<>();
     private KeyPairProvider keyPairProvider;
 
     protected AbstractFactoryManager() {
@@ -183,13 +183,14 @@ public abstract class AbstractFactoryManager
         return properties;
     }
 
-    public void setProperties(Map<String, Object> properties) {
-        this.properties = ValidateUtils.checkNotNull(properties, "Null properties not allowed");
+    @Override
+    public PropertyResolver getParentPropertyResolver() {
+        return null;
     }
 
     @Override
     public String getVersion() {
-        return FactoryManagerUtils.getStringProperty(VersionProperties.getVersionProperties(), "sshd-version", DEFAULT_VERSION).toUpperCase();
+        return PropertyResolverUtils.getStringProperty(VersionProperties.getVersionProperties(), "sshd-version", DEFAULT_VERSION).toUpperCase();
     }
 
     @Override
@@ -202,7 +203,7 @@ public abstract class AbstractFactoryManager
     }
 
     public int getNioWorkers() {
-        int nb = FactoryManagerUtils.getIntProperty(this, NIO_WORKERS, DEFAULT_NIO_WORKERS);
+        int nb = PropertyResolverUtils.getIntProperty(this, NIO_WORKERS, DEFAULT_NIO_WORKERS);
         if (nb > 0) {
             return nb;
         } else {    // it may have been configured to a negative value
@@ -212,9 +213,9 @@ public abstract class AbstractFactoryManager
 
     public void setNioWorkers(int nioWorkers) {
         if (nioWorkers > 0) {
-            FactoryManagerUtils.updateProperty(this, NIO_WORKERS, nioWorkers);
+            PropertyResolverUtils.updateProperty(this, NIO_WORKERS, nioWorkers);
         } else {
-            FactoryManagerUtils.updateProperty(this, NIO_WORKERS, null);
+            PropertyResolverUtils.updateProperty(this, NIO_WORKERS, null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
index a49e16e..dc0ff3d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
@@ -19,8 +19,8 @@
 package org.apache.sshd.common;
 
 import java.util.List;
-import java.util.Map;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.sshd.agent.SshAgentFactory;
 import org.apache.sshd.common.channel.Channel;
@@ -45,67 +45,109 @@ import org.apache.sshd.server.forward.ForwardingFilter;
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
-public interface FactoryManager extends SessionListenerManager, ChannelListenerManager {
+public interface FactoryManager extends SessionListenerManager, ChannelListenerManager, PropertyResolver {
 
     /**
-     * Key used to retrieve the value of the window size in the
+     * Key used to retrieve the value of the channel window size in the
      * configuration properties map.
+     * @see #DEFAULT_WINDOW_SIZE
      */
     String WINDOW_SIZE = "window-size";
 
     /**
+     * Default {@link #WINDOW_SIZE} if none set
+     */
+    int DEFAULT_WINDOW_SIZE = 0x200000;
+
+    /**
      * Key used to retrieve timeout (msec.) to wait for data to
      * become available when reading from a channel. If not set
      * or non-positive then infinite value is assumed
+     * @see #DEFAULT_WINDOW_TIMEOUT
      */
     String WINDOW_TIMEOUT = "window-timeout";
 
+    /**
+     * Default {@link #WINDOW_TIMEOUT} value
+     */
+    long DEFAULT_WINDOW_TIMEOUT = 0L;
 
     /**
      * Key used to retrieve the value of the maximum packet size
      * in the configuration properties map.
+     * @see #DEFAULT_MAX_PACKET_SIZE
      */
     String MAX_PACKET_SIZE = "packet-size";
 
     /**
+     * Default {@link #MAX_PACKET_SIZE} if none set
+     */
+    int DEFAULT_MAX_PACKET_SIZE = 0x8000;
+
+    /**
      * Number of NIO worker threads to use.
+     * @see #DEFAULT_NIO_WORKERS
      */
     String NIO_WORKERS = "nio-workers";
 
     /**
-     * Default number of worker threads to use.
+     * Default number of worker threads to use if none set.
      */
     int DEFAULT_NIO_WORKERS = Runtime.getRuntime().availableProcessors() + 1;
 
     /**
      * Key used to retrieve the value of the timeout after which
      * it will close the connection if the other side has not been
-     * authenticated.
+     * authenticated - in milliseconds.
+     * @see #DEFAULT_AUTH_TIMEOUT
      */
     String AUTH_TIMEOUT = "auth-timeout";
 
     /**
+     * Default value for {@link #AUTH_TIMEOUT} if none set
+     */
+    long DEFAULT_AUTH_TIMEOUT = TimeUnit.MINUTES.toMillis(2L);
+
+    /**
      * Key used to retrieve the value of idle timeout after which
-     * it will close the connection.  In milliseconds.
+     * it will close the connection - in milliseconds.
+     * @see #DEFAULT_AUTH_TIMEOUT
      */
     String IDLE_TIMEOUT = "idle-timeout";
 
     /**
+     * Default value for {@link #IDLE_TIMEOUT} if none set
+     */
+    long DEFAULT_IDLE_TIMEOUT = TimeUnit.MINUTES.toMillis(10L);
+
+    /**
      * Key used to retrieve the value of the disconnect timeout which
      * is used when a disconnection is attempted.  If the disconnect
      * message has not been sent before the timeout, the underlying socket
-     * will be forcibly closed.
+     * will be forcibly closed - in milliseconds.
+     * @see #DEFAULT_DISCONNECT_TIMEOUT
      */
     String DISCONNECT_TIMEOUT = "disconnect-timeout";
 
     /**
+     * Default value for {@link #DISCONNECT_TIMEOUT} if none set
+     */
+    long DEFAULT_DISCONNECT_TIMEOUT = TimeUnit.SECONDS.toMillis(10L);
+
+    /**
      * Key used to configure the timeout used when writing a close request
      * on a channel. If the message can not be written before the specified
      * timeout elapses, the channel will be immediately closed. In milliseconds.
+     * @see #DEFAULT_AUTH_TIMEOUT
      */
     String CHANNEL_CLOSE_TIMEOUT = "channel-close-timeout";
 
     /**
+     * Default {@link #CHANNEL_CLOSE_TIMEOUT} value if none set
+     */
+    long DEFAULT_CHANNEL_CLOSE_TIMEOUT = TimeUnit.SECONDS.toMillis(5L);
+
+    /**
      * Socket backlog.
      * See {@link java.nio.channels.AsynchronousServerSocketChannel#bind(java.net.SocketAddress, int)}
      */
@@ -160,27 +202,6 @@ public interface FactoryManager extends SessionListenerManager, ChannelListenerM
     String DEFAULT_VERSION = "SSHD-UNKNOWN";
 
     /**
-     * <P>A map of properties that can be used to configure the SSH server
-     * or client.  This map will never be changed by either the server or
-     * client and is not supposed to be changed at runtime (changes are not
-     * bound to have any effect on a running client or server), though it may
-     * affect the creation of sessions later as these values are usually not
-     * cached.</P>
-     *
-     * <P><B>Note:</B> the <U>type</U> of the mapped property should match the
-     * expected configuration value type - {@code Long, Integer, Boolean,
-     * String}, etc.... If it doesn't, the {@code toString()} result of the
-     * mapped value is used to convert it to the required type. E.g., if
-     * the mapped value is the <U>string</U> &quot;1234&quot; and the expected
-     * value is a {@code long} then it will be parsed into one. Also, if
-     * the mapped value is an {@code Integer} but a {@code long} is expected,
-     * then it will be converted into one.</P>
-     *
-     * @return a valid <code>Map</code> containing configuration values, never {@code null}
-     */
-    Map<String, Object> getProperties();
-
-    /**
      * An upper case string identifying the version of the software used on
      * client or server side. This version includes the name of the software
      * and usually looks like this: <code>SSHD-1.0</code>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/FactoryManagerUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManagerUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManagerUtils.java
deleted file mode 100644
index d62c4c1..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManagerUtils.java
+++ /dev/null
@@ -1,343 +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.common;
-
-import java.util.Map;
-import java.util.Objects;
-
-import org.apache.sshd.common.channel.Channel;
-import org.apache.sshd.common.session.Session;
-import org.apache.sshd.common.util.GenericUtils;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public final class FactoryManagerUtils {
-
-    private FactoryManagerUtils() {
-        throw new UnsupportedOperationException("No instance allowed");
-    }
-
-    /**
-     * @param channel      The {@link Channel} instance
-     * @param name         The property name
-     * @param defaultValue The default value to return if the specified property
-     *                     does not exist in the properties map
-     * @return The resolved property
-     * @throws NumberFormatException if malformed value
-     */
-    public static long getLongProperty(Channel channel, String name, long defaultValue) {
-        return getLongProperty(channel.getSession(), name, defaultValue);
-    }
-
-    /**
-     * @param session      The {@link Session} instance
-     * @param name         The property name
-     * @param defaultValue The default value to return if the specified property
-     *                     does not exist in the properties map
-     * @return The resolved property
-     * @throws NumberFormatException if malformed value
-     */
-    public static long getLongProperty(Session session, String name, long defaultValue) {
-        return getLongProperty(session.getFactoryManager(), name, defaultValue);
-    }
-
-    /**
-     * @param manager      The {@link FactoryManager} instance
-     * @param name         The property name
-     * @param defaultValue The default value to return if the specified property
-     *                     does not exist in the properties map
-     * @return The resolved property
-     * @throws NumberFormatException if malformed value
-     */
-    public static long getLongProperty(FactoryManager manager, String name, long defaultValue) {
-        return getLongProperty(manager.getProperties(), name, defaultValue);
-    }
-
-    /**
-     * @param props        The properties {@link Map} - ignored if {@code null}/empty
-     * @param name         The property name
-     * @param defaultValue The default value to return if the specified property
-     *                     does not exist in the properties map or is an empty string
-     * @return The resolved property
-     * @throws NumberFormatException if malformed value
-     */
-    public static long getLongProperty(Map<String, ?> props, String name, long defaultValue) {
-        Object value = GenericUtils.isEmpty(props) ? null : props.get(name);
-        if (value == null) {
-            return defaultValue;
-        } else if (value instanceof Long) {
-            return (Long) value;
-        } else {    // we parse the string in case it is not a valid long value
-            return Long.parseLong(value.toString());
-        }
-    }
-
-    /**
-     * @param channel The {@link Channel} instance
-     * @param name    The property name
-     * @return The {@link Long} value or {@code null} if property not found or empty string
-     * @throws NumberFormatException if malformed value
-     */
-    public static Long getLong(Channel channel, String name) {
-        return getLong(channel.getSession(), name);
-    }
-
-    /**
-     * @param session The {@link Session} instance
-     * @param name    The property name
-     * @return The {@link Long} value or {@code null} if property not found or empty string
-     * @throws NumberFormatException if malformed value
-     */
-    public static Long getLong(Session session, String name) {
-        return getLong(session.getFactoryManager(), name);
-    }
-
-    /**
-     * @param manager The {@link FactoryManager} instance
-     * @param name    The property name
-     * @return The {@link Long} value or {@code null} if property not found
-     * @throws NumberFormatException if malformed value
-     */
-    public static Long getLong(FactoryManager manager, String name) {
-        return getLong(manager.getProperties(), name);
-    }
-
-    /**
-     * @param props The properties {@link Map} - ignored if {@code null}/empty
-     * @param name  The property name
-     * @return The {@link Long} value or {@code null} if property not found or
-     * empty string
-     * @throws NumberFormatException if malformed value
-     */
-    public static Long getLong(Map<String, ?> props, String name) {
-        Object value = GenericUtils.isEmpty(props) ? null : props.get(name);
-        if (value == null) {
-            return null;
-        } else if (value instanceof Long) {
-            return (Long) value;
-        } else {    // we parse the string in case it is not a valid long value
-            return Long.valueOf(value.toString());
-        }
-    }
-
-    public static Object updateProperty(Channel channel, String name, long value) {
-        return updateProperty(channel.getSession(), name, value);
-    }
-
-    public static Object updateProperty(Session session, String name, long value) {
-        return updateProperty(session.getFactoryManager(), name, value);
-    }
-
-    public static Object updateProperty(FactoryManager manager, String name, long value) {
-        return updateProperty(manager.getProperties(), name, value);
-    }
-
-    public static Object updateProperty(Map<String, Object> props, String name, long value) {
-        return updateProperty(props, name, Long.valueOf(value));
-    }
-
-    public static int getIntProperty(Channel channel, String name, int defaultValue) {
-        return getIntProperty(channel.getSession(), name, defaultValue);
-    }
-
-    public static int getIntProperty(Session session, String name, int defaultValue) {
-        return getIntProperty(session.getFactoryManager(), name, defaultValue);
-    }
-
-    public static int getIntProperty(FactoryManager manager, String name, int defaultValue) {
-        return getIntProperty(manager.getProperties(), name, defaultValue);
-    }
-
-    public static int getIntProperty(Map<String, ?> props, String name, int defaultValue) {
-        Object value = GenericUtils.isEmpty(props) ? null : props.get(name);
-        if (value == null) {
-            return defaultValue;
-        } else if (value instanceof Integer) {
-            return (Integer) value;
-        } else {    // we parse the string in case this is NOT an integer
-            return Integer.parseInt(value.toString());
-        }
-    }
-
-    public static Integer getInteger(Channel channel, String name) {
-        return getInteger(channel.getSession(), name);
-    }
-
-    public static Integer getInteger(Session session, String name) {
-        return getInteger(session.getFactoryManager(), name);
-    }
-
-    public static Integer getInteger(FactoryManager manager, String name) {
-        return getInteger(manager.getProperties(), name);
-    }
-
-    public static Integer getInteger(Map<String, ?> props, String name) {
-        Object value = GenericUtils.isEmpty(props) ? null : props.get(name);
-        if (value == null) {
-            return null;
-        } else if (value instanceof Integer) {
-            return (Integer) value;
-        } else {    // we parse the string in case this is NOT an integer
-            return Integer.valueOf(value.toString());
-        }
-    }
-
-    public static Object updateProperty(Channel channel, String name, int value) {
-        return updateProperty(channel.getSession(), name, value);
-    }
-
-    public static Object updateProperty(Session session, String name, int value) {
-        return updateProperty(session.getFactoryManager(), name, value);
-    }
-
-    public static Object updateProperty(FactoryManager manager, String name, int value) {
-        return updateProperty(manager.getProperties(), name, value);
-    }
-
-    public static Object updateProperty(Map<String, Object> props, String name, int value) {
-        return updateProperty(props, name, Integer.valueOf(value));
-    }
-
-    public static boolean getBooleanProperty(Channel channel, String name, boolean defaultValue) {
-        return getBooleanProperty(channel.getSession(), name, defaultValue);
-    }
-
-    public static boolean getBooleanProperty(Session session, String name, boolean defaultValue) {
-        return getBooleanProperty(session.getFactoryManager(), name, defaultValue);
-    }
-
-    public static boolean getBooleanProperty(FactoryManager manager, String name, boolean defaultValue) {
-        return getBooleanProperty(manager.getProperties(), name, defaultValue);
-    }
-
-    public static boolean getBooleanProperty(Map<String, ?> props, String name, boolean defaultValue) {
-        Boolean value = getBoolean(props, name);
-        if (value == null) {
-            return defaultValue;
-        } else {
-            return value;
-        }
-    }
-
-    public static Boolean getBoolean(Channel channel, String name) {
-        return getBoolean(channel.getSession(), name);
-    }
-
-    public static Boolean getBoolean(Session session, String name) {
-        return getBoolean(session.getFactoryManager(), name);
-    }
-
-    public static Boolean getBoolean(FactoryManager manager, String name) {
-        return getBoolean(manager.getProperties(), name);
-    }
-
-    public static Boolean getBoolean(Map<String, ?> props, String name) {
-        Object value = GenericUtils.isEmpty(props) ? null : props.get(name);
-        if (value == null) {
-            return null;
-        } else if (value instanceof Boolean) {
-            return (Boolean) value;
-        } else {
-            return Boolean.valueOf(value.toString());
-        }
-    }
-
-    public static Object updateProperty(Channel channel, String name, boolean value) {
-        return updateProperty(channel.getSession(), name, value);
-    }
-
-    public static Object updateProperty(Session session, String name, boolean value) {
-        return updateProperty(session.getFactoryManager(), name, value);
-    }
-
-    public static Object updateProperty(FactoryManager manager, String name, boolean value) {
-        return updateProperty(manager.getProperties(), name, value);
-    }
-
-    public static Object updateProperty(Map<String, Object> props, String name, boolean value) {
-        return updateProperty(props, name, Boolean.valueOf(value));
-    }
-
-    public static String getString(Channel channel, String name) {
-        return getString(channel.getSession(), name);
-    }
-
-    public static String getString(Session session, String name) {
-        return getString(session.getFactoryManager(), name);
-    }
-
-    public static String getString(FactoryManager manager, String name) {
-        return getString(manager.getProperties(), name);
-    }
-
-    public static String getStringProperty(Channel channel, String name, String defaultValue) {
-        return getStringProperty(channel.getSession(), name, defaultValue);
-    }
-
-    public static String getStringProperty(Session session, String name, String defaultValue) {
-        return getStringProperty(session.getFactoryManager(), name, defaultValue);
-    }
-
-    public static String getStringProperty(FactoryManager manager, String name, String defaultValue) {
-        return getStringProperty(manager.getProperties(), name, defaultValue);
-    }
-
-    public static String getString(Map<String, ?> props, String name) {
-        return getStringProperty(props, name, null);
-    }
-
-    public static String getStringProperty(Map<String, ?> props, String name, String defaultValue) {
-        Object value = GenericUtils.isEmpty(props) ? null : props.get(name);
-        String s = Objects.toString(value, null);
-        if (GenericUtils.isEmpty(s)) {
-            return defaultValue;
-        } else {
-            return s;
-        }
-    }
-
-    public static Object updateProperty(Channel channel, String name, Object value) {
-        return updateProperty(channel.getSession(), name, value);
-    }
-
-    public static Object updateProperty(Session session, String name, Object value) {
-        return updateProperty(session.getFactoryManager(), name, value);
-    }
-
-    public static Object updateProperty(FactoryManager manager, String name, Object value) {
-        return updateProperty(manager.getProperties(), name, value);
-    }
-
-    /**
-     * @param props The {@link Map} of properties to update
-     * @param name  The property name
-     * @param value The property value - if {@code null}/empty then the
-     *              specified property is <U>removed</U> from the properties map
-     * @return The removed or previous value (if any)
-     */
-    public static Object updateProperty(Map<String, Object> props, String name, Object value) {
-        if ((value == null) || ((value instanceof CharSequence) && GenericUtils.isEmpty((CharSequence) value))) {
-            return props.remove(name);
-        } else {
-            return props.put(name, value);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/PropertyResolver.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/PropertyResolver.java b/sshd-core/src/main/java/org/apache/sshd/common/PropertyResolver.java
new file mode 100644
index 0000000..574a294
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/PropertyResolver.java
@@ -0,0 +1,63 @@
+/*
+ * 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.common;
+
+import java.util.Map;
+
+/**
+ * Indicates an entity that can be configured using properties. The properties
+ * are simple name-value pairs where the actual value type depends on the
+ * property. Some automatic conversions may be available - e.g., from a string
+ * to a numeric or {@code boolean} value, or from {@code int} to {@code long},
+ * etc.. <B>Note:</B> implementations may decide to use case <U>insensitive</U>
+ * property names, therefore it is <U><B>highly discouraged</B></U> to use names
+ * that differ from each other only in case sensitivity. Also, implementations may
+ * choose to trim whitespaces, thus such are also highly discouraged.
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface PropertyResolver {
+    /**
+     * @return The parent resolver that can be used to query for missing
+     * properties - {@code null} if no parent
+     */
+    PropertyResolver getParentPropertyResolver();
+
+    /**
+     * <P>A map of properties that can be used to configure the SSH server
+     * or client.  This map will never be changed by either the server or
+     * client and is not supposed to be changed at runtime (changes are not
+     * bound to have any effect on a running client or server), though it may
+     * affect the creation of sessions later as these values are usually not
+     * cached.</P>
+     *
+     * <P><B>Note:</B> the <U>type</U> of the mapped property should match the
+     * expected configuration value type - {@code Long, Integer, Boolean,
+     * String}, etc.... If it doesn't, the {@code toString()} result of the
+     * mapped value is used to convert it to the required type. E.g., if
+     * the mapped value is the <U>string</U> &quot;1234&quot; and the expected
+     * value is a {@code long} then it will be parsed into one. Also, if
+     * the mapped value is an {@code Integer} but a {@code long} is expected,
+     * then it will be converted into one.</P>
+     *
+     * @return a valid <code>Map</code> containing configuration values, never {@code null}
+     */
+    Map<String, Object> getProperties();
+}