You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by gn...@apache.org on 2016/09/15 19:34:52 UTC

[15/16] mina-sshd git commit: [SSHD-698] Use lambda and method references, streams Deprecate Utils inner classes and use interface methods instead.

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 24c9983..a83dfeb 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
@@ -91,15 +91,11 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
         this.type = ValidateUtils.checkNotNullAndNotEmpty(type, "No channel type specified");
         this.streaming = Streaming.Sync;
 
-        addChannelSignalRequestHandlers(new EventNotifier<String>() {
-            @SuppressWarnings("synthetic-access")
-            @Override
-            public void notifyEvent(String event) throws Exception {
-                if (log.isDebugEnabled()) {
-                    log.debug("notifyEvent({}): {}", AbstractClientChannel.this, event);
-                }
-                notifyStateChanged(event);
+        addChannelSignalRequestHandlers(event -> {
+            if (log.isDebugEnabled()) {
+                log.debug("notifyEvent({}): {}", AbstractClientChannel.this, event);
             }
+            notifyStateChanged(event);
         });
     }
 
@@ -179,24 +175,20 @@ public abstract class AbstractClientChannel extends AbstractChannel implements C
     protected Closeable getInnerCloseable() {
         return builder()
                 .when(openFuture)
-                .run(new Runnable() {
-                    @SuppressWarnings("synthetic-access")
-                    @Override
-                    public void run() {
-                        // If the channel has not been opened yet,
-                        // skip the SSH_MSG_CHANNEL_CLOSE exchange
-                        if (openFuture == null) {
-                            gracefulFuture.setClosed();
-                        }
-                        // Close inverted streams after
-                        // If the inverted stream is closed before, there's a small time window
-                        // in which we have:
-                        //    ChannelPipedInputStream#closed = true
-                        //    ChannelPipedInputStream#writerClosed = false
-                        // which leads to an IOException("Pipe closed") when reading.
-                        IoUtils.closeQuietly(in, out, err);
-                        IoUtils.closeQuietly(invertedIn, invertedOut, invertedErr);
+                .run(() -> {
+                    // If the channel has not been opened yet,
+                    // skip the SSH_MSG_CHANNEL_CLOSE exchange
+                    if (openFuture == null) {
+                        gracefulFuture.setClosed();
                     }
+                    // Close inverted streams after
+                    // If the inverted stream is closed before, there's a small time window
+                    // in which we have:
+                    //    ChannelPipedInputStream#closed = true
+                    //    ChannelPipedInputStream#writerClosed = false
+                    // which leads to an IOException("Pipe closed") when reading.
+                    IoUtils.closeQuietly(in, out, err);
+                    IoUtils.closeQuietly(invertedIn, invertedOut, invertedErr);
                 })
                 .parallel(asyncIn, asyncOut, asyncErr)
                 .close(new GracefulChannelCloseable())

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 e59f7b3..e76aab4 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
@@ -101,12 +101,7 @@ public class ChannelSession extends AbstractClientChannel {
                 // 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
-                pumper = pumperService.submit(new Runnable() {
-                    @Override
-                    public void run() {
-                        pumpInputStream();
-                    }
-                });
+                pumper = pumperService.submit(this::pumpInputStream);
             }
         }
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 2f9119b..132e756 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
@@ -24,8 +24,6 @@ import java.util.Date;
 import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.channel.Channel;
-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;
@@ -112,12 +110,7 @@ public class ChannelSubsystem extends ChannelSession {
     }
 
     public void onClose(final Runnable run) {
-        closeFuture.addListener(new SshFutureListener<CloseFuture>() {
-            @Override
-            public void operationComplete(CloseFuture future) {
-                run.run();
-            }
-        });
+        closeFuture.addListener(future -> run.run());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 08750a3..669ae0d 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
@@ -79,19 +79,15 @@ public class PtyCapableChannelSession extends ChannelSession {
     public static final int DEFAULT_WIDTH = 640;
     public static final int DEFAULT_HEIGHT = 480;
     public static final Map<PtyMode, Integer> DEFAULT_PTY_MODES =
-            Collections.unmodifiableMap(new EnumMap<PtyMode, Integer>(PtyMode.class) {
-                private static final long serialVersionUID = 1L;    // we're not serializing it
-
-                {
-                    put(PtyMode.ISIG, 1);
-                    put(PtyMode.ICANON, 1);
-                    put(PtyMode.ECHO, 1);
-                    put(PtyMode.ECHOE, 1);
-                    put(PtyMode.ECHOK, 1);
-                    put(PtyMode.ECHONL, 0);
-                    put(PtyMode.NOFLSH, 0);
-                }
-            });
+            GenericUtils.<PtyMode, Integer>mapBuilder()
+                .put(PtyMode.ISIG, 1)
+                .put(PtyMode.ICANON, 1)
+                .put(PtyMode.ECHO, 1)
+                .put(PtyMode.ECHOE, 1)
+                .put(PtyMode.ECHOK, 1)
+                .put(PtyMode.ECHONL, 0)
+                .put(PtyMode.NOFLSH, 0)
+                .immutable();
 
     private boolean agentForwarding;
     private boolean usePty;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java b/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
index 20e1f40..d8c08a6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/HostConfigEntry.java
@@ -504,9 +504,7 @@ public class HostConfigEntry extends HostPatternsHolder implements MutableUserHo
             return setProperty(key, value);
         }
 
-        StringBuilder sb = new StringBuilder(curVal.length() + value.length() + 1);
-        sb.append(curVal).append(',').append(value);
-        return setProperty(key, sb.toString());
+        return setProperty(key, curVal + ',' + value);
     }
 
     /**
@@ -671,22 +669,19 @@ public class HostConfigEntry extends HostPatternsHolder implements MutableUserHo
         if (GenericUtils.isEmpty(entries)) {
             return HostConfigEntryResolver.EMPTY;
         } else {
-            return new HostConfigEntryResolver() {
-                @Override
-                public HostConfigEntry resolveEffectiveHost(String host, int port, String username) throws IOException {
-                    List<HostConfigEntry> matches = findMatchingEntries(host, entries);
-                    int numMatches = GenericUtils.size(matches);
-                    if (numMatches <= 0) {
-                        return null;
-                    }
-
-                    HostConfigEntry match = (numMatches == 1) ? matches.get(0) : findBestMatch(matches);
-                    if (match == null) {
-                        ValidateUtils.throwIllegalArgumentException("No best match found for %s@%s:%d out of %d matches", username, host, port, numMatches);
-                    }
+            return (host1, port1, username1) -> {
+                List<HostConfigEntry> matches = findMatchingEntries(host1, entries);
+                int numMatches = GenericUtils.size(matches);
+                if (numMatches <= 0) {
+                    return null;
+                }
 
-                    return normalizeEntry(match, host, port, username);
+                HostConfigEntry match = (numMatches == 1) ? matches.get(0) : findBestMatch(matches);
+                if (match == null) {
+                    ValidateUtils.throwIllegalArgumentException("No best match found for %s@%s:%d out of %d matches", username1, host1, port1, numMatches);
                 }
+
+                return normalizeEntry(match, host1, port1, username1);
             };
         }
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/KnownHostDigest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/KnownHostDigest.java b/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/KnownHostDigest.java
index 3005f47..1710194 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/KnownHostDigest.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/hosts/KnownHostDigest.java
@@ -60,6 +60,6 @@ public enum KnownHostDigest implements NamedFactory<Mac> {
     }
 
     public static KnownHostDigest fromName(String name) {
-        return NamedResource.Utils.findByName(name, String.CASE_INSENSITIVE_ORDER, VALUES);
+        return NamedResource.findByName(name, String.CASE_INSENSITIVE_ORDER, VALUES);
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
index fb9abce..29aee8d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
@@ -43,7 +43,7 @@ public class BuiltinClientIdentitiesWatcher extends ClientIdentitiesWatcher {
 
     public BuiltinClientIdentitiesWatcher(Path keysFolder, boolean supportedOnly,
             ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
-        this(keysFolder, NamedResource.Utils.getNameList(BuiltinIdentities.VALUES), supportedOnly, loader, provider, strict);
+        this(keysFolder, NamedResource.getNameList(BuiltinIdentities.VALUES), supportedOnly, loader, provider, strict);
     }
 
     public BuiltinClientIdentitiesWatcher(Path keysFolder, Collection<String> ids, boolean supportedOnly,
@@ -56,7 +56,7 @@ public class BuiltinClientIdentitiesWatcher extends ClientIdentitiesWatcher {
 
     public BuiltinClientIdentitiesWatcher(Path keysFolder, boolean supportedOnly,
             Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
-        this(keysFolder, NamedResource.Utils.getNameList(BuiltinIdentities.VALUES), supportedOnly, loader, provider, strict);
+        this(keysFolder, NamedResource.getNameList(BuiltinIdentities.VALUES), supportedOnly, loader, provider, strict);
     }
 
     public BuiltinClientIdentitiesWatcher(Path keysFolder, Collection<String> ids, boolean supportedOnly,
@@ -94,19 +94,13 @@ public class BuiltinClientIdentitiesWatcher extends ClientIdentitiesWatcher {
             toRemove.add(kp);
         }
 
-        if (GenericUtils.isEmpty(toRemove)) {
-            return keys;
-        }
-
-        for (KeyPair kp : toRemove) {
-            keys.remove(kp);
-        }
+        GenericUtils.forEach(toRemove, keys::remove);
 
         return keys;
     }
 
     public static List<Path> getDefaultBuiltinIdentitiesPaths(Path keysFolder) {
-        return getBuiltinIdentitiesPaths(keysFolder, NamedResource.Utils.getNameList(BuiltinIdentities.VALUES));
+        return getBuiltinIdentitiesPaths(keysFolder, NamedResource.getNameList(BuiltinIdentities.VALUES));
     }
 
     public static List<Path> getBuiltinIdentitiesPaths(Path keysFolder, Collection<String> ids) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
index c3dfe01..3c90060 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
@@ -111,11 +111,6 @@ public class ClientIdentitiesWatcher extends AbstractKeyPairProvider implements
             return Collections.emptyList();
         }
 
-        List<ClientIdentityProvider> providers = new ArrayList<>(paths.size());
-        for (Path p : paths) {
-            providers.add(new ClientIdentityFileWatcher(p, loader, provider, strict));
-        }
-
-        return providers;
+        return GenericUtils.map(paths, p -> new ClientIdentityFileWatcher(p, loader, provider, strict));
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentity.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentity.java b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentity.java
index e3e7b3c..7554b8d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentity.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentity.java
@@ -56,12 +56,7 @@ public final class ClientIdentity {
     public static final String ID_FILE_SUFFIX = "";
 
     public static final Transformer<String, String> ID_GENERATOR =
-        new Transformer<String, String>() {
-            @Override
-            public String transform(String input) {
-                return getIdentityFileName(input);
-            }
-        };
+            ClientIdentity::getIdentityFileName;
 
     private ClientIdentity() {
         throw new UnsupportedOperationException("No instance");

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
index dc736f9..1641095 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
@@ -54,7 +54,7 @@ public class DHGClient extends AbstractDHClientKeyExchange {
         return factory.getName();
     }
 
-    public static final KeyExchangeFactory newFactory(final DHFactory delegate) {
+    public static KeyExchangeFactory newFactory(final DHFactory delegate) {
         return new KeyExchangeFactory() {
             @Override
             public String getName() {
@@ -100,11 +100,11 @@ public class DHGClient extends AbstractDHClientKeyExchange {
     public boolean next(int cmd, Buffer buffer) throws Exception {
         Session session = getSession();
         if (log.isDebugEnabled()) {
-            log.debug("next({})[{}] process command={}", this, session, KeyExchange.Utils.getSimpleKexOpcodeName(cmd));
+            log.debug("next({})[{}] process command={}", this, session, KeyExchange.getSimpleKexOpcodeName(cmd));
         }
         if (cmd != SshConstants.SSH_MSG_KEXDH_REPLY) {
             throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
-                    "Protocol error: expected packet SSH_MSG_KEXDH_REPLY, got " + KeyExchange.Utils.getSimpleKexOpcodeName(cmd));
+                    "Protocol error: expected packet SSH_MSG_KEXDH_REPLY, got " + KeyExchange.getSimpleKexOpcodeName(cmd));
         }
 
         byte[] k_s = buffer.getBytes();
@@ -132,7 +132,7 @@ public class DHGClient extends AbstractDHClientKeyExchange {
         hash.update(buffer.array(), 0, buffer.available());
         h = hash.digest();
 
-        Signature verif = ValidateUtils.checkNotNull(NamedFactory.Utils.create(session.getSignatureFactories(), keyAlg),
+        Signature verif = ValidateUtils.checkNotNull(NamedFactory.create(session.getSignatureFactories(), keyAlg),
                 "No verifier located for algorithm=%s",
                 keyAlg);
         verif.initVerifier(serverKey);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
index 644ab48..16bfcbe 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
@@ -103,13 +103,13 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
     public boolean next(int cmd, Buffer buffer) throws Exception {
         Session session = getSession();
         if (log.isDebugEnabled()) {
-            log.debug("next({})[{}] process command={}", this, session, KeyExchange.Utils.getGroupKexOpcodeName(cmd));
+            log.debug("next({})[{}] process command={}", this, session, KeyExchange.getGroupKexOpcodeName(cmd));
         }
 
         if (cmd != expected) {
             throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
-                    "Protocol error: expected packet " + KeyExchange.Utils.getGroupKexOpcodeName(expected)
-                  + ", got " + KeyExchange.Utils.getGroupKexOpcodeName(cmd));
+                    "Protocol error: expected packet " + KeyExchange.getGroupKexOpcodeName(expected)
+                  + ", got " + KeyExchange.getGroupKexOpcodeName(cmd));
         }
 
         if (cmd == SshConstants.SSH_MSG_KEX_DH_GEX_GROUP) {
@@ -163,7 +163,7 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
             h = hash.digest();
 
             Signature verif = ValidateUtils.checkNotNull(
-                    NamedFactory.Utils.create(session.getSignatureFactories(), keyAlg),
+                    NamedFactory.create(session.getSignatureFactories(), keyAlg),
                     "No verifier located for algorithm=%s",
                     keyAlg);
             verif.initVerifier(serverKey);
@@ -175,7 +175,7 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
             return true;
         }
 
-        throw new IllegalStateException("Unknown command value: " + KeyExchange.Utils.getGroupKexOpcodeName(cmd));
+        throw new IllegalStateException("Unknown command value: " + KeyExchange.getGroupKexOpcodeName(cmd));
     }
 
     protected AbstractDH getDH(BigInteger p, BigInteger g) throws Exception {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 f798de5..233abf1 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
@@ -144,23 +144,21 @@ public abstract class AbstractScpClient extends AbstractLoggingBean implements S
     @Override
     public void upload(String[] local, String remote, Collection<Option> options) throws IOException {
         final Collection<String> paths = Arrays.asList(ValidateUtils.checkNotNullAndNotEmpty(local, "Invalid argument local: %s", (Object) local));
-        runUpload(remote, options, paths, new ScpOperationExecutor<String>() {
-            @Override
-            public void execute(ScpHelper helper, Collection<String> local, Collection<Option> sendOptions) throws IOException {
-                helper.send(local, sendOptions.contains(Option.Recursive), sendOptions.contains(Option.PreserveAttributes), ScpHelper.DEFAULT_SEND_BUFFER_SIZE);
-            }
-        });
+        runUpload(remote, options, paths, (helper, local1, sendOptions) ->
+                helper.send(local1,
+                            sendOptions.contains(Option.Recursive),
+                            sendOptions.contains(Option.PreserveAttributes),
+                            ScpHelper.DEFAULT_SEND_BUFFER_SIZE));
     }
 
     @Override
     public void upload(Path[] local, String remote, Collection<Option> options) throws IOException {
         final Collection<Path> paths = Arrays.asList(ValidateUtils.checkNotNullAndNotEmpty(local, "Invalid argument local: %s", (Object) local));
-        runUpload(remote, options, paths, new ScpOperationExecutor<Path>() {
-            @Override
-            public void execute(ScpHelper helper, Collection<Path> local, Collection<Option> sendOptions) throws IOException {
-                helper.sendPaths(local, sendOptions.contains(Option.Recursive), sendOptions.contains(Option.PreserveAttributes), ScpHelper.DEFAULT_SEND_BUFFER_SIZE);
-            }
-        });
+        runUpload(remote, options, paths, (helper, local1, sendOptions) ->
+                helper.sendPaths(local1,
+                                 sendOptions.contains(Option.Recursive),
+                                 sendOptions.contains(Option.PreserveAttributes),
+                                 ScpHelper.DEFAULT_SEND_BUFFER_SIZE));
     }
 
     protected abstract <T> void runUpload(String remote, Collection<Option> options, Collection<T> local, AbstractScpClient.ScpOperationExecutor<T> executor) throws IOException;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
index b7453f8..9894bfd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
@@ -93,7 +93,7 @@ public abstract class AbstractClientSession extends AbstractSession implements C
 
     protected AbstractClientSession(ClientFactoryManager factoryManager, IoSession ioSession) {
         super(false, factoryManager, ioSession);
-        identitiesProvider = AuthenticationIdentitiesProvider.Utils.wrap(identities);
+        identitiesProvider = AuthenticationIdentitiesProvider.wrap(identities);
     }
 
     @Override
@@ -179,8 +179,8 @@ public abstract class AbstractClientSession extends AbstractSession implements C
             return null;
         }
 
-        int index = AuthenticationIdentitiesProvider.Utils.findIdentityIndex(
-                identities, AuthenticationIdentitiesProvider.Utils.PASSWORD_IDENTITY_COMPARATOR, password);
+        int index = AuthenticationIdentitiesProvider.findIdentityIndex(
+                identities, AuthenticationIdentitiesProvider.PASSWORD_IDENTITY_COMPARATOR, password);
         if (index >= 0) {
             return (String) identities.remove(index);
         } else {
@@ -209,8 +209,8 @@ public abstract class AbstractClientSession extends AbstractSession implements C
             return null;
         }
 
-        int index = AuthenticationIdentitiesProvider.Utils.findIdentityIndex(
-                identities, AuthenticationIdentitiesProvider.Utils.KEYPAIR_IDENTITY_COMPARATOR, kp);
+        int index = AuthenticationIdentitiesProvider.findIdentityIndex(
+                identities, AuthenticationIdentitiesProvider.KEYPAIR_IDENTITY_COMPARATOR, kp);
         if (index >= 0) {
             return (KeyPair) identities.remove(index);
         } else {
@@ -355,7 +355,7 @@ public abstract class AbstractClientSession extends AbstractSession implements C
 
     @Override
     public FileSystem createSftpFileSystem(int version) throws IOException {
-        return createSftpFileSystem(SftpVersionSelector.Utils.fixedVersionSelector(version));
+        return createSftpFileSystem(SftpVersionSelector.fixedVersionSelector(version));
     }
 
     @Override
@@ -365,7 +365,7 @@ public abstract class AbstractClientSession extends AbstractSession implements C
 
     @Override
     public FileSystem createSftpFileSystem(int version, int readBufferSize, int writeBufferSize) throws IOException {
-        return createSftpFileSystem(SftpVersionSelector.Utils.fixedVersionSelector(version), readBufferSize, writeBufferSize);
+        return createSftpFileSystem(SftpVersionSelector.fixedVersionSelector(version), readBufferSize, writeBufferSize);
     }
 
     @Override
@@ -421,7 +421,7 @@ public abstract class AbstractClientSession extends AbstractSession implements C
     protected String resolveAvailableSignaturesProposal(FactoryManager manager) {
         // the client does not have to provide keys for the available signatures
         ValidateUtils.checkTrue(manager == getFactoryManager(), "Mismatched factory manager instances");
-        return NamedResource.Utils.getNames(getSignatureFactories());
+        return NamedResource.getNames(getSignatureFactories());
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 e55517d..1377e99 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
@@ -64,12 +64,7 @@ public class ClientConnectionService extends AbstractConnectionService<AbstractC
         if (interval > 0L) {
             FactoryManager manager = session.getFactoryManager();
             ScheduledExecutorService service = manager.getScheduledExecutorService();
-            service.scheduleAtFixedRate(new Runnable() {
-                @Override
-                public void run() {
-                    sendHeartBeat();
-                }
-            }, interval, interval, TimeUnit.MILLISECONDS);
+            service.scheduleAtFixedRate(this::sendHeartBeat, interval, interval, TimeUnit.MILLISECONDS);
             if (log.isDebugEnabled()) {
                 log.debug("startHeartbeat - started at interval={}", interval);
             }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 aac8d57..e9a019a 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
@@ -88,7 +88,7 @@ public class ClientUserAuthService
             }
 
             for (String pref : GenericUtils.split(prefs, ',')) {
-                NamedFactory<UserAuth> factory = NamedResource.Utils.findByName(pref, String.CASE_INSENSITIVE_ORDER, authFactories);
+                NamedFactory<UserAuth> factory = NamedResource.findByName(pref, String.CASE_INSENSITIVE_ORDER, authFactories);
                 if (factory != null) {
                     clientMethods.add(pref);
                 } else {
@@ -318,7 +318,7 @@ public class ClientUserAuthService
                 return;
             }
 
-            userAuth = NamedFactory.Utils.create(authFactories, method);
+            userAuth = NamedFactory.create(authFactories, method);
             if (userAuth == null) {
                 throw new UnsupportedOperationException("Failed to find a user-auth factory for method=" + method);
             }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java
index 4a65e5c..90007c5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClient.java
@@ -20,8 +20,6 @@
 package org.apache.sshd.client.simple;
 
 import java.io.IOException;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
@@ -45,46 +43,6 @@ public abstract class AbstractSimpleClient extends AbstractLoggingBean implement
     }
 
     @Override
-    public SftpClient sftpLogin(String host, String username, String password) throws IOException {
-        return sftpLogin(host, DEFAULT_PORT, username, password);
-    }
-
-    @Override
-    public SftpClient sftpLogin(String host, int port, String username, String password) throws IOException {
-        return sftpLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, password);
-    }
-
-    @Override
-    public SftpClient sftpLogin(String host, String username, KeyPair identity) throws IOException {
-        return sftpLogin(host, DEFAULT_PORT, username, identity);
-    }
-
-    @Override
-    public SftpClient sftpLogin(String host, int port, String username, KeyPair identity) throws IOException {
-        return sftpLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, identity);
-    }
-
-    @Override
-    public SftpClient sftpLogin(InetAddress host, String username, String password) throws IOException {
-        return sftpLogin(host, DEFAULT_PORT, username, password);
-    }
-
-    @Override
-    public SftpClient sftpLogin(InetAddress host, int port, String username, String password) throws IOException {
-        return sftpLogin(new InetSocketAddress(ValidateUtils.checkNotNull(host, "No host address"), port), username, password);
-    }
-
-    @Override
-    public SftpClient sftpLogin(InetAddress host, String username, KeyPair identity) throws IOException {
-        return sftpLogin(host, DEFAULT_PORT, username, identity);
-    }
-
-    @Override
-    public SftpClient sftpLogin(InetAddress host, int port, String username, KeyPair identity) throws IOException {
-        return sftpLogin(new InetSocketAddress(ValidateUtils.checkNotNull(host, "No host address"), port), username, identity);
-    }
-
-    @Override
     public SftpClient sftpLogin(SocketAddress target, String username, String password) throws IOException {
         return createSftpClient(sessionLogin(target, username, password));
     }
@@ -148,42 +106,38 @@ public abstract class AbstractSimpleClient extends AbstractLoggingBean implement
     protected SftpClient createSftpClient(final ClientSession session, final SftpClient client) throws IOException {
         ClassLoader loader = getClass().getClassLoader();
         Class<?>[] interfaces = {SftpClient.class};
-        return (SftpClient) Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
-            @SuppressWarnings("synthetic-access")
-            @Override
-            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                Throwable err = null;
-                Object result = null;
-                String name = method.getName();
+        return (SftpClient) Proxy.newProxyInstance(loader, interfaces, (proxy, method, args) -> {
+            Throwable err = null;
+            Object result = null;
+            String name = method.getName();
+            try {
+                result = method.invoke(client, args);
+            } catch (Throwable t) {
+                if (log.isTraceEnabled()) {
+                    log.trace("invoke(SftpClient#{}) failed ({}) to execute: {}",
+                              name, t.getClass().getSimpleName(), t.getMessage());
+                }
+                err = GenericUtils.accumulateException(err, t);
+            }
+
+            // propagate the "close" call to the session as well
+            if ("close".equals(name) && GenericUtils.isEmpty(args)) {
                 try {
-                    result = method.invoke(client, args);
+                    session.close();
                 } catch (Throwable t) {
-                    if (log.isTraceEnabled()) {
-                        log.trace("invoke(SftpClient#{}) failed ({}) to execute: {}",
+                    if (log.isDebugEnabled()) {
+                        log.debug("invoke(ClientSession#{}) failed ({}) to execute: {}",
                                   name, t.getClass().getSimpleName(), t.getMessage());
                     }
                     err = GenericUtils.accumulateException(err, t);
                 }
+            }
 
-                // propagate the "close" call to the session as well
-                if ("close".equals(name) && GenericUtils.isEmpty(args)) {
-                    try {
-                        session.close();
-                    } catch (Throwable t) {
-                        if (log.isDebugEnabled()) {
-                            log.debug("invoke(ClientSession#{}) failed ({}) to execute: {}",
-                                      name, t.getClass().getSimpleName(), t.getMessage());
-                        }
-                        err = GenericUtils.accumulateException(err, t);
-                    }
-                }
-
-                if (err != null) {
-                    throw err;
-                }
-
-                return result;
+            if (err != null) {
+                throw err;
             }
+
+            return result;
         });
     }
     @Override
@@ -241,25 +195,21 @@ public abstract class AbstractSimpleClient extends AbstractLoggingBean implement
             final ScpClient client = ValidateUtils.checkNotNull(session, "No client session").createScpClient();
             ClassLoader loader = getClass().getClassLoader();
             Class<?>[] interfaces = {CloseableScpClient.class};
-            return (CloseableScpClient) Proxy.newProxyInstance(loader, interfaces, new InvocationHandler() {
-                @SuppressWarnings("synthetic-access")
-                @Override
-                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                    String name = method.getName();
-                    try {
-                        // The Channel implementation is provided by the session
-                        if (("close".equals(name) || "isOpen".equals(name)) && GenericUtils.isEmpty(args)) {
-                            return method.invoke(session, args);
-                        } else {
-                            return method.invoke(client, args);
-                        }
-                    } catch (Throwable t) {
-                        if (log.isTraceEnabled()) {
-                            log.trace("invoke(CloseableScpClient#{}) failed ({}) to execute: {}",
-                                      name, t.getClass().getSimpleName(), t.getMessage());
-                        }
-                        throw t;
+            return (CloseableScpClient) Proxy.newProxyInstance(loader, interfaces, (proxy, method, args) -> {
+                String name = method.getName();
+                try {
+                    // The Channel implementation is provided by the session
+                    if (("close".equals(name) || "isOpen".equals(name)) && GenericUtils.isEmpty(args)) {
+                        return method.invoke(session, args);
+                    } else {
+                        return method.invoke(client, args);
+                    }
+                } catch (Throwable t) {
+                    if (log.isTraceEnabled()) {
+                        log.trace("invoke(CloseableScpClient#{}) failed ({}) to execute: {}",
+                                  name, t.getClass().getSimpleName(), t.getMessage());
                     }
+                    throw t;
                 }
             });
         } catch (Exception e) {
@@ -287,43 +237,4 @@ public abstract class AbstractSimpleClient extends AbstractLoggingBean implement
         }
     }
 
-    @Override   // TODO make this a default method in Java-8
-    public ClientSession sessionLogin(String host, String username, String password) throws IOException {
-        return sessionLogin(host, DEFAULT_PORT, username, password);
-    }
-
-    @Override   // TODO make this a default method in Java-8
-    public ClientSession sessionLogin(String host, String username, KeyPair identity) throws IOException {
-        return sessionLogin(host, DEFAULT_PORT, username, identity);
-    }
-
-    @Override   // TODO make this a default method in Java-8
-    public ClientSession sessionLogin(InetAddress host, String username, String password) throws IOException {
-        return sessionLogin(host, DEFAULT_PORT, username, password);
-    }
-
-    @Override
-    public ClientSession sessionLogin(InetAddress host, String username, KeyPair identity) throws IOException {
-        return sessionLogin(host, DEFAULT_PORT, username, identity);
-    }
-
-    @Override   // TODO make this a default method in Java-8
-    public ClientSession sessionLogin(String host, int port, String username, String password) throws IOException {
-        return sessionLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, password);
-    }
-
-    @Override   // TODO make this a default method in Java-8
-    public ClientSession sessionLogin(InetAddress host, int port, String username, String password) throws IOException {
-        return sessionLogin(new InetSocketAddress(ValidateUtils.checkNotNull(host, "No host address"), port), username, password);
-    }
-
-    @Override   // TODO make this a default method in Java-8
-    public ClientSession sessionLogin(String host, int port, String username, KeyPair identity) throws IOException {
-        return sessionLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, identity);
-    }
-
-    @Override
-    public ClientSession sessionLogin(InetAddress host, int port, String username, KeyPair identity) throws IOException {
-        return sessionLogin(new InetSocketAddress(ValidateUtils.checkNotNull(host, "No host address"), port), username, identity);
-    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
index c6fe238..0a44c22 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/simple/AbstractSimpleClientSessionCreator.java
@@ -151,7 +151,7 @@ public abstract class AbstractSimpleClientSessionCreator extends AbstractSimpleC
 
             @Override
             public ConnectFuture connect(HostConfigEntry hostConfig) throws IOException {
-                return connect(hostConfig);
+                return creator.connect(hostConfig);
             }
 
             @Override

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSessionClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSessionClient.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSessionClient.java
index a21257a..d15a496 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSessionClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSessionClient.java
@@ -21,11 +21,13 @@ package org.apache.sshd.client.simple;
 
 import java.io.IOException;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.nio.channels.Channel;
 import java.security.KeyPair;
 
 import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * A simplified <U>synchronous</U> API for creating client sessions
@@ -42,7 +44,9 @@ public interface SimpleSessionClient extends SimpleClientConfigurator, Channel {
      * @return Created {@link ClientSession}
      * @throws IOException If failed to login or authenticate
      */
-    ClientSession sessionLogin(String host, String username, String password) throws IOException;
+    default ClientSession sessionLogin(String host, String username, String password) throws IOException {
+        return sessionLogin(host, DEFAULT_PORT, username, password);
+    }
 
     /**
      * Creates a session and logs in using the provided credentials
@@ -54,7 +58,9 @@ public interface SimpleSessionClient extends SimpleClientConfigurator, Channel {
      * @return Created {@link ClientSession}
      * @throws IOException If failed to login or authenticate
      */
-    ClientSession sessionLogin(String host, int port, String username, String password) throws IOException;
+    default ClientSession sessionLogin(String host, int port, String username, String password) throws IOException {
+        return sessionLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, password);
+    }
 
     /**
      * Creates a session on the default port and logs in using the provided credentials
@@ -65,7 +71,9 @@ public interface SimpleSessionClient extends SimpleClientConfigurator, Channel {
      * @return Created {@link ClientSession}
      * @throws IOException If failed to login or authenticate
      */
-    ClientSession sessionLogin(String host, String username, KeyPair identity) throws IOException;
+    default ClientSession sessionLogin(String host, String username, KeyPair identity) throws IOException {
+        return sessionLogin(host, DEFAULT_PORT, username, identity);
+    }
 
     /**
      * Creates a session and logs in using the provided credentials
@@ -77,7 +85,9 @@ public interface SimpleSessionClient extends SimpleClientConfigurator, Channel {
      * @return Created {@link ClientSession}
      * @throws IOException If failed to login or authenticate
      */
-    ClientSession sessionLogin(String host, int port, String username, KeyPair identity) throws IOException;
+    default ClientSession sessionLogin(String host, int port, String username, KeyPair identity) throws IOException {
+        return sessionLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, identity);
+    }
 
     /**
      * Creates a session on the default port and logs in using the provided credentials
@@ -88,7 +98,9 @@ public interface SimpleSessionClient extends SimpleClientConfigurator, Channel {
      * @return Created {@link ClientSession}
      * @throws IOException If failed to login or authenticate
      */
-    ClientSession sessionLogin(InetAddress host, String username, String password) throws IOException;
+    default ClientSession sessionLogin(InetAddress host, String username, String password) throws IOException {
+        return sessionLogin(host, DEFAULT_PORT, username, password);
+    }
 
     /**
      * Creates a session and logs in using the provided credentials
@@ -100,7 +112,9 @@ public interface SimpleSessionClient extends SimpleClientConfigurator, Channel {
      * @return Created {@link ClientSession}
      * @throws IOException If failed to login or authenticate
      */
-    ClientSession sessionLogin(InetAddress host, int port, String username, String password) throws IOException;
+    default ClientSession sessionLogin(InetAddress host, int port, String username, String password) throws IOException {
+        return sessionLogin(new InetSocketAddress(ValidateUtils.checkNotNull(host, "No host address"), port), username, password);
+    }
 
     /**
      * Creates a session on the default port and logs in using the provided credentials
@@ -111,7 +125,9 @@ public interface SimpleSessionClient extends SimpleClientConfigurator, Channel {
      * @return Created {@link ClientSession}
      * @throws IOException If failed to login or authenticate
      */
-    ClientSession sessionLogin(InetAddress host, String username, KeyPair identity) throws IOException;
+    default ClientSession sessionLogin(InetAddress host, String username, KeyPair identity) throws IOException {
+        return sessionLogin(host, DEFAULT_PORT, username, identity);
+    }
 
     /**
      * Creates a session and logs in using the provided credentials
@@ -123,7 +139,9 @@ public interface SimpleSessionClient extends SimpleClientConfigurator, Channel {
      * @return Created {@link ClientSession}
      * @throws IOException If failed to login or authenticate
      */
-    ClientSession sessionLogin(InetAddress host, int port, String username, KeyPair identity) throws IOException;
+    default ClientSession sessionLogin(InetAddress host, int port, String username, KeyPair identity) throws IOException {
+        return sessionLogin(new InetSocketAddress(ValidateUtils.checkNotNull(host, "No host address"), port), username, identity);
+    }
 
     /**
      * Creates a session and logs in using the provided credentials

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSftpClient.java
index fb52aee..8776ad3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/simple/SimpleSftpClient.java
@@ -21,11 +21,13 @@ package org.apache.sshd.client.simple;
 
 import java.io.IOException;
 import java.net.InetAddress;
+import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.nio.channels.Channel;
 import java.security.KeyPair;
 
 import org.apache.sshd.client.subsystem.sftp.SftpClient;
+import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * A simplified <U>synchronous</U> API for obtaining SFTP sessions.
@@ -43,7 +45,9 @@ public interface SimpleSftpClient extends SimpleClientConfigurator, Channel {
      * underlying session
      * @throws IOException If failed to login or authenticate
      */
-    SftpClient sftpLogin(String host, String username, String password) throws IOException;
+    default SftpClient sftpLogin(String host, String username, String password) throws IOException {
+        return sftpLogin(host, DEFAULT_PORT, username, password);
+    }
 
     /**
      * Creates an SFTP session using the provided credentials
@@ -56,7 +60,9 @@ public interface SimpleSftpClient extends SimpleClientConfigurator, Channel {
      * underlying session
      * @throws IOException If failed to login or authenticate
      */
-    SftpClient sftpLogin(String host, int port, String username, String password) throws IOException;
+    default SftpClient sftpLogin(String host, int port, String username, String password) throws IOException {
+        return sftpLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, password);
+    }
 
     /**
      * Creates an SFTP session on the default port and logs in using the provided credentials
@@ -68,7 +74,9 @@ public interface SimpleSftpClient extends SimpleClientConfigurator, Channel {
      * underlying session
      * @throws IOException If failed to login or authenticate
      */
-    SftpClient sftpLogin(String host, String username, KeyPair identity) throws IOException;
+    default SftpClient sftpLogin(String host, String username, KeyPair identity) throws IOException {
+        return sftpLogin(host, DEFAULT_PORT, username, identity);
+    }
 
     /**
      * Creates an SFTP session using the provided credentials
@@ -81,7 +89,9 @@ public interface SimpleSftpClient extends SimpleClientConfigurator, Channel {
      * underlying session
      * @throws IOException If failed to login or authenticate
      */
-    SftpClient sftpLogin(String host, int port, String username, KeyPair identity) throws IOException;
+    default SftpClient sftpLogin(String host, int port, String username, KeyPair identity) throws IOException {
+        return sftpLogin(InetAddress.getByName(ValidateUtils.checkNotNullAndNotEmpty(host, "No host")), port, username, identity);
+    }
 
     /**
      * Creates an SFTP session on the default port and logs in using the provided credentials
@@ -93,7 +103,9 @@ public interface SimpleSftpClient extends SimpleClientConfigurator, Channel {
      * underlying session
      * @throws IOException If failed to login or authenticate
      */
-    SftpClient sftpLogin(InetAddress host, String username, String password) throws IOException;
+    default SftpClient sftpLogin(InetAddress host, String username, String password) throws IOException {
+        return sftpLogin(host, DEFAULT_PORT, username, password);
+    }
 
     /**
      * Creates an SFTP session using the provided credentials
@@ -106,7 +118,9 @@ public interface SimpleSftpClient extends SimpleClientConfigurator, Channel {
      * underlying session
      * @throws IOException If failed to login or authenticate
      */
-    SftpClient sftpLogin(InetAddress host, int port, String username, String password) throws IOException;
+    default SftpClient sftpLogin(InetAddress host, int port, String username, String password) throws IOException {
+        return sftpLogin(new InetSocketAddress(ValidateUtils.checkNotNull(host, "No host address"), port), username, password);
+    }
 
     /**
      * Creates an SFTP session on the default port and logs in using the provided credentials
@@ -118,7 +132,9 @@ public interface SimpleSftpClient extends SimpleClientConfigurator, Channel {
      * underlying session
      * @throws IOException If failed to login or authenticate
      */
-    SftpClient sftpLogin(InetAddress host, String username, KeyPair identity) throws IOException;
+    default SftpClient sftpLogin(InetAddress host, String username, KeyPair identity) throws IOException {
+        return sftpLogin(host, DEFAULT_PORT, username, identity);
+    }
 
     /**
      * Creates an SFTP session using the provided credentials
@@ -131,7 +147,9 @@ public interface SimpleSftpClient extends SimpleClientConfigurator, Channel {
      * underlying session
      * @throws IOException If failed to login or authenticate
      */
-    SftpClient sftpLogin(InetAddress host, int port, String username, KeyPair identity) throws IOException;
+    default SftpClient sftpLogin(InetAddress host, int port, String username, KeyPair identity) throws IOException {
+        return sftpLogin(new InetSocketAddress(ValidateUtils.checkNotNull(host, "No host address"), port), username, identity);
+    }
 
     /**
      * Creates an SFTP session using the provided credentials

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
index ecf6ffb..848790c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
@@ -141,6 +141,7 @@ public abstract class AbstractSftpClient extends AbstractSubsystemClient impleme
             String lang = buffer.getString();
             checkResponseStatus(cmd, id, substatus, msg, lang);
         } else {
+            //noinspection ThrowableResultOfMethodCallIgnored
             handleUnexpectedPacket(cmd, SftpConstants.SSH_FXP_STATUS, id, type, length, buffer);
         }
     }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 dddcfd5..8650332 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
@@ -89,18 +89,14 @@ public class DefaultSftpClient extends AbstractSftpClient {
 
         long initializationTimeout = PropertyResolverUtils.getLongProperty(clientSession, SFTP_CHANNEL_OPEN_TIMEOUT, DEFAULT_CHANNEL_OPEN_TIMEOUT);
         this.channel.open().verify(initializationTimeout);
-        this.channel.onClose(new Runnable() {
-            @SuppressWarnings("synthetic-access")
-            @Override
-            public void run() {
-                synchronized (messages) {
-                    closing.set(true);
-                    messages.notifyAll();
-                }
+        this.channel.onClose(() -> {
+            synchronized (messages) {
+                closing.set(true);
+                messages.notifyAll();
+            }
 
-                if (versionHolder.get() <= 0) {
-                    log.warn("onClose({}) closed before version negotiated", channel);
-                }
+            if (versionHolder.get() <= 0) {
+                log.warn("onClose({}) closed before version negotiated", channel);
             }
         });
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClientCreator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClientCreator.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClientCreator.java
index 2f93c90..8e41729 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClientCreator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClientCreator.java
@@ -46,7 +46,7 @@ public interface SftpClientCreator {
      * @throws IOException If failed to create the client or use the specified version
      */
     default SftpClient createSftpClient(int version) throws IOException {
-        return createSftpClient(SftpVersionSelector.Utils.fixedVersionSelector(version));
+        return createSftpClient(SftpVersionSelector.fixedVersionSelector(version));
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 4a1bc7a..96c40a4 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
@@ -27,7 +27,6 @@ import java.nio.file.FileSystemException;
 import java.nio.file.attribute.GroupPrincipal;
 import java.nio.file.attribute.UserPrincipal;
 import java.nio.file.attribute.UserPrincipalLookupService;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -56,9 +55,7 @@ public class SftpFileSystem extends BaseFileSystem<SftpPath> implements ClientSe
     public static final Set<String> UNIVERSAL_SUPPORTED_VIEWS =
             Collections.unmodifiableSet(
                     GenericUtils.asSortedSet(String.CASE_INSENSITIVE_ORDER,
-                            Arrays.asList(
-                                    "basic", "posix", "owner"
-                            )));
+                            "basic", "posix", "owner"));
 
     private final String id;
     private final ClientSession clientSession;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/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 48b10d2..3ecd93c 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
@@ -118,15 +118,12 @@ public class SftpFileSystemProvider extends FileSystemProvider {
     public static final String VERSION_PARAM = "version";
 
     public static final Set<Class<? extends FileAttributeView>> UNIVERSAL_SUPPORTED_VIEWS =
-            Collections.unmodifiableSet(new HashSet<Class<? extends FileAttributeView>>() {
-                private static final long serialVersionUID = 1L;    // we're not serializing it
+            Collections.unmodifiableSet(GenericUtils.asSet(
+                    PosixFileAttributeView.class,
+                    FileOwnerAttributeView.class,
+                    BasicFileAttributeView.class
+            ));
 
-                {
-                    add(PosixFileAttributeView.class);
-                    add(FileOwnerAttributeView.class);
-                    add(BasicFileAttributeView.class);
-                }
-            });
     protected final Logger log;
 
     private final SshClient client;
@@ -270,7 +267,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
 
         String[] values = GenericUtils.split(preference, ',');
         if (values.length == 1) {
-            return SftpVersionSelector.Utils.fixedVersionSelector(Integer.parseInt(values[0]));
+            return SftpVersionSelector.fixedVersionSelector(Integer.parseInt(values[0]));
         }
 
         int[] preferred = new int[values.length];
@@ -278,7 +275,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
             preferred[index] = Integer.parseInt(values[index]);
         }
 
-        return SftpVersionSelector.Utils.preferredVersionSelector(preferred);
+        return SftpVersionSelector.preferredVersionSelector(preferred);
     }
 
     // NOTE: URI parameters override environment ones
@@ -431,6 +428,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
                  *      The option is ignored when the file system does not
                  *  support the creation of sparse files
                  */
+                //noinspection UnnecessaryContinue
                 continue;
             } else {
                 throw new IllegalArgumentException("newFileChannel(" + path + ") unsupported open option: " + option);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributes.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributes.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributes.java
index d5c9df3..a07e67f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributes.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpPosixFileAttributes.java
@@ -25,6 +25,7 @@ import java.nio.file.attribute.PosixFileAttributes;
 import java.nio.file.attribute.PosixFilePermission;
 import java.nio.file.attribute.UserPrincipal;
 import java.util.Set;
+
 import org.apache.sshd.client.subsystem.sftp.SftpClient.Attributes;
 import org.apache.sshd.common.util.GenericUtils;
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
index a8fa062..a0d80e7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
@@ -21,6 +21,7 @@ package org.apache.sshd.client.subsystem.sftp;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.stream.StreamSupport;
 
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.util.GenericUtils;
@@ -36,63 +37,19 @@ public interface SftpVersionSelector {
     /**
      * An {@link SftpVersionSelector} that returns the current version
      */
-    SftpVersionSelector CURRENT = new SftpVersionSelector() {
-        @Override
-        public int selectVersion(ClientSession session, int current, List<Integer> available) {
-            return current;
-        }
-
-        @Override
-        public String toString() {
-            return "CURRENT";
-        }
-    };
+    SftpVersionSelector CURRENT = new NamedVersionSelector("CURRENT", (session, current, available) -> current);
 
     /**
      * An {@link SftpVersionSelector} that returns the maximum available version
      */
-    SftpVersionSelector MAXIMUM = new SftpVersionSelector() {
-        @Override
-        public int selectVersion(ClientSession session, int current, List<Integer> available) {
-            int candidate = current;
-            if (GenericUtils.size(available) > 0) {
-                for (Number version : available) {
-                    if (candidate < version.intValue()) {
-                        candidate = version.intValue();
-                    }
-                }
-            }
-            return candidate;
-        }
-
-        @Override
-        public String toString() {
-            return "MAXIMUM";
-        }
-    };
+    SftpVersionSelector MAXIMUM = new NamedVersionSelector("MAXIMUM", (session, current, available) ->
+            GenericUtils.stream(available).mapToInt(Integer::intValue).max().orElse(current));
 
     /**
      * An {@link SftpVersionSelector} that returns the maximum available version
      */
-    SftpVersionSelector MINIMUM = new SftpVersionSelector() {
-        @Override
-        public int selectVersion(ClientSession session, int current, List<Integer> available) {
-            int candidate = current;
-            if (GenericUtils.size(available) > 0) {
-                for (Number version : available) {
-                    if (candidate > version.intValue()) {
-                        candidate = version.intValue();
-                    }
-                }
-            }
-            return candidate;
-        }
-
-        @Override
-        public String toString() {
-            return "MINIMUM";
-        }
-    };
+    SftpVersionSelector MINIMUM = new NamedVersionSelector("MINIMUM", (session, current, available) ->
+            GenericUtils.stream(available).mapToInt(Integer::intValue).min().orElse(current));
 
     /**
      * @param session   The {@link ClientSession} through which the SFTP connection is made
@@ -107,6 +64,7 @@ public interface SftpVersionSelector {
      * Utility class to help using {@link SftpVersionSelector}s
      */
     // CHECKSTYLE:OFF
+    @Deprecated
     final class Utils {
     // CHECKSTYLE:ON
 
@@ -114,75 +72,85 @@ public interface SftpVersionSelector {
             throw new UnsupportedOperationException("No instance allowed");
         }
 
-        /**
-         * Creates a selector the always returns the requested (fixed version) regardless
-         * of what the current or reported available versions are. If the requested version
-         * is not reported as available then an exception will be eventually thrown by the
-         * client during re-negotiation phase.
-         *
-         * @param version The requested version
-         * @return The {@link SftpVersionSelector}
-         */
         public static SftpVersionSelector fixedVersionSelector(final int version) {
-            return new SftpVersionSelector() {
-                @Override
-                public int selectVersion(ClientSession session, int current, List<Integer> available) {
-                    return version;
-                }
-            };
+            return SftpVersionSelector.fixedVersionSelector(version);
         }
 
-        /**
-         * Selects a version in order of preference - if none of the preferred
-         * versions is listed as available then an exception is thrown when the
-         * {@link SftpVersionSelector#selectVersion(int, List)} method is invoked
-         *
-         * @param preferred The preferred versions in decreasing order of
-         * preference (i.e., most preferred is 1st) - may not be {@code null}/empty
-         * @return A {@link SftpVersionSelector} that attempts to select
-         * the most preferred version that is also listed as available.
-         */
         public static SftpVersionSelector preferredVersionSelector(final int ... preferred) {
-            return preferredVersionSelector(NumberUtils.asList(preferred));
+            return SftpVersionSelector.preferredVersionSelector(preferred);
 
         }
 
-        /**
-         * Selects a version in order of preference - if none of the preferred
-         * versions is listed as available then an exception is thrown when the
-         * {@link SftpVersionSelector#selectVersion(int, List)} method is invoked
-         *
-         * @param preferred The preferred versions in decreasing order of
-         * preference (i.e., most preferred is 1st)
-         * @return A {@link SftpVersionSelector} that attempts to select
-         * the most preferred version that is also listed as available.
-         */
         public static SftpVersionSelector preferredVersionSelector(final Iterable<? extends Number> preferred) {
-            if (preferred instanceof Collection<?>) {
-                ValidateUtils.checkNotNullAndNotEmpty((Collection<?>) preferred, "Empty preferred versions");
-            } else {
-                ValidateUtils.checkNotNull(preferred, "No preferred versions");
-            }
-
-            return new SftpVersionSelector() {
-                @Override
-                public int selectVersion(ClientSession session, int current, List<Integer> available) {
-                    for (Number prefValue : preferred) {
-                        int version = prefValue.intValue();
-                        if (version == current) {
-                            return version;
-                        }
-
-                        for (Integer avail : available) {
-                            if (version == avail) {
-                                return version;
-                            }
-                        }
-                    }
-
-                    throw new IllegalStateException("Preferred versions (" + preferred + ") not available: " + available);
-                }
-            };
+            return SftpVersionSelector.preferredVersionSelector(preferred);
         }
     }
+
+    /**
+     * Creates a selector the always returns the requested (fixed version) regardless
+     * of what the current or reported available versions are. If the requested version
+     * is not reported as available then an exception will be eventually thrown by the
+     * client during re-negotiation phase.
+     *
+     * @param version The requested version
+     * @return The {@link SftpVersionSelector}
+     */
+    static SftpVersionSelector fixedVersionSelector(final int version) {
+        return (session, current, available) -> version;
+    }
+
+    /**
+     * Selects a version in order of preference - if none of the preferred
+     * versions is listed as available then an exception is thrown when the
+     * {@link SftpVersionSelector#selectVersion(ClientSession, int, List)} method is invoked
+     *
+     * @param preferred The preferred versions in decreasing order of
+     * preference (i.e., most preferred is 1st) - may not be {@code null}/empty
+     * @return A {@link SftpVersionSelector} that attempts to select
+     * the most preferred version that is also listed as available.
+     */
+    static SftpVersionSelector preferredVersionSelector(final int ... preferred) {
+        return preferredVersionSelector(NumberUtils.asList(preferred));
+
+    }
+
+    /**
+     * Selects a version in order of preference - if none of the preferred
+     * versions is listed as available then an exception is thrown when the
+     * {@link SftpVersionSelector#selectVersion(ClientSession, int, List)} method is invoked
+     *
+     * @param preferred The preferred versions in decreasing order of
+     * preference (i.e., most preferred is 1st)
+     * @return A {@link SftpVersionSelector} that attempts to select
+     * the most preferred version that is also listed as available.
+     */
+    static SftpVersionSelector preferredVersionSelector(final Iterable<? extends Number> preferred) {
+        ValidateUtils.checkNotNullAndNotEmpty((Collection<?>) preferred, "Empty preferred versions");
+        return (session, current, available) -> StreamSupport.stream(preferred.spliterator(), false)
+                .mapToInt(Number::intValue)
+                .filter(v -> v == current || available.contains(v))
+                .findFirst()
+                .orElseThrow(() -> new IllegalStateException("Preferred versions (" + preferred + ") not available: " + available));
+    }
+
+    class NamedVersionSelector implements SftpVersionSelector {
+        private final String name;
+        private final SftpVersionSelector selector;
+
+        public NamedVersionSelector(String name, SftpVersionSelector selector) {
+            this.name = name;
+            this.selector = selector;
+        }
+
+        @Override
+        public int selectVersion(ClientSession session, int current, List<Integer> available) {
+            return selector.selectVersion(session, current, available);
+        }
+
+        @Override
+        public String toString() {
+            return name;
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/BuiltinSftpClientExtensions.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/BuiltinSftpClientExtensions.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/BuiltinSftpClientExtensions.java
index dda5e00..9e83837 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/BuiltinSftpClientExtensions.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/BuiltinSftpClientExtensions.java
@@ -133,7 +133,7 @@ public enum BuiltinSftpClientExtensions implements SftpClientExtensionFactory {
     }
 
     public static BuiltinSftpClientExtensions fromName(String n) {
-        return NamedResource.Utils.findByName(n, String.CASE_INSENSITIVE_ORDER, VALUES);
+        return NamedResource.findByName(n, String.CASE_INSENSITIVE_ORDER, VALUES);
     }
 
     public static BuiltinSftpClientExtensions fromInstance(Object o) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractSftpClientExtension.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractSftpClientExtension.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractSftpClientExtension.java
index 949cca3..ecd60dd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractSftpClientExtension.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractSftpClientExtension.java
@@ -47,11 +47,11 @@ public abstract class AbstractSftpClientExtension extends AbstractLoggingBean im
     private final boolean supported;
 
     protected AbstractSftpClientExtension(String name, SftpClient client, RawSftpClient raw, Collection<String> extras) {
-        this(name, client, raw, !GenericUtils.isEmpty(extras) && extras.contains(name));
+        this(name, client, raw, GenericUtils.isNotEmpty(extras) && extras.contains(name));
     }
 
     protected AbstractSftpClientExtension(String name, SftpClient client, RawSftpClient raw, Map<String, byte[]> extensions) {
-        this(name, client, raw, !GenericUtils.isEmpty(extensions) && extensions.containsKey(name));
+        this(name, client, raw, GenericUtils.isNotEmpty(extensions) && extensions.containsKey(name));
     }
 
     protected AbstractSftpClientExtension(String name, SftpClient client, RawSftpClient raw, boolean supported) {

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java b/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java
index 9b0c38a..b09a746 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/AttributeStore.java
@@ -104,61 +104,74 @@ public interface AttributeStore {
      * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
      */
     // CHECKSTYLE:OFF
+    @Deprecated
     final class Utils {
     // CHECKSTYLE:ON
         private Utils() {
             throw new UnsupportedOperationException("No instance allowed");
         }
 
-        /**
-         * @param <T> The generic attribute type
-         * @param manager The {@link FactoryManager} - ignored if {@code null}
-         * @param key The attribute key - never {@code null}
-         * @return Associated value - {@code null} if not found
-         */
         public static <T> T resolveAttribute(FactoryManager manager, AttributeKey<T> key) {
-            ValidateUtils.checkNotNull(key, "No key");
-            return (manager == null) ? null : manager.getAttribute(key);
+            return AttributeStore.resolveAttribute(manager, key);
         }
 
-        /**
-         * Attempts to use the session's attribute, if not found then tries the factory manager
-         *
-         * @param <T> The generic attribute type
-         * @param session The {@link Session} - ignored if {@code null}
-         * @param key The attribute key - never {@code null}
-         * @return Associated value - {@code null} if not found
-         * @see Session#getFactoryManager()
-         * @see #resolveAttribute(FactoryManager, AttributeKey)
-         */
         public static <T> T resolveAttribute(Session session, AttributeKey<T> key) {
-            ValidateUtils.checkNotNull(key, "No key");
-            if (session == null) {
-                return null;
-            }
-
-            T value = session.getAttribute(key);
-            return (value != null) ? value : resolveAttribute(session.getFactoryManager(), key);
+            return AttributeStore.resolveAttribute(session, key);
         }
 
-        /**
-         * Attempts to use the channel attribute, if not found then tries the session
-         *
-         * @param <T> The generic attribute type
-         * @param channel The {@link Channel} - ignored if {@code null}
-         * @param key The attribute key - never {@code null}
-         * @return Associated value - {@code null} if not found
-         * @see Session#getFactoryManager()
-         * @see #resolveAttribute(Session, AttributeKey)
-         */
         public static <T> T resolveAttribute(Channel channel, AttributeKey<T> key) {
-            ValidateUtils.checkNotNull(key, "No key");
-            if (channel == null) {
-                return null;
-            }
+            return AttributeStore.resolveAttribute(channel, key);
+        }
+    }
 
-            T value = channel.getAttribute(key);
-            return (value != null) ? value : resolveAttribute(channel.getSession(), key);
+    /**
+     * @param <T> The generic attribute type
+     * @param manager The {@link FactoryManager} - ignored if {@code null}
+     * @param key The attribute key - never {@code null}
+     * @return Associated value - {@code null} if not found
+     */
+    static <T> T resolveAttribute(FactoryManager manager, AttributeKey<T> key) {
+        ValidateUtils.checkNotNull(key, "No key");
+        return (manager == null) ? null : manager.getAttribute(key);
+    }
+
+    /**
+     * Attempts to use the session's attribute, if not found then tries the factory manager
+     *
+     * @param <T> The generic attribute type
+     * @param session The {@link Session} - ignored if {@code null}
+     * @param key The attribute key - never {@code null}
+     * @return Associated value - {@code null} if not found
+     * @see Session#getFactoryManager()
+     * @see #resolveAttribute(FactoryManager, AttributeKey)
+     */
+    static <T> T resolveAttribute(Session session, AttributeKey<T> key) {
+        ValidateUtils.checkNotNull(key, "No key");
+        if (session == null) {
+            return null;
+        }
+
+        T value = session.getAttribute(key);
+        return (value != null) ? value : resolveAttribute(session.getFactoryManager(), key);
+    }
+
+    /**
+     * Attempts to use the channel attribute, if not found then tries the session
+     *
+     * @param <T> The generic attribute type
+     * @param channel The {@link Channel} - ignored if {@code null}
+     * @param key The attribute key - never {@code null}
+     * @return Associated value - {@code null} if not found
+     * @see Session#getFactoryManager()
+     * @see #resolveAttribute(Session, AttributeKey)
+     */
+    static <T> T resolveAttribute(Channel channel, AttributeKey<T> key) {
+        ValidateUtils.checkNotNull(key, "No key");
+        if (channel == null) {
+            return null;
         }
+
+        T value = channel.getAttribute(key);
+        return (value != null) ? value : resolveAttribute(channel.getSession(), key);
     }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java b/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
index 2f2ebd0..081db31 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
@@ -281,7 +281,7 @@ public class BaseBuilder<T extends AbstractFactoryManager, S extends BaseBuilder
      * @see BuiltinCiphers#isSupported()
      */
     public static List<NamedFactory<Cipher>> setUpDefaultCiphers(boolean ignoreUnsupported) {
-        return NamedFactory.Utils.setUpBuiltinFactories(ignoreUnsupported, DEFAULT_CIPHERS_PREFERENCE);
+        return NamedFactory.setUpBuiltinFactories(ignoreUnsupported, DEFAULT_CIPHERS_PREFERENCE);
     }
 
     /**
@@ -296,7 +296,7 @@ public class BaseBuilder<T extends AbstractFactoryManager, S extends BaseBuilder
      * @see BuiltinMacs#isSupported()
      */
     public static List<NamedFactory<Mac>> setUpDefaultMacs(boolean ignoreUnsupported) {
-        return NamedFactory.Utils.setUpBuiltinFactories(ignoreUnsupported, DEFAULT_MAC_PREFERENCE);
+        return NamedFactory.setUpBuiltinFactories(ignoreUnsupported, DEFAULT_MAC_PREFERENCE);
     }
 
     /**
@@ -311,6 +311,6 @@ public class BaseBuilder<T extends AbstractFactoryManager, S extends BaseBuilder
      * @see BuiltinSignatures#isSupported()
      */
     public static List<NamedFactory<Signature>> setUpDefaultSignatures(boolean ignoreUnsupported) {
-        return NamedFactory.Utils.setUpBuiltinFactories(ignoreUnsupported, DEFAULT_SIGNATURE_PREFERENCE);
+        return NamedFactory.setUpBuiltinFactories(ignoreUnsupported, DEFAULT_SIGNATURE_PREFERENCE);
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/common/BuiltinFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/BuiltinFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/BuiltinFactory.java
index 7a138e8..1e436c6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/BuiltinFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/BuiltinFactory.java
@@ -18,9 +18,11 @@
  */
 package org.apache.sshd.common;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.sshd.common.util.GenericUtils;
 
 /**
  * A named optional factory.
@@ -31,6 +33,7 @@ import java.util.List;
 public interface BuiltinFactory<T> extends NamedFactory<T>, OptionalFeature {
 
     // CHECKSTYLE:OFF
+    @Deprecated
     final class Utils {
     // CHECKSTYLE:ON
 
@@ -40,13 +43,15 @@ public interface BuiltinFactory<T> extends NamedFactory<T>, OptionalFeature {
 
         public static <T, E extends BuiltinFactory<T>> List<NamedFactory<T>> setUpFactories(
                 boolean ignoreUnsupported, Collection<? extends E> preferred) {
-            List<NamedFactory<T>> avail = new ArrayList<>(preferred.size());
-            for (E f : preferred) {
-                if (ignoreUnsupported || f.isSupported()) {
-                    avail.add(f);
-                }
-            }
-            return avail;
+            return BuiltinFactory.setUpFactories(ignoreUnsupported, preferred);
         }
     }
+
+    static <T, E extends BuiltinFactory<T>> List<NamedFactory<T>> setUpFactories(
+            boolean ignoreUnsupported, Collection<? extends E> preferred) {
+        return GenericUtils.stream(preferred)
+                .filter(f -> ignoreUnsupported || f.isSupported())
+                .collect(Collectors.toList());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/977b7b52/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java b/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java
index f86a00f..0c7f2bb 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/Closeable.java
@@ -18,7 +18,10 @@
  */
 package org.apache.sshd.common;
 
+import java.io.IOException;
+import java.net.SocketTimeoutException;
 import java.nio.channels.Channel;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.sshd.common.future.CloseFuture;
 import org.apache.sshd.common.future.SshFutureListener;
@@ -34,6 +37,18 @@ import org.apache.sshd.common.future.SshFutureListener;
 public interface Closeable extends Channel {
 
     /**
+     * Timeout (milliseconds) for waiting on a {@link CloseFuture} to successfully
+     * complete its action.
+     * @see #DEFAULT_CLOSE_WAIT_TIMEOUT
+     */
+    String CLOSE_WAIT_TIMEOUT = "sshd-close-wait-time";
+
+    /**
+     * Default value for {@link #CLOSE_WAIT_TIMEOUT} if none specified
+     */
+    long DEFAULT_CLOSE_WAIT_TIMEOUT = TimeUnit.SECONDS.toMillis(15L);
+
+    /**
      * Close this resource asynchronously and return a future.
      * Resources support two closing modes: a graceful mode
      * which will cleanly close the resource and an immediate mode
@@ -78,4 +93,32 @@ public interface Closeable extends Channel {
      */
     boolean isClosing();
 
+    default boolean isOpen() {
+        return !(isClosed() || isClosing());
+    }
+
+    @Override
+    default void close() throws IOException {
+        Closeable.close(this);
+    }
+
+    static long getMaxCloseWaitTime(PropertyResolver resolver) {
+        return (resolver == null) ? DEFAULT_CLOSE_WAIT_TIMEOUT
+                : PropertyResolverUtils.getLongProperty(resolver, CLOSE_WAIT_TIMEOUT, DEFAULT_CLOSE_WAIT_TIMEOUT);
+    }
+
+    static void close(Closeable closeable) throws IOException {
+        if (closeable == null) {
+            return;
+        }
+        if ((!closeable.isClosed()) && (!closeable.isClosing())) {
+            CloseFuture future = closeable.close(true);
+            long maxWait = (closeable instanceof PropertyResolver)
+                    ? getMaxCloseWaitTime((PropertyResolver) closeable) : DEFAULT_CLOSE_WAIT_TIMEOUT;
+            boolean successful = future.await(maxWait);
+            if (!successful) {
+                throw new SocketTimeoutException("Failed to receive closure confirmation within " + maxWait + " millis");
+            }
+        }
+    }
 }