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 2016/02/23 17:38:22 UTC

[2/8] mina-sshd git commit: Fixed Maven bundle plugin warnings "Export XXX, has 1, private references [XXX]"

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/common/session/impl/AbstractSessionFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/AbstractSessionFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/session/impl/AbstractSessionFactory.java
deleted file mode 100644
index 5ad579a..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/AbstractSessionFactory.java
+++ /dev/null
@@ -1,53 +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.session.impl;
-
-import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.io.IoSession;
-import org.apache.sshd.common.util.ValidateUtils;
-
-/**
- * An abstract base factory of sessions.
- *
- * @param <M> Type of {@link FactoryManager}
- * @param <S> Type of {@link AbstractSession}
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public abstract class AbstractSessionFactory<M extends FactoryManager, S extends AbstractSession> extends AbstractSessionIoHandler {
-    private final M manager;
-
-    protected AbstractSessionFactory(M manager) {
-        this.manager = ValidateUtils.checkNotNull(manager, "No factory manager instance");
-    }
-
-    public M getFactoryManager() {
-        return manager;
-    }
-
-    @Override
-    protected S createSession(IoSession ioSession) throws Exception {
-        return setupSession(doCreateSession(ioSession));
-    }
-
-    protected abstract S doCreateSession(IoSession ioSession) throws Exception;
-
-    protected S setupSession(S session) throws Exception {
-        return session;
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/common/session/impl/AbstractSessionIoHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/AbstractSessionIoHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/session/impl/AbstractSessionIoHandler.java
deleted file mode 100644
index 9ae95bb..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/AbstractSessionIoHandler.java
+++ /dev/null
@@ -1,82 +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.session.impl;
-
-import org.apache.sshd.common.RuntimeSshException;
-import org.apache.sshd.common.io.IoHandler;
-import org.apache.sshd.common.io.IoSession;
-import org.apache.sshd.common.util.Readable;
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-
-/**
- * TODO Add javadoc
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public abstract class AbstractSessionIoHandler extends AbstractLoggingBean implements IoHandler {
-    protected AbstractSessionIoHandler() {
-        super();
-    }
-
-    @Override
-    public void sessionCreated(IoSession ioSession) throws Exception {
-        AbstractSession session = ValidateUtils.checkNotNull(
-                createSession(ioSession), "No session created for %s", ioSession);
-        AbstractSession.attachSession(ioSession, session);
-    }
-
-    @Override
-    public void sessionClosed(IoSession ioSession) throws Exception {
-        AbstractSession session = ValidateUtils.checkNotNull(
-                AbstractSession.getSession(ioSession), "No abstract session to handle closure of %s", ioSession);
-        session.close(true);
-    }
-
-    @Override
-    public void exceptionCaught(IoSession ioSession, Throwable cause) throws Exception {
-        AbstractSession session = AbstractSession.getSession(ioSession, true);
-        if (session != null) {
-            session.exceptionCaught(cause);
-        } else {
-            throw new IllegalStateException("No session available", cause);
-        }
-    }
-
-    @Override
-    public void messageReceived(IoSession ioSession, Readable message) throws Exception {
-        AbstractSession session = ValidateUtils.checkNotNull(
-                AbstractSession.getSession(ioSession), "No abstract session to handle incoming message for %s", ioSession);
-        try {
-            session.messageReceived(message);
-        } catch (Error e) {
-            if (log.isDebugEnabled()) {
-                log.debug("messageReceived({}) failed {} to handle message: {}",
-                          ioSession, e.getClass().getSimpleName(), e.getMessage());
-            }
-
-            if (log.isTraceEnabled()) {
-                log.trace("messageReceived(" + ioSession + ") message handling error details", e);
-            }
-            throw new RuntimeSshException(e);
-        }
-    }
-
-    protected abstract AbstractSession createSession(IoSession ioSession) throws Exception;
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/common/session/impl/PendingWriteFuture.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/PendingWriteFuture.java b/sshd-core/src/main/java/org/apache/sshd/common/session/impl/PendingWriteFuture.java
deleted file mode 100644
index 6b1f2e0..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/PendingWriteFuture.java
+++ /dev/null
@@ -1,61 +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.session.impl;
-
-import org.apache.sshd.common.future.SshFutureListener;
-import org.apache.sshd.common.io.AbstractIoWriteFuture;
-import org.apache.sshd.common.io.IoWriteFuture;
-import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.buffer.Buffer;
-
-/**
- * Future holding a packet pending key exchange termination.
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class PendingWriteFuture extends AbstractIoWriteFuture implements SshFutureListener<IoWriteFuture> {
-    private final Buffer buffer;
-
-    public PendingWriteFuture(Buffer buffer) {
-        super(null);
-        this.buffer = ValidateUtils.checkNotNull(buffer, "No buffer provided");
-    }
-
-    public Buffer getBuffer() {
-        return buffer;
-    }
-
-    public void setWritten() {
-        setValue(Boolean.TRUE);
-    }
-
-    public void setException(Throwable cause) {
-        ValidateUtils.checkNotNull(cause, "No cause specified");
-        setValue(cause);
-    }
-
-    @Override
-    public void operationComplete(IoWriteFuture future) {
-        if (future.isWritten()) {
-            setWritten();
-        } else {
-            setException(future.getException());
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/common/session/impl/ReservedSessionMessagesHandlerAdapter.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/ReservedSessionMessagesHandlerAdapter.java b/sshd-core/src/main/java/org/apache/sshd/common/session/impl/ReservedSessionMessagesHandlerAdapter.java
deleted file mode 100644
index 36834c9..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/ReservedSessionMessagesHandlerAdapter.java
+++ /dev/null
@@ -1,69 +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.session.impl;
-
-import org.apache.sshd.common.session.ReservedSessionMessagesHandler;
-import org.apache.sshd.common.session.Session;
-import org.apache.sshd.common.util.buffer.Buffer;
-import org.apache.sshd.common.util.buffer.BufferUtils;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-
-/**
- * Delegates the main interface methods to specific ones after having
- * decoded each message buffer
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class ReservedSessionMessagesHandlerAdapter
-        extends AbstractLoggingBean
-        implements ReservedSessionMessagesHandler {
-    public static final ReservedSessionMessagesHandlerAdapter DEFAULT = new ReservedSessionMessagesHandlerAdapter();
-
-    public ReservedSessionMessagesHandlerAdapter() {
-        super();
-    }
-
-    @Override
-    public void handleIgnoreMessage(Session session, Buffer buffer) throws Exception {
-        handleIgnoreMessage(session, buffer.getBytes(), buffer);
-    }
-
-    public void handleIgnoreMessage(Session session, byte[] data, Buffer buffer) throws Exception {
-        if (log.isDebugEnabled()) {
-            log.debug("handleIgnoreMessage({}) SSH_MSG_IGNORE", session);
-        }
-
-        if (log.isTraceEnabled()) {
-            log.trace("handleIgnoreMessage({}) data: {}", session, BufferUtils.toHex(data));
-        }
-    }
-
-    @Override
-    public void handleDebugMessage(Session session, Buffer buffer) throws Exception {
-        handleDebugMessage(session, buffer.getBoolean(), buffer.getString(), buffer.getString(), buffer);
-    }
-
-    public void handleDebugMessage(Session session, boolean display, String msg, String lang, Buffer buffer) throws Exception {
-        if (log.isDebugEnabled()) {
-            log.debug("handleDebugMessage({}) SSH_MSG_DEBUG (display={}) [lang={}] '{}'",
-                      session, display, lang, msg);
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/common/session/impl/SessionTimeoutListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/SessionTimeoutListener.java b/sshd-core/src/main/java/org/apache/sshd/common/session/impl/SessionTimeoutListener.java
deleted file mode 100644
index a6dea42..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/impl/SessionTimeoutListener.java
+++ /dev/null
@@ -1,86 +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.session.impl;
-
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-
-import org.apache.sshd.common.session.Session;
-import org.apache.sshd.common.session.SessionListener;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-
-/**
- * Task that iterates over all currently open {@link AbstractSession}s and checks each of them for timeouts. If
- * the {@link AbstractSession} has timed out (either auth or idle timeout), the session will be disconnected.
- *
- * @see org.apache.sshd.common.session.impl.AbstractSession#checkForTimeouts()
- */
-public class SessionTimeoutListener extends AbstractLoggingBean implements SessionListener, Runnable {
-    private final Set<AbstractSession> sessions = new CopyOnWriteArraySet<AbstractSession>();
-
-    public SessionTimeoutListener() {
-        super();
-    }
-
-    @Override
-    public void sessionCreated(Session session) {
-        if ((session instanceof AbstractSession) && ((session.getAuthTimeout() > 0L) || (session.getIdleTimeout() > 0L))) {
-            sessions.add((AbstractSession) session);
-            log.debug("sessionCreated({}) tracking", session);
-        } else {
-            log.trace("sessionCreated({}) not tracked", session);
-        }
-    }
-
-    @Override
-    public void sessionEvent(Session session, Event event) {
-        // ignored
-    }
-
-    @Override
-    public void sessionException(Session session, Throwable t) {
-        if (log.isDebugEnabled()) {
-            log.debug("sessionException({}) {}: {}", session, t.getClass().getSimpleName(), t.getMessage());
-        }
-        if (log.isTraceEnabled()) {
-            log.trace("sessionException(" + session + ") details", t);
-        }
-        sessionClosed(session);
-    }
-
-    @Override
-    public void sessionClosed(Session s) {
-        if (sessions.remove(s)) {
-            log.debug("sessionClosed({}) un-tracked", s);
-        } else {
-            log.trace("sessionClosed({}) not tracked", s);
-        }
-    }
-
-    @Override
-    public void run() {
-        for (AbstractSession session : sessions) {
-            try {
-                session.checkForTimeouts();
-            } catch (Exception e) {
-                log.warn(e.getClass().getSimpleName() + " while checking session=" + session + " timeouts: " + e.getMessage(), e);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
index 649a7f1..600de6a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
@@ -40,13 +40,13 @@ import org.apache.sshd.common.Factory;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.ServiceFactory;
-import org.apache.sshd.common.impl.AbstractFactoryManager;
+import org.apache.sshd.common.helpers.AbstractFactoryManager;
 import org.apache.sshd.common.io.IoAcceptor;
 import org.apache.sshd.common.io.IoServiceFactory;
 import org.apache.sshd.common.io.IoSession;
 import org.apache.sshd.common.io.mina.MinaServiceFactory;
 import org.apache.sshd.common.io.nio2.Nio2ServiceFactory;
-import org.apache.sshd.common.session.impl.AbstractSession;
+import org.apache.sshd.common.session.helpers.AbstractSession;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.SecurityUtils;
 import org.apache.sshd.common.util.ValidateUtils;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java
index 7dd0d38..52801d6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java
@@ -22,7 +22,7 @@ import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.forward.TcpipForwarder;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.session.Session;
-import org.apache.sshd.common.session.impl.AbstractConnectionServiceRequestHandler;
+import org.apache.sshd.common.session.helpers.AbstractConnectionServiceRequestHandler;
 import org.apache.sshd.common.util.Int2IntFunction;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java
index b86c0c1..1cfe6b1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java
@@ -19,7 +19,7 @@
 package org.apache.sshd.server.global;
 
 import org.apache.sshd.common.session.ConnectionService;
-import org.apache.sshd.common.session.impl.AbstractConnectionServiceRequestHandler;
+import org.apache.sshd.common.session.helpers.AbstractConnectionServiceRequestHandler;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java
index 503311d..c29a509 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java
@@ -19,7 +19,7 @@
 package org.apache.sshd.server.global;
 
 import org.apache.sshd.common.session.ConnectionService;
-import org.apache.sshd.common.session.impl.AbstractConnectionServiceRequestHandler;
+import org.apache.sshd.common.session.helpers.AbstractConnectionServiceRequestHandler;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java
index 6f99b7d..037c1ea 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java
@@ -22,7 +22,7 @@ import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.forward.TcpipForwarder;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.session.Session;
-import org.apache.sshd.common.session.impl.AbstractConnectionServiceRequestHandler;
+import org.apache.sshd.common.session.helpers.AbstractConnectionServiceRequestHandler;
 import org.apache.sshd.common.util.Int2IntFunction;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java b/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
index 9a197f8..dfa0f60 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/scp/ScpCommand.java
@@ -32,7 +32,7 @@ import org.apache.sshd.common.scp.ScpException;
 import org.apache.sshd.common.scp.ScpFileOpener;
 import org.apache.sshd.common.scp.ScpHelper;
 import org.apache.sshd.common.scp.ScpTransferEventListener;
-import org.apache.sshd.common.scp.impl.DefaultScpFileOpener;
+import org.apache.sshd.common.scp.helpers.DefaultScpFileOpener;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.session.SessionHolder;
 import org.apache.sshd.common.util.GenericUtils;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
index 36e03a1..0d4c096 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
@@ -23,7 +23,7 @@ import java.util.List;
 
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.io.IoSession;
-import org.apache.sshd.common.session.impl.AbstractSession;
+import org.apache.sshd.common.session.helpers.AbstractSession;
 import org.apache.sshd.server.ServerFactoryManager;
 import org.apache.sshd.server.auth.UserAuth;
 import org.apache.sshd.server.auth.gss.GSSAuthenticator;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
index cdb16d8..9ed7146 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
@@ -19,7 +19,7 @@
 package org.apache.sshd.server.session;
 
 import org.apache.sshd.common.SshException;
-import org.apache.sshd.common.session.impl.AbstractConnectionService;
+import org.apache.sshd.common.session.helpers.AbstractConnectionService;
 
 /**
  * Server side <code>ssh-connection</code> service.

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java
index bc66787..da13db8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java
@@ -19,7 +19,7 @@
 package org.apache.sshd.server.session;
 
 import org.apache.sshd.common.io.IoSession;
-import org.apache.sshd.common.session.impl.AbstractSessionFactory;
+import org.apache.sshd.common.session.helpers.AbstractSessionFactory;
 import org.apache.sshd.server.ServerFactoryManager;
 
 /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java b/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
index b183c1a..07070d5 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
@@ -90,7 +90,7 @@ import org.apache.sshd.common.keyprovider.KeyPairProvider;
 import org.apache.sshd.common.session.ConnectionService;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.session.SessionListener;
-import org.apache.sshd.common.session.impl.AbstractSession;
+import org.apache.sshd.common.session.helpers.AbstractSession;
 import org.apache.sshd.common.subsystem.sftp.SftpConstants;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.Transformer;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
index 054ace8..928ee4c 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
@@ -50,7 +50,7 @@ import org.apache.sshd.common.scp.ScpException;
 import org.apache.sshd.common.scp.ScpFileOpener;
 import org.apache.sshd.common.scp.ScpHelper;
 import org.apache.sshd.common.scp.ScpTransferEventListener;
-import org.apache.sshd.common.scp.impl.DefaultScpFileOpener;
+import org.apache.sshd.common.scp.helpers.DefaultScpFileOpener;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.OsUtils;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractCheckFileExtensionTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractCheckFileExtensionTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractCheckFileExtensionTest.java
new file mode 100644
index 0000000..20ce0cd
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractCheckFileExtensionTest.java
@@ -0,0 +1,239 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.client.subsystem.sftp.extensions.helpers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+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.AbstractSftpClientTestSupport;
+import org.apache.sshd.client.subsystem.sftp.SftpClient;
+import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle;
+import org.apache.sshd.client.subsystem.sftp.extensions.CheckFileHandleExtension;
+import org.apache.sshd.client.subsystem.sftp.extensions.CheckFileNameExtension;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.digest.BuiltinDigests;
+import org.apache.sshd.common.digest.Digest;
+import org.apache.sshd.common.digest.DigestFactory;
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.common.subsystem.sftp.SftpException;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
+import org.apache.sshd.common.util.Pair;
+import org.apache.sshd.common.util.buffer.BufferUtils;
+import org.apache.sshd.common.util.io.IoUtils;
+import org.apache.sshd.util.test.Utils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RunWith(Parameterized.class)   // see https://github.com/junit-team/junit/wiki/Parameterized-tests
+public class AbstractCheckFileExtensionTest extends AbstractSftpClientTestSupport {
+    private static final Collection<Integer> DATA_SIZES =
+            Collections.unmodifiableList(
+                    Arrays.asList(
+                            Integer.valueOf(Byte.MAX_VALUE),
+                            Integer.valueOf(SftpConstants.MIN_CHKFILE_BLOCKSIZE),
+                            Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE),
+                            Integer.valueOf(Byte.SIZE * IoUtils.DEFAULT_COPY_SIZE)
+                    ));
+    private static final Collection<Integer> BLOCK_SIZES =
+            Collections.unmodifiableList(
+                    Arrays.asList(
+                            Integer.valueOf(0),
+                            Integer.valueOf(SftpConstants.MIN_CHKFILE_BLOCKSIZE),
+                            Integer.valueOf(1024),
+                            Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE)
+                    ));
+    @SuppressWarnings("synthetic-access")
+    private static final Collection<Object[]> PARAMETERS =
+            Collections.unmodifiableCollection(new LinkedList<Object[]>() {
+                private static final long serialVersionUID = 1L;    // we're not serializing it
+
+                {
+                    for (DigestFactory factory : BuiltinDigests.VALUES) {
+                        if (!factory.isSupported()) {
+                            System.out.println("Skip unsupported digest=" + factory.getAlgorithm());
+                            continue;
+                        }
+
+                        String algorithm = factory.getName();
+                        for (Number dataSize : DATA_SIZES) {
+                            for (Number blockSize : BLOCK_SIZES) {
+                                add(new Object[]{algorithm, dataSize, blockSize});
+                            }
+                        }
+                    }
+                }
+            });
+
+    @Parameters(name = "{0} - dataSize={1}, blockSize={2}")
+    public static Collection<Object[]> parameters() {
+        return PARAMETERS;
+    }
+
+    private final String algorithm;
+    private final int dataSize, blockSize;
+
+    public AbstractCheckFileExtensionTest(String algorithm, int dataSize, int blockSize) throws IOException {
+        this.algorithm = algorithm;
+        this.dataSize = dataSize;
+        this.blockSize = blockSize;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        setupServer();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        tearDownServer();
+    }
+
+    @Test
+    public void testCheckFileExtension() throws Exception {
+        testCheckFileExtension(algorithm, dataSize, blockSize);
+    }
+
+    private void testCheckFileExtension(String expectedAlgorithm, int inputDataSize, int hashBlockSize) throws Exception {
+        NamedFactory<? extends Digest> factory = BuiltinDigests.fromFactoryName(expectedAlgorithm);
+        Digest digest = null;
+        if (blockSize == 0) {
+            digest = factory.create();
+            digest.init();
+        }
+
+        byte[] seed = (getClass().getName() + "#" + getCurrentTestName()
+                + "-" + expectedAlgorithm
+                + "-" + inputDataSize + "/" + hashBlockSize
+                + IoUtils.EOL)
+                .getBytes(StandardCharsets.UTF_8);
+
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream(inputDataSize + seed.length)) {
+            while (baos.size() < inputDataSize) {
+                baos.write(seed);
+
+                if (digest != null) {
+                    digest.update(seed);
+                }
+            }
+
+            testCheckFileExtension(factory, baos.toByteArray(), hashBlockSize, (digest == null) ? null : digest.digest());
+        }
+    }
+
+    private void testCheckFileExtension(NamedFactory<? extends Digest> factory, byte[] data, int hashBlockSize, byte[] expectedHash) throws Exception {
+        Path targetPath = detectTargetFolder();
+        Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName());
+        Path srcFile = assertHierarchyTargetFolderExists(lclSftp).resolve(factory.getName() + "-data-" + data.length + "-" + hashBlockSize + ".txt");
+        Files.write(srcFile, data, IoUtils.EMPTY_OPEN_OPTIONS);
+
+        List<String> algorithms = new ArrayList<String>(BuiltinDigests.VALUES.size());
+        // put the selected algorithm 1st and then the rest
+        algorithms.add(factory.getName());
+        for (NamedFactory<? extends Digest> f : BuiltinDigests.VALUES) {
+            if (f == factory) {
+                continue;
+            }
+
+            algorithms.add(f.getName());
+        }
+
+        Path parentPath = targetPath.getParent();
+        String srcPath = Utils.resolveRelativeRemotePath(parentPath, srcFile);
+        String srcFolder = Utils.resolveRelativeRemotePath(parentPath, srcFile.getParent());
+
+        try (SshClient client = setupTestClient()) {
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                try (SftpClient sftp = session.createSftpClient()) {
+                    CheckFileNameExtension file = assertExtensionCreated(sftp, CheckFileNameExtension.class);
+                    try {
+                        Pair<String, ?> result = file.checkFileName(srcFolder, algorithms, 0L, 0L, hashBlockSize);
+                        fail("Unexpected success to hash folder=" + srcFolder + ": " + result.getFirst());
+                    } catch (IOException e) {    // expected - not allowed to hash a folder
+                        assertTrue("Not an SftpException", e instanceof SftpException);
+                    }
+
+                    CheckFileHandleExtension hndl = assertExtensionCreated(sftp, CheckFileHandleExtension.class);
+                    try (CloseableHandle dirHandle = sftp.openDir(srcFolder)) {
+                        try {
+                            Pair<String, ?> result = hndl.checkFileHandle(dirHandle, algorithms, 0L, 0L, hashBlockSize);
+                            fail("Unexpected handle success on folder=" + srcFolder + ": " + result.getFirst());
+                        } catch (IOException e) {    // expected - not allowed to hash a folder
+                            assertTrue("Not an SftpException", e instanceof SftpException);
+                        }
+                    }
+
+                    validateHashResult(file, file.checkFileName(srcPath, algorithms, 0L, 0L, hashBlockSize), algorithms.get(0), expectedHash);
+                    try (CloseableHandle fileHandle = sftp.open(srcPath, SftpClient.OpenMode.Read)) {
+                        validateHashResult(hndl, hndl.checkFileHandle(fileHandle, algorithms, 0L, 0L, hashBlockSize), algorithms.get(0), expectedHash);
+                    }
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+
+    private void validateHashResult(NamedResource hasher, Pair<String, Collection<byte[]>> result, String expectedAlgorithm, byte[] expectedHash) {
+        String name = hasher.getName();
+        assertNotNull("No result for hash=" + name, result);
+        assertEquals("Mismatched hash algorithms for " + name, expectedAlgorithm, result.getFirst());
+
+        if (NumberUtils.length(expectedHash) > 0) {
+            Collection<byte[]> values = result.getSecond();
+            assertEquals("Mismatched hash values count for " + name, 1, GenericUtils.size(values));
+
+            byte[] actualHash = values.iterator().next();
+            if (!Arrays.equals(expectedHash, actualHash)) {
+                fail("Mismatched hashes for " + name
+                   + ": expected=" + BufferUtils.toHex(':', expectedHash)
+                   + ", actual=" + BufferUtils.toHex(':', expectedHash));
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractMD5HashExtensionTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractMD5HashExtensionTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractMD5HashExtensionTest.java
new file mode 100644
index 0000000..8a5fe30
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/AbstractMD5HashExtensionTest.java
@@ -0,0 +1,187 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.client.subsystem.sftp.extensions.helpers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+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.AbstractSftpClientTestSupport;
+import org.apache.sshd.client.subsystem.sftp.SftpClient;
+import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle;
+import org.apache.sshd.client.subsystem.sftp.extensions.MD5FileExtension;
+import org.apache.sshd.client.subsystem.sftp.extensions.MD5HandleExtension;
+import org.apache.sshd.common.digest.BuiltinDigests;
+import org.apache.sshd.common.digest.Digest;
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.common.subsystem.sftp.SftpException;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.buffer.BufferUtils;
+import org.apache.sshd.common.util.io.IoUtils;
+import org.apache.sshd.util.test.Utils;
+import org.junit.After;
+import org.junit.Assume;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RunWith(Parameterized.class)   // see https://github.com/junit-team/junit/wiki/Parameterized-tests
+public class AbstractMD5HashExtensionTest extends AbstractSftpClientTestSupport {
+    private static final List<Integer> DATA_SIZES =
+            Collections.unmodifiableList(
+                    Arrays.asList(
+                            Integer.valueOf(Byte.MAX_VALUE),
+                            Integer.valueOf(SftpConstants.MD5_QUICK_HASH_SIZE),
+                            Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE),
+                            Integer.valueOf(Byte.SIZE * IoUtils.DEFAULT_COPY_SIZE)
+                    ));
+
+    @Parameters(name = "dataSize={0}")
+    public static Collection<Object[]> parameters() {
+        return parameterize(DATA_SIZES);
+    }
+
+    @BeforeClass
+    public static void checkMD5Supported() {
+        Assume.assumeTrue("MD5 not supported", BuiltinDigests.md5.isSupported());
+    }
+
+    private final int size;
+
+    public AbstractMD5HashExtensionTest(int size) throws IOException {
+        this.size = size;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        setupServer();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        tearDownServer();
+    }
+
+    @Test
+    public void testMD5HashExtension() throws Exception {
+        testMD5HashExtension(size);
+    }
+
+    private void testMD5HashExtension(int dataSize) throws Exception {
+        byte[] seed = (getClass().getName() + "#" + getCurrentTestName() + "-" + dataSize + IoUtils.EOL).getBytes(StandardCharsets.UTF_8);
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream(dataSize + seed.length)) {
+            while (baos.size() < dataSize) {
+                baos.write(seed);
+            }
+
+            testMD5HashExtension(baos.toByteArray());
+        }
+    }
+
+    private void testMD5HashExtension(byte[] data) throws Exception {
+        Digest digest = BuiltinDigests.md5.create();
+        digest.init();
+        digest.update(data);
+
+        byte[] expectedHash = digest.digest();
+        byte[] quickHash = expectedHash;
+        if (data.length > SftpConstants.MD5_QUICK_HASH_SIZE) {
+            byte[] quickData = new byte[SftpConstants.MD5_QUICK_HASH_SIZE];
+            System.arraycopy(data, 0, quickData, 0, quickData.length);
+            digest = BuiltinDigests.md5.create();
+            digest.init();
+            digest.update(quickData);
+            quickHash = digest.digest();
+        }
+
+        Path targetPath = detectTargetFolder();
+        Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName());
+        Path srcFile = assertHierarchyTargetFolderExists(lclSftp).resolve("data-" + data.length + ".txt");
+        Files.write(srcFile, data, IoUtils.EMPTY_OPEN_OPTIONS);
+
+        Path parentPath = targetPath.getParent();
+        String srcPath = Utils.resolveRelativeRemotePath(parentPath, srcFile);
+        String srcFolder = Utils.resolveRelativeRemotePath(parentPath, srcFile.getParent());
+
+        try (SshClient client = setupTestClient()) {
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                try (SftpClient sftp = session.createSftpClient()) {
+                    MD5FileExtension file = assertExtensionCreated(sftp, MD5FileExtension.class);
+                    try {
+                        byte[] actual = file.getHash(srcFolder, 0L, 0L, quickHash);
+                        fail("Unexpected file success on folder=" + srcFolder + ": " + BufferUtils.toHex(':', actual));
+                    } catch (IOException e) {    // expected - not allowed to hash a folder
+                        assertTrue("Not an SftpException for file hash on " + srcFolder, e instanceof SftpException);
+                    }
+
+                    MD5HandleExtension hndl = assertExtensionCreated(sftp, MD5HandleExtension.class);
+                    try (CloseableHandle dirHandle = sftp.openDir(srcFolder)) {
+                        try {
+                            byte[] actual = hndl.getHash(dirHandle, 0L, 0L, quickHash);
+                            fail("Unexpected handle success on folder=" + srcFolder + ": " + BufferUtils.toHex(':', actual));
+                        } catch (IOException e) {    // expected - not allowed to hash a folder
+                            assertTrue("Not an SftpException for handle hash on " + srcFolder, e instanceof SftpException);
+                        }
+                    }
+
+                    try (CloseableHandle fileHandle = sftp.open(srcPath, SftpClient.OpenMode.Read)) {
+                        for (byte[] qh : new byte[][]{GenericUtils.EMPTY_BYTE_ARRAY, quickHash}) {
+                            for (boolean useFile : new boolean[]{true, false}) {
+                                byte[] actualHash = useFile ? file.getHash(srcPath, 0L, 0L, qh) : hndl.getHash(fileHandle, 0L, 0L, qh);
+                                String type = useFile ? file.getClass().getSimpleName() : hndl.getClass().getSimpleName();
+                                if (!Arrays.equals(expectedHash, actualHash)) {
+                                    fail("Mismatched hash for quick=" + BufferUtils.toHex(':', qh)
+                                            + " using " + type + " on " + srcFile
+                                            + ": expected=" + BufferUtils.toHex(':', expectedHash)
+                                            + ", actual=" + BufferUtils.toHex(':', actualHash));
+                                }
+                            }
+                        }
+                    }
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyDataExtensionImplTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyDataExtensionImplTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyDataExtensionImplTest.java
new file mode 100644
index 0000000..713c1a9
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyDataExtensionImplTest.java
@@ -0,0 +1,200 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.client.subsystem.sftp.extensions.helpers;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+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.AbstractSftpClientTestSupport;
+import org.apache.sshd.client.subsystem.sftp.SftpClient;
+import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle;
+import org.apache.sshd.client.subsystem.sftp.extensions.CopyDataExtension;
+import org.apache.sshd.common.Factory;
+import org.apache.sshd.common.random.Random;
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.common.util.io.IoUtils;
+import org.apache.sshd.util.test.Utils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RunWith(Parameterized.class)   // see https://github.com/junit-team/junit/wiki/Parameterized-tests
+public class CopyDataExtensionImplTest extends AbstractSftpClientTestSupport {
+    private static final List<Object[]> PARAMETERS =
+            Collections.unmodifiableList(
+                    Arrays.<Object[]>asList(
+                            new Object[]{
+                                    Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE),
+                                    Integer.valueOf(0),
+                                    Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE),
+                                    Long.valueOf(0L)
+                            },
+                            new Object[]{
+                                    Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE),
+                                    Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE / 2),
+                                    Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE / 4),
+                                    Long.valueOf(0L)
+                            },
+                            new Object[]{
+                                    Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE),
+                                    Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE / 2),
+                                    Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE / 4),
+                                    Long.valueOf(IoUtils.DEFAULT_COPY_SIZE / 2)
+                            },
+                            new Object[]{
+                                    Integer.valueOf(Byte.MAX_VALUE),
+                                    Integer.valueOf(Byte.MAX_VALUE / 2),
+                                    Integer.valueOf(Byte.MAX_VALUE),    // attempt to read more than available
+                                    Long.valueOf(0L)
+                            }
+                    ));
+
+    @Parameters(name = "size={0}, readOffset={1}, readLength={2}, writeOffset={3}")
+    public static Collection<Object[]> parameters() {
+        return PARAMETERS;
+    }
+
+    private int size, srcOffset, length;
+    private long dstOffset;
+
+    public CopyDataExtensionImplTest(int size, int srcOffset, int length, long dstOffset) throws IOException {
+        this.size = size;
+        this.srcOffset = srcOffset;
+        this.length = length;
+        this.dstOffset = dstOffset;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        setupServer();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        tearDownServer();
+    }
+
+    @Test
+    public void testCopyDataExtension() throws Exception {
+        testCopyDataExtension(size, srcOffset, length, dstOffset);
+    }
+
+    private void testCopyDataExtension(int dataSize, int readOffset, int readLength, long writeOffset) throws Exception {
+        byte[] seed = (getClass().getName() + "#" + getCurrentTestName()
+                + "-" + dataSize
+                + "-" + readOffset + "/" + readLength + "/" + writeOffset
+                + IoUtils.EOL)
+                .getBytes(StandardCharsets.UTF_8);
+        try (ByteArrayOutputStream baos = new ByteArrayOutputStream(dataSize + seed.length)) {
+            while (baos.size() < dataSize) {
+                baos.write(seed);
+            }
+
+            testCopyDataExtension(baos.toByteArray(), readOffset, readLength, writeOffset);
+        }
+    }
+
+    private void testCopyDataExtension(byte[] data, int readOffset, int readLength, long writeOffset) throws Exception {
+        Path targetPath = detectTargetFolder();
+        Path parentPath = targetPath.getParent();
+        Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName());
+        LinkOption[] options = IoUtils.getLinkOptions(false);
+        String baseName = readOffset + "-" + readLength + "-" + writeOffset;
+        Path srcFile = assertHierarchyTargetFolderExists(lclSftp, options).resolve(baseName + "-src.txt");
+        Files.write(srcFile, data, IoUtils.EMPTY_OPEN_OPTIONS);
+        String srcPath = Utils.resolveRelativeRemotePath(parentPath, srcFile);
+
+        Path dstFile = srcFile.getParent().resolve(baseName + "-dst.txt");
+        if (Files.exists(dstFile, options)) {
+            Files.delete(dstFile);
+        }
+        String dstPath = Utils.resolveRelativeRemotePath(parentPath, dstFile);
+
+        try (SshClient client = setupTestClient()) {
+            client.start();
+
+            if (writeOffset > 0L) {
+                Factory<? extends Random> factory = client.getRandomFactory();
+                Random randomizer = factory.create();
+                long totalLength = writeOffset + readLength;
+                byte[] workBuf = new byte[(int) Math.min(totalLength, IoUtils.DEFAULT_COPY_SIZE)];
+                try (OutputStream output = Files.newOutputStream(dstFile, IoUtils.EMPTY_OPEN_OPTIONS)) {
+                    while (totalLength > 0L) {
+                        randomizer.fill(workBuf);
+                        output.write(workBuf);
+                        totalLength -= workBuf.length;
+                    }
+                }
+            }
+
+            try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                try (SftpClient sftp = session.createSftpClient()) {
+                    CopyDataExtension ext = assertExtensionCreated(sftp, CopyDataExtension.class);
+                    try (CloseableHandle readHandle = sftp.open(srcPath, SftpClient.OpenMode.Read);
+                         CloseableHandle writeHandle = sftp.open(dstPath, SftpClient.OpenMode.Write, SftpClient.OpenMode.Create)) {
+                        ext.copyData(readHandle, readOffset, readLength, writeHandle, writeOffset);
+                    }
+                }
+            } finally {
+                client.stop();
+            }
+        }
+
+        int available = data.length, required = readOffset + readLength;
+        if (required > available) {
+            required = available;
+        }
+        byte[] expected = new byte[required - readOffset];
+        System.arraycopy(data, readOffset, expected, 0, expected.length);
+
+        byte[] actual = new byte[expected.length];
+        try (FileChannel channel = FileChannel.open(dstFile, IoUtils.EMPTY_OPEN_OPTIONS)) {
+            int readLen = channel.read(ByteBuffer.wrap(actual), writeOffset);
+            assertEquals("Mismatched read data size", expected.length, readLen);
+        }
+        assertArrayEquals("Mismatched copy data", expected, actual);
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyFileExtensionImplTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyFileExtensionImplTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyFileExtensionImplTest.java
new file mode 100644
index 0000000..e929f47
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/CopyFileExtensionImplTest.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.client.subsystem.sftp.extensions.helpers;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+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.AbstractSftpClientTestSupport;
+import org.apache.sshd.client.subsystem.sftp.SftpClient;
+import org.apache.sshd.client.subsystem.sftp.extensions.CopyFileExtension;
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.common.subsystem.sftp.SftpException;
+import org.apache.sshd.common.util.io.IoUtils;
+import org.apache.sshd.util.test.Utils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class CopyFileExtensionImplTest extends AbstractSftpClientTestSupport {
+    public CopyFileExtensionImplTest() throws IOException {
+        super();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        setupServer();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        tearDownServer();
+    }
+
+    @Test
+    public void testCopyFileExtension() throws Exception {
+        Path targetPath = detectTargetFolder();
+        Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
+        Utils.deleteRecursive(lclSftp);
+
+        byte[] data = (getClass().getName() + "#" + getCurrentTestName()).getBytes(StandardCharsets.UTF_8);
+        Path srcFile = assertHierarchyTargetFolderExists(lclSftp).resolve("src.txt");
+        Files.write(srcFile, data, IoUtils.EMPTY_OPEN_OPTIONS);
+
+        Path parentPath = targetPath.getParent();
+        String srcPath = Utils.resolveRelativeRemotePath(parentPath, srcFile);
+        Path dstFile = lclSftp.resolve("dst.txt");
+        String dstPath = Utils.resolveRelativeRemotePath(parentPath, dstFile);
+
+        LinkOption[] options = IoUtils.getLinkOptions(false);
+        assertFalse("Destination file unexpectedly exists", Files.exists(dstFile, options));
+
+        try (SshClient client = setupTestClient()) {
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                try (SftpClient sftp = session.createSftpClient()) {
+                    CopyFileExtension ext = assertExtensionCreated(sftp, CopyFileExtension.class);
+                    ext.copyFile(srcPath, dstPath, false);
+                    assertTrue("Source file not preserved", Files.exists(srcFile, options));
+                    assertTrue("Destination file not created", Files.exists(dstFile, options));
+
+                    byte[] actual = Files.readAllBytes(dstFile);
+                    assertArrayEquals("Mismatched copied data", data, actual);
+
+                    try {
+                        ext.copyFile(srcPath, dstPath, false);
+                        fail("Unexpected success to overwrite existing destination: " + dstFile);
+                    } catch (IOException e) {
+                        assertTrue("Not an SftpException", e instanceof SftpException);
+                    }
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImplTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImplTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImplTest.java
new file mode 100644
index 0000000..e8affed
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/helpers/SpaceAvailableExtensionImplTest.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.client.subsystem.sftp.extensions.helpers;
+
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+import java.nio.file.FileStore;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+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.AbstractSftpClientTestSupport;
+import org.apache.sshd.client.subsystem.sftp.SftpClient;
+import org.apache.sshd.client.subsystem.sftp.extensions.SpaceAvailableExtension;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.common.subsystem.sftp.extensions.SpaceAvailableExtensionInfo;
+import org.apache.sshd.server.Command;
+import org.apache.sshd.server.subsystem.sftp.SftpSubsystem;
+import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
+import org.apache.sshd.util.test.Utils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class SpaceAvailableExtensionImplTest extends AbstractSftpClientTestSupport {
+    public SpaceAvailableExtensionImplTest() throws IOException {
+        super();
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        setupServer();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        tearDownServer();
+    }
+
+    @Test
+    public void testFileStoreReport() throws Exception {
+        Path targetPath = detectTargetFolder();
+        Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), getCurrentTestName());
+        Path parentPath = targetPath.getParent();
+        FileStore store = Files.getFileStore(lclSftp.getRoot());
+        final String queryPath = Utils.resolveRelativeRemotePath(parentPath, lclSftp);
+        final SpaceAvailableExtensionInfo expected = new SpaceAvailableExtensionInfo(store);
+        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory() {
+            @Override
+            public Command create() {
+                return new SftpSubsystem(getExecutorService(), isShutdownOnExit(), getUnsupportedAttributePolicy()) {
+                    @Override
+                    protected SpaceAvailableExtensionInfo doSpaceAvailable(int id, String path) throws IOException {
+                        if (!queryPath.equals(path)) {
+                            throw new StreamCorruptedException("Mismatched query paths: expected=" + queryPath + ", actual=" + path);
+                        }
+
+                        return expected;
+                    }
+                };
+            }
+        }));
+
+        try (SshClient client = setupTestClient()) {
+            client.start();
+
+            try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+                session.addPasswordIdentity(getCurrentTestName());
+                session.auth().verify(5L, TimeUnit.SECONDS);
+
+                try (SftpClient sftp = session.createSftpClient()) {
+                    SpaceAvailableExtension ext = assertExtensionCreated(sftp, SpaceAvailableExtension.class);
+                    SpaceAvailableExtensionInfo actual = ext.available(queryPath);
+                    assertEquals("Mismatched information", expected, actual);
+                }
+            } finally {
+                client.stop();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/3f69f229/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractCheckFileExtensionTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractCheckFileExtensionTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractCheckFileExtensionTest.java
deleted file mode 100644
index 05f7820..0000000
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractCheckFileExtensionTest.java
+++ /dev/null
@@ -1,239 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.sshd.client.subsystem.sftp.extensions.impl;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-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.AbstractSftpClientTestSupport;
-import org.apache.sshd.client.subsystem.sftp.SftpClient;
-import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle;
-import org.apache.sshd.client.subsystem.sftp.extensions.CheckFileHandleExtension;
-import org.apache.sshd.client.subsystem.sftp.extensions.CheckFileNameExtension;
-import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.NamedResource;
-import org.apache.sshd.common.digest.BuiltinDigests;
-import org.apache.sshd.common.digest.Digest;
-import org.apache.sshd.common.digest.DigestFactory;
-import org.apache.sshd.common.subsystem.sftp.SftpConstants;
-import org.apache.sshd.common.subsystem.sftp.SftpException;
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.NumberUtils;
-import org.apache.sshd.common.util.Pair;
-import org.apache.sshd.common.util.buffer.BufferUtils;
-import org.apache.sshd.common.util.io.IoUtils;
-import org.apache.sshd.util.test.Utils;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.MethodSorters;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-/**
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@RunWith(Parameterized.class)   // see https://github.com/junit-team/junit/wiki/Parameterized-tests
-public class AbstractCheckFileExtensionTest extends AbstractSftpClientTestSupport {
-    private static final Collection<Integer> DATA_SIZES =
-            Collections.unmodifiableList(
-                    Arrays.asList(
-                            Integer.valueOf(Byte.MAX_VALUE),
-                            Integer.valueOf(SftpConstants.MIN_CHKFILE_BLOCKSIZE),
-                            Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE),
-                            Integer.valueOf(Byte.SIZE * IoUtils.DEFAULT_COPY_SIZE)
-                    ));
-    private static final Collection<Integer> BLOCK_SIZES =
-            Collections.unmodifiableList(
-                    Arrays.asList(
-                            Integer.valueOf(0),
-                            Integer.valueOf(SftpConstants.MIN_CHKFILE_BLOCKSIZE),
-                            Integer.valueOf(1024),
-                            Integer.valueOf(IoUtils.DEFAULT_COPY_SIZE)
-                    ));
-    @SuppressWarnings("synthetic-access")
-    private static final Collection<Object[]> PARAMETERS =
-            Collections.unmodifiableCollection(new LinkedList<Object[]>() {
-                private static final long serialVersionUID = 1L;    // we're not serializing it
-
-                {
-                    for (DigestFactory factory : BuiltinDigests.VALUES) {
-                        if (!factory.isSupported()) {
-                            System.out.println("Skip unsupported digest=" + factory.getAlgorithm());
-                            continue;
-                        }
-
-                        String algorithm = factory.getName();
-                        for (Number dataSize : DATA_SIZES) {
-                            for (Number blockSize : BLOCK_SIZES) {
-                                add(new Object[]{algorithm, dataSize, blockSize});
-                            }
-                        }
-                    }
-                }
-            });
-
-    @Parameters(name = "{0} - dataSize={1}, blockSize={2}")
-    public static Collection<Object[]> parameters() {
-        return PARAMETERS;
-    }
-
-    private final String algorithm;
-    private final int dataSize, blockSize;
-
-    public AbstractCheckFileExtensionTest(String algorithm, int dataSize, int blockSize) throws IOException {
-        this.algorithm = algorithm;
-        this.dataSize = dataSize;
-        this.blockSize = blockSize;
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        setupServer();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        tearDownServer();
-    }
-
-    @Test
-    public void testCheckFileExtension() throws Exception {
-        testCheckFileExtension(algorithm, dataSize, blockSize);
-    }
-
-    private void testCheckFileExtension(String expectedAlgorithm, int inputDataSize, int hashBlockSize) throws Exception {
-        NamedFactory<? extends Digest> factory = BuiltinDigests.fromFactoryName(expectedAlgorithm);
-        Digest digest = null;
-        if (blockSize == 0) {
-            digest = factory.create();
-            digest.init();
-        }
-
-        byte[] seed = (getClass().getName() + "#" + getCurrentTestName()
-                + "-" + expectedAlgorithm
-                + "-" + inputDataSize + "/" + hashBlockSize
-                + IoUtils.EOL)
-                .getBytes(StandardCharsets.UTF_8);
-
-        try (ByteArrayOutputStream baos = new ByteArrayOutputStream(inputDataSize + seed.length)) {
-            while (baos.size() < inputDataSize) {
-                baos.write(seed);
-
-                if (digest != null) {
-                    digest.update(seed);
-                }
-            }
-
-            testCheckFileExtension(factory, baos.toByteArray(), hashBlockSize, (digest == null) ? null : digest.digest());
-        }
-    }
-
-    private void testCheckFileExtension(NamedFactory<? extends Digest> factory, byte[] data, int hashBlockSize, byte[] expectedHash) throws Exception {
-        Path targetPath = detectTargetFolder();
-        Path lclSftp = Utils.resolve(targetPath, SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName());
-        Path srcFile = assertHierarchyTargetFolderExists(lclSftp).resolve(factory.getName() + "-data-" + data.length + "-" + hashBlockSize + ".txt");
-        Files.write(srcFile, data, IoUtils.EMPTY_OPEN_OPTIONS);
-
-        List<String> algorithms = new ArrayList<String>(BuiltinDigests.VALUES.size());
-        // put the selected algorithm 1st and then the rest
-        algorithms.add(factory.getName());
-        for (NamedFactory<? extends Digest> f : BuiltinDigests.VALUES) {
-            if (f == factory) {
-                continue;
-            }
-
-            algorithms.add(f.getName());
-        }
-
-        Path parentPath = targetPath.getParent();
-        String srcPath = Utils.resolveRelativeRemotePath(parentPath, srcFile);
-        String srcFolder = Utils.resolveRelativeRemotePath(parentPath, srcFile.getParent());
-
-        try (SshClient client = setupTestClient()) {
-            client.start();
-
-            try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
-                session.addPasswordIdentity(getCurrentTestName());
-                session.auth().verify(5L, TimeUnit.SECONDS);
-
-                try (SftpClient sftp = session.createSftpClient()) {
-                    CheckFileNameExtension file = assertExtensionCreated(sftp, CheckFileNameExtension.class);
-                    try {
-                        Pair<String, ?> result = file.checkFileName(srcFolder, algorithms, 0L, 0L, hashBlockSize);
-                        fail("Unexpected success to hash folder=" + srcFolder + ": " + result.getFirst());
-                    } catch (IOException e) {    // expected - not allowed to hash a folder
-                        assertTrue("Not an SftpException", e instanceof SftpException);
-                    }
-
-                    CheckFileHandleExtension hndl = assertExtensionCreated(sftp, CheckFileHandleExtension.class);
-                    try (CloseableHandle dirHandle = sftp.openDir(srcFolder)) {
-                        try {
-                            Pair<String, ?> result = hndl.checkFileHandle(dirHandle, algorithms, 0L, 0L, hashBlockSize);
-                            fail("Unexpected handle success on folder=" + srcFolder + ": " + result.getFirst());
-                        } catch (IOException e) {    // expected - not allowed to hash a folder
-                            assertTrue("Not an SftpException", e instanceof SftpException);
-                        }
-                    }
-
-                    validateHashResult(file, file.checkFileName(srcPath, algorithms, 0L, 0L, hashBlockSize), algorithms.get(0), expectedHash);
-                    try (CloseableHandle fileHandle = sftp.open(srcPath, SftpClient.OpenMode.Read)) {
-                        validateHashResult(hndl, hndl.checkFileHandle(fileHandle, algorithms, 0L, 0L, hashBlockSize), algorithms.get(0), expectedHash);
-                    }
-                }
-            } finally {
-                client.stop();
-            }
-        }
-    }
-
-    private void validateHashResult(NamedResource hasher, Pair<String, Collection<byte[]>> result, String expectedAlgorithm, byte[] expectedHash) {
-        String name = hasher.getName();
-        assertNotNull("No result for hash=" + name, result);
-        assertEquals("Mismatched hash algorithms for " + name, expectedAlgorithm, result.getFirst());
-
-        if (NumberUtils.length(expectedHash) > 0) {
-            Collection<byte[]> values = result.getSecond();
-            assertEquals("Mismatched hash values count for " + name, 1, GenericUtils.size(values));
-
-            byte[] actualHash = values.iterator().next();
-            if (!Arrays.equals(expectedHash, actualHash)) {
-                fail("Mismatched hashes for " + name
-                   + ": expected=" + BufferUtils.toHex(':', expectedHash)
-                   + ", actual=" + BufferUtils.toHex(':', expectedHash));
-            }
-        }
-    }
-}