http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/251db9b9/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java 
b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
deleted file mode 100644
index a6f162f..0000000
--- 
a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
+++ /dev/null
@@ -1,1500 +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;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.SocketTimeoutException;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.nio.channels.SeekableByteChannel;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.CopyOption;
-import java.nio.file.DirectoryStream;
-import java.nio.file.FileSystem;
-import java.nio.file.Files;
-import java.nio.file.LinkOption;
-import java.nio.file.OpenOption;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
-import java.nio.file.attribute.FileAttribute;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.EnumSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.Vector;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.atomic.AtomicReference;
-
-import com.jcraft.jsch.ChannelSftp;
-import com.jcraft.jsch.JSch;
-
-import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.client.subsystem.sftp.SftpClient.Attributes;
-import org.apache.sshd.client.subsystem.sftp.SftpClient.CloseableHandle;
-import org.apache.sshd.client.subsystem.sftp.SftpClient.DirEntry;
-import org.apache.sshd.client.subsystem.sftp.SftpClient.OpenMode;
-import 
org.apache.sshd.client.subsystem.sftp.extensions.BuiltinSftpClientExtensions;
-import org.apache.sshd.client.subsystem.sftp.extensions.SftpClientExtension;
-import org.apache.sshd.common.Factory;
-import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.OptionalFeature;
-import org.apache.sshd.common.PropertyResolverUtils;
-import org.apache.sshd.common.channel.WindowClosedException;
-import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
-import org.apache.sshd.common.random.Random;
-import org.apache.sshd.common.subsystem.sftp.SftpConstants;
-import org.apache.sshd.common.subsystem.sftp.SftpException;
-import 
org.apache.sshd.common.subsystem.sftp.extensions.AclSupportedParser.AclCapabilities;
-import org.apache.sshd.common.subsystem.sftp.extensions.NewlineParser.Newline;
-import org.apache.sshd.common.subsystem.sftp.extensions.ParserUtils;
-import 
org.apache.sshd.common.subsystem.sftp.extensions.Supported2Parser.Supported2;
-import 
org.apache.sshd.common.subsystem.sftp.extensions.SupportedParser.Supported;
-import 
org.apache.sshd.common.subsystem.sftp.extensions.VersionsParser.Versions;
-import 
org.apache.sshd.common.subsystem.sftp.extensions.openssh.AbstractOpenSSHExtensionParser.OpenSSHExtension;
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.OsUtils;
-import org.apache.sshd.common.util.buffer.BufferUtils;
-import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
-import org.apache.sshd.common.util.io.IoUtils;
-import org.apache.sshd.server.Command;
-import org.apache.sshd.server.session.ServerSession;
-import org.apache.sshd.server.subsystem.sftp.AbstractSftpEventListenerAdapter;
-import org.apache.sshd.server.subsystem.sftp.AbstractSftpSubsystemHelper;
-import org.apache.sshd.server.subsystem.sftp.DirectoryHandle;
-import org.apache.sshd.server.subsystem.sftp.FileHandle;
-import org.apache.sshd.server.subsystem.sftp.Handle;
-import org.apache.sshd.server.subsystem.sftp.SftpEventListener;
-import org.apache.sshd.server.subsystem.sftp.SftpEventListenerManager;
-import org.apache.sshd.server.subsystem.sftp.SftpFileSystemAccessor;
-import org.apache.sshd.server.subsystem.sftp.SftpSubsystemEnvironment;
-import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
-import org.apache.sshd.util.test.SimpleUserInfo;
-import org.apache.sshd.util.test.Utils;
-import org.junit.After;
-import org.junit.Assume;
-import org.junit.Before;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
-
-/**
- * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
- */
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class SftpTest extends AbstractSftpClientTestSupport {
-    private static final Map<String, OptionalFeature> EXPECTED_EXTENSIONS = 
AbstractSftpSubsystemHelper.DEFAULT_SUPPORTED_CLIENT_EXTENSIONS;
-
-    private com.jcraft.jsch.Session session;
-
-    public SftpTest() throws IOException {
-        super();
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        setupServer();
-        JSch sch = new JSch();
-        session = sch.getSession("sshd", TEST_LOCALHOST, port);
-        session.setUserInfo(new SimpleUserInfo("sshd"));
-        session.connect();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        if (session != null) {
-            session.disconnect();
-        }
-    }
-
-    @Test   // see SSHD-547
-    public void testWriteOffsetIgnoredForAppendMode() throws IOException {
-        Path targetPath = detectTargetFolder();
-        Path parentPath = targetPath.getParent();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Path testFile = 
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
-        Files.deleteIfExists(testFile);
-
-        byte[] expectedRandom = new byte[Byte.MAX_VALUE];
-        Factory<? extends Random> factory = sshd.getRandomFactory();
-        Random rnd = factory.create();
-        rnd.fill(expectedRandom);
-
-        byte[] expectedText = (getClass().getName() + "#" + 
getCurrentTestName()).getBytes(StandardCharsets.UTF_8);
-        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()) {
-                String file = Utils.resolveRelativeRemotePath(parentPath, 
testFile);
-
-                try (CloseableHandle handle = sftp.open(file, OpenMode.Create, 
OpenMode.Write, OpenMode.Read, OpenMode.Append)) {
-                    sftp.write(handle, 7365L, expectedRandom);
-                    byte[] actualRandom = new byte[expectedRandom.length];
-                    int readLen = sftp.read(handle, 0L, actualRandom);
-                    assertEquals("Incomplete random data read", 
expectedRandom.length, readLen);
-                    assertArrayEquals("Mismatched read random data", 
expectedRandom, actualRandom);
-
-                    sftp.write(handle, 3777347L, expectedText);
-                    byte[] actualText = new byte[expectedText.length];
-                    readLen = sftp.read(handle, actualRandom.length, 
actualText);
-                    assertEquals("Incomplete text data read", 
actualText.length, readLen);
-                    assertArrayEquals("Mismatched read text data", 
expectedText, actualText);
-                }
-            }
-        }
-
-        byte[] actualBytes = Files.readAllBytes(testFile);
-        assertEquals("Mismatched result file size", expectedRandom.length + 
expectedText.length, actualBytes.length);
-
-        byte[] actualRandom = Arrays.copyOfRange(actualBytes, 0, 
expectedRandom.length);
-        assertArrayEquals("Mismatched random part", expectedRandom, 
actualRandom);
-
-        byte[] actualText = Arrays.copyOfRange(actualBytes, 
expectedRandom.length, actualBytes.length);
-        assertArrayEquals("Mismatched text part", expectedText, actualText);
-    }
-
-    @Test   // see SSHD-545
-    public void testReadBufferLimit() throws Exception {
-        Path targetPath = detectTargetFolder();
-        Path parentPath = targetPath.getParent();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Path testFile = 
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
-        byte[] expected = new byte[1024];
-
-        Factory<? extends Random> factory = sshd.getRandomFactory();
-        Random rnd = factory.create();
-        rnd.fill(expected);
-        Files.write(testFile, expected);
-
-        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()) {
-                String file = Utils.resolveRelativeRemotePath(parentPath, 
testFile);
-                byte[] actual = new byte[expected.length];
-                int maxAllowed = actual.length / 4;
-                // allow less than actual
-                PropertyResolverUtils.updateProperty(sshd, 
AbstractSftpSubsystemHelper.MAX_READDATA_PACKET_LENGTH_PROP, maxAllowed);
-                try (CloseableHandle handle = sftp.open(file, OpenMode.Read)) {
-                    int readLen = sftp.read(handle, 0L, actual);
-                    assertEquals("Mismatched read len", maxAllowed, readLen);
-
-                    for (int index = 0; index < readLen; index++) {
-                        byte expByte = expected[index];
-                        byte actByte = actual[index];
-                        if (expByte != actByte) {
-                            fail("Mismatched values at index=" + index
-                                + ": expected=0x" + 
Integer.toHexString(expByte & 0xFF)
-                                + ", actual=0x" + Integer.toHexString(actByte 
& 0xFF));
-                        }
-                    }
-                } finally {
-                    PropertyResolverUtils.updateProperty(sshd,
-                        
AbstractSftpSubsystemHelper.MAX_READDATA_PACKET_LENGTH_PROP,
-                        
AbstractSftpSubsystemHelper.DEFAULT_MAX_READDATA_PACKET_LENGTH);
-                }
-            }
-        }
-    }
-
-    @Test   // see extra fix for SSHD-538
-    public void testNavigateBeyondRootFolder() throws Exception {
-        Path rootLocation = Paths.get(OsUtils.isUNIX() ? "/" : "C:\\");
-        final FileSystem fsRoot = rootLocation.getFileSystem();
-        sshd.setFileSystemFactory(session1 -> fsRoot);
-
-        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()) {
-                String rootDir = sftp.canonicalPath("/");
-                String upDir = sftp.canonicalPath(rootDir + "/..");
-                assertEquals("Mismatched root dir parent", rootDir, upDir);
-            }
-        }
-    }
-
-    @Test   // see SSHD-605
-    public void testCannotEscapeUserAbsoluteRoot() throws Exception {
-        testCannotEscapeRoot(true);
-    }
-
-    @Test   // see SSHD-605
-    public void testCannotEscapeUserRelativeRoot() throws Exception {
-        testCannotEscapeRoot(false);
-    }
-
-    private void testCannotEscapeRoot(boolean useAbsolutePath) throws 
Exception {
-        Path targetPath = detectTargetFolder();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        assertHierarchyTargetFolderExists(lclSftp);
-        sshd.setFileSystemFactory(new VirtualFileSystemFactory(lclSftp));
-
-        try (ClientSession session = client.connect(getCurrentTestName(), 
TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
-            session.addPasswordIdentity(getCurrentTestName());
-            session.auth().verify(5L, TimeUnit.SECONDS);
-
-            String escapePath;
-            if (useAbsolutePath) {
-                escapePath = targetPath.toString();
-                if (OsUtils.isWin32()) {
-                    escapePath = "/" + escapePath.replace(File.separatorChar, 
'/');
-                }
-            } else {
-                Path parent = lclSftp.getParent();
-                Path forbidden = 
Files.createDirectories(parent.resolve("forbidden"));
-                escapePath = "../" + forbidden.getFileName();
-            }
-
-            try (SftpClient sftp = session.createSftpClient()) {
-                SftpClient.Attributes attrs = sftp.stat(escapePath);
-                fail("Unexpected escape success for path=" + escapePath + ": " 
+ attrs);
-            } catch (SftpException e) {
-                int expected = OsUtils.isWin32() || (!useAbsolutePath)
-                        ? SftpConstants.SSH_FX_INVALID_FILENAME
-                        : SftpConstants.SSH_FX_NO_SUCH_FILE;
-                assertEquals("Mismatched status for " + escapePath,
-                             SftpConstants.getStatusName(expected),
-                             SftpConstants.getStatusName(e.getStatus()));
-            }
-        }
-    }
-
-    @Test
-    public void testNormalizeRemoteRootValues() throws Exception {
-        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()) {
-                StringBuilder sb = new StringBuilder(Long.SIZE + 1);
-                String expected = sftp.canonicalPath("/");
-                for (int i = 0; i < Long.SIZE; i++) {
-                    if (sb.length() > 0) {
-                        sb.setLength(0);
-                    }
-
-                    for (int j = 1; j <= i; j++) {
-                        sb.append('/');
-                    }
-
-                    String remotePath = sb.toString();
-                    String actual = sftp.canonicalPath(remotePath);
-                    assertEquals("Mismatched roots for " + remotePath.length() 
+ " slashes", expected, actual);
-                }
-            }
-        }
-    }
-
-    @Test
-    public void testNormalizeRemotePathsValues() throws Exception {
-        Path targetPath = detectTargetFolder();
-        Path parentPath = targetPath.getParent();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Path testFile = 
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
-        String file = Utils.resolveRelativeRemotePath(parentPath, testFile);
-        String[] comps = GenericUtils.split(file, '/');
-
-        Factory<? extends Random> factory = client.getRandomFactory();
-        Random rnd = factory.create();
-        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()) {
-                StringBuilder sb = new StringBuilder(file.length() + 
comps.length);
-                String expected = sftp.canonicalPath(file);
-                for (int i = 0; i < file.length(); i++) {
-                    if (sb.length() > 0) {
-                        sb.setLength(0);
-                    }
-
-                    sb.append(comps[0]);
-                    for (int j = 1; j < comps.length; j++) {
-                        String name = comps[j];
-                        slashify(sb, rnd);
-                        sb.append(name);
-                    }
-                    slashify(sb, rnd);
-
-                    if (rnd.random(Byte.SIZE) < (Byte.SIZE / 2)) {
-                        sb.append('.');
-                    }
-
-                    String remotePath = sb.toString();
-                    String actual = sftp.canonicalPath(remotePath);
-                    assertEquals("Mismatched canonical value for " + 
remotePath, expected, actual);
-                }
-            }
-        }
-    }
-
-    private static int slashify(StringBuilder sb, Random rnd) {
-        int slashes = 1 /* at least one slash */ + rnd.random(Byte.SIZE);
-        for (int k = 0; k < slashes; k++) {
-            sb.append('/');
-        }
-
-        return slashes;
-    }
-
-    @Test
-    public void testOpen() throws Exception {
-        Path targetPath = detectTargetFolder();
-        Path parentPath = targetPath.getParent();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Path clientFolder = lclSftp.resolve("client");
-        Path testFile = clientFolder.resolve("file.txt");
-        String file = Utils.resolveRelativeRemotePath(parentPath, testFile);
-
-        File javaFile = testFile.toFile();
-        assertHierarchyTargetFolderExists(javaFile.getParentFile());
-
-        try (ClientSession session = client.connect(getCurrentTestName(), 
TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
-            session.addPasswordIdentity(getCurrentTestName());
-            session.auth().verify(5L, TimeUnit.SECONDS);
-
-            javaFile.createNewFile();
-            javaFile.setWritable(false, false);
-            javaFile.setReadable(false, false);
-
-            try (SftpClient sftp = session.createSftpClient()) {
-                boolean isWindows = OsUtils.isWin32();
-
-                try (SftpClient.CloseableHandle h = sftp.open(file /* no mode 
== read */)) {
-                    // NOTE: on Windows files are always readable
-                    // see 
https://svn.apache.org/repos/asf/harmony/enhanced/java/branches/java6/classlib/modules/
-                    //      
luni/src/test/api/windows/org/apache/harmony/luni/tests/java/io/WinFileTest.java
-                    assertTrue("Empty read should have failed on " + file, 
isWindows);
-                } catch (IOException e) {
-                    if (isWindows) {
-                        throw e;
-                    }
-                }
-
-                try (SftpClient.CloseableHandle h = sftp.open(file, 
EnumSet.of(SftpClient.OpenMode.Write))) {
-                    fail("Empty write should have failed on " + file);
-                } catch (IOException e) {
-                    // ok
-                }
-
-                try (SftpClient.CloseableHandle h = sftp.open(file, 
EnumSet.of(SftpClient.OpenMode.Truncate))) {
-                    // NOTE: on Windows files are always readable
-                    assertTrue("Empty truncate should have failed on " + file, 
isWindows);
-                } catch (IOException e) {
-                    // ok
-                }
-
-                // NOTE: on Windows files are always readable
-                int perms = sftp.stat(file).getPermissions();
-                int readMask = isWindows ? 0 : SftpConstants.S_IRUSR;
-                int permsMask = SftpConstants.S_IWUSR | readMask;
-                assertEquals("Mismatched permissions for " + file + ": 0x" + 
Integer.toHexString(perms), 0, perms & permsMask);
-
-                javaFile.setWritable(true, false);
-
-                try (SftpClient.CloseableHandle h = sftp.open(file, 
EnumSet.of(SftpClient.OpenMode.Truncate, SftpClient.OpenMode.Write))) {
-                    // OK should succeed
-                    assertTrue("Handle not marked as open for file=" + file, 
h.isOpen());
-                }
-
-                byte[] d = "0123456789\n".getBytes(StandardCharsets.UTF_8);
-                try (SftpClient.CloseableHandle h = sftp.open(file, 
EnumSet.of(SftpClient.OpenMode.Write))) {
-                    sftp.write(h, 0, d, 0, d.length);
-                    sftp.write(h, d.length, d, 0, d.length);
-                }
-
-                try (SftpClient.CloseableHandle h = sftp.open(file, 
EnumSet.of(SftpClient.OpenMode.Write))) {
-                    sftp.write(h, d.length * 2, d, 0, d.length);
-                }
-
-                try (SftpClient.CloseableHandle h = sftp.open(file, 
EnumSet.of(SftpClient.OpenMode.Write))) {
-                    byte[] overwrite = "-".getBytes(StandardCharsets.UTF_8);
-                    sftp.write(h, 3L, overwrite, 0, 1);
-                    d[3] = overwrite[0];
-                }
-
-                try (SftpClient.CloseableHandle h = sftp.open(file /* no mode 
== read */)) {
-                    // NOTE: on Windows files are always readable
-                    assertTrue("Data read should have failed on " + file, 
isWindows);
-                } catch (IOException e) {
-                    if (isWindows) {
-                        throw e;
-                    }
-                }
-
-                javaFile.setReadable(true, false);
-
-                byte[] buf = new byte[3];
-                try (SftpClient.CloseableHandle h = sftp.open(file /* no mode 
== read */)) {
-                    int l = sftp.read(h, 2L, buf, 0, buf.length);
-                    String expected = new String(d, 2, l, 
StandardCharsets.UTF_8);
-                    String actual = new String(buf, 0, l, 
StandardCharsets.UTF_8);
-                    assertEquals("Mismatched read data", expected, actual);
-                }
-            }
-        }
-    }
-
-    @Test
-    public void testInputStreamSkipAndReset() throws Exception {
-        Path targetPath = detectTargetFolder();
-        Path parentPath = targetPath.getParent();
-        Path localFile = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Files.createDirectories(localFile.getParent());
-        byte[] data = (getClass().getName() + "#" + getCurrentTestName() + "[" 
+ localFile + "]").getBytes(StandardCharsets.UTF_8);
-        Files.write(localFile, data, StandardOpenOption.CREATE);
-        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();
-                 InputStream stream = 
sftp.read(Utils.resolveRelativeRemotePath(parentPath, localFile), 
OpenMode.Read)) {
-                assertFalse("Stream reported mark supported", 
stream.markSupported());
-                try {
-                    stream.mark(data.length);
-                    fail("Unexpected success to mark the read limit");
-                } catch (UnsupportedOperationException e) {
-                    // expected - ignored
-                }
-
-                byte[] expected = new byte[data.length / 4];
-                int readLen = stream.read(expected);
-                assertEquals("Failed to read fully initial data", 
expected.length, readLen);
-
-                byte[] actual = new byte[readLen];
-                stream.reset();
-                readLen = stream.read(actual);
-                assertEquals("Failed to read fully reset data", actual.length, 
readLen);
-                assertArrayEquals("Mismatched re-read data contents", 
expected, actual);
-
-                System.arraycopy(data, 0, expected, 0, expected.length);
-                assertArrayEquals("Mismatched original data contents", 
expected, actual);
-
-                long skipped = stream.skip(readLen);
-                assertEquals("Mismatched skipped forward size", readLen, 
skipped);
-
-                readLen = stream.read(actual);
-                assertEquals("Failed to read fully skipped forward data", 
actual.length, readLen);
-
-                System.arraycopy(data, expected.length + readLen, expected, 0, 
expected.length);
-                assertArrayEquals("Mismatched skipped forward data contents", 
expected, actual);
-
-                skipped = stream.skip(0 - readLen);
-                assertEquals("Mismatched backward skip size", readLen, 
skipped);
-                readLen = stream.read(actual);
-                assertEquals("Failed to read fully skipped backward data", 
actual.length, readLen);
-                assertArrayEquals("Mismatched skipped backward data contents", 
expected, actual);
-            }
-        }
-    }
-
-    @Test
-    public void testSftpFileSystemAccessor() throws Exception {
-        List<NamedFactory<Command>> factories = sshd.getSubsystemFactories();
-        assertEquals("Mismatched subsystem factories count", 1, 
GenericUtils.size(factories));
-
-        NamedFactory<Command> f = factories.get(0);
-        assertObjectInstanceOf("Not an SFTP subsystem factory", 
SftpSubsystemFactory.class, f);
-
-        SftpSubsystemFactory factory = (SftpSubsystemFactory) f;
-        SftpFileSystemAccessor accessor = factory.getFileSystemAccessor();
-        try {
-            AtomicReference<Path> fileHolder = new AtomicReference<>();
-            AtomicReference<Path> dirHolder = new AtomicReference<>();
-            factory.setFileSystemAccessor(new SftpFileSystemAccessor() {
-                @Override
-                public SeekableByteChannel openFile(ServerSession session, 
SftpEventListenerManager subsystem, Path file,
-                        String handle, Set<? extends OpenOption> options, 
FileAttribute<?>... attrs)
-                                throws IOException {
-                    fileHolder.set(file);
-                    return SftpFileSystemAccessor.super.openFile(session, 
subsystem, file, handle, options, attrs);
-                }
-
-                @Override
-                public DirectoryStream<Path> openDirectory(
-                        ServerSession session, SftpEventListenerManager 
subsystem, Path dir, String handle) throws IOException {
-                    dirHolder.set(dir);
-                    return SftpFileSystemAccessor.super.openDirectory(session, 
subsystem, dir, handle);
-                }
-
-                @Override
-                public String toString() {
-                    return SftpFileSystemAccessor.class.getSimpleName() + "[" 
+ getCurrentTestName() + "]";
-                }
-            });
-
-            Path targetPath = detectTargetFolder();
-            Path parentPath = targetPath.getParent();
-            Path localFile = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-            Files.createDirectories(localFile.getParent());
-            byte[] expected = (getClass().getName() + "#" + 
getCurrentTestName() + "[" + localFile + "]").getBytes(StandardCharsets.UTF_8);
-            Files.write(localFile, expected, StandardOpenOption.CREATE);
-            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()) {
-                    byte[] actual = new byte[expected.length];
-                    try (InputStream stream = 
sftp.read(Utils.resolveRelativeRemotePath(parentPath, localFile), 
OpenMode.Read)) {
-                        IoUtils.readFully(stream, actual);
-                    }
-
-                    Path remoteFile = fileHolder.getAndSet(null);
-                    assertNotNull("No remote file holder value", remoteFile);
-                    assertEquals("Mismatched opened local files", 
localFile.toFile(), remoteFile.toFile());
-                    assertArrayEquals("Mismatched retrieved file contents", 
expected, actual);
-
-                    Path localParent = localFile.getParent();
-                    String localName = 
Objects.toString(localFile.getFileName(), null);
-                    try (CloseableHandle handle = 
sftp.openDir(Utils.resolveRelativeRemotePath(parentPath, localParent))) {
-                        List<DirEntry> entries = sftp.readDir(handle);
-                        Path remoteParent = dirHolder.getAndSet(null);
-                        assertNotNull("No remote folder holder value", 
remoteParent);
-                        assertEquals("Mismatched opened folder", 
localParent.toFile(), remoteParent.toFile());
-                        assertFalse("No dir entries", 
GenericUtils.isEmpty(entries));
-
-                        for (DirEntry de : entries) {
-                            Attributes attrs = de.getAttributes();
-                            if (!attrs.isRegularFile()) {
-                                continue;
-                            }
-
-                            if (localName.equals(de.getFilename())) {
-                                return;
-                            }
-                        }
-
-                        fail("Cannot find listing of " + localName);
-                    }
-                }
-            }
-        } finally {
-            factory.setFileSystemAccessor(accessor);    // restore original
-        }
-    }
-
-    @Test
-    @SuppressWarnings({"checkstyle:anoninnerlength", 
"checkstyle:methodlength"})
-    public void testClient() throws Exception {
-        List<NamedFactory<Command>> factories = sshd.getSubsystemFactories();
-        assertEquals("Mismatched subsystem factories count", 1, 
GenericUtils.size(factories));
-
-        NamedFactory<Command> f = factories.get(0);
-        assertObjectInstanceOf("Not an SFTP subsystem factory", 
SftpSubsystemFactory.class, f);
-
-        SftpSubsystemFactory factory = (SftpSubsystemFactory) f;
-        final AtomicInteger versionHolder = new AtomicInteger(-1);
-        final AtomicInteger openCount = new AtomicInteger(0);
-        final AtomicInteger closeCount = new AtomicInteger(0);
-        final AtomicLong readSize = new AtomicLong(0L);
-        final AtomicLong writeSize = new AtomicLong(0L);
-        final AtomicInteger entriesCount = new AtomicInteger(0);
-        final AtomicInteger creatingCount = new AtomicInteger(0);
-        final AtomicInteger createdCount = new AtomicInteger(0);
-        final AtomicInteger removingCount = new AtomicInteger(0);
-        final AtomicInteger removedCount = new AtomicInteger(0);
-        final AtomicInteger modifyingCount = new AtomicInteger(0);
-        final AtomicInteger modifiedCount = new AtomicInteger(0);
-        SftpEventListener listener = new AbstractSftpEventListenerAdapter() {
-            @Override
-            public void initialized(ServerSession session, int version) {
-                log.info("initialized(" + session + ") version: " + version);
-                assertTrue("Initialized version below minimum", version >= 
SftpSubsystemEnvironment.LOWER_SFTP_IMPL);
-                assertTrue("Initialized version above maximum", version <= 
SftpSubsystemEnvironment.HIGHER_SFTP_IMPL);
-                assertTrue("Initializion re-called", 
versionHolder.getAndSet(version) < 0);
-            }
-
-            @Override
-            public void destroying(ServerSession session) {
-                log.info("destroying(" + session + ")");
-                assertTrue("Initialization method not called", 
versionHolder.get() > 0);
-            }
-
-            @Override
-            public void written(ServerSession session, String remoteHandle, 
FileHandle localHandle,
-                    long offset, byte[] data, int dataOffset, int dataLen, 
Throwable thrown) {
-                writeSize.addAndGet(dataLen);
-                if (log.isDebugEnabled()) {
-                    log.debug("write(" + session + ")[" + 
localHandle.getFile() + "] offset=" + offset + ", requested=" + dataLen);
-                }
-            }
-
-            @Override
-            public void removing(ServerSession session, Path path) {
-                removingCount.incrementAndGet();
-                log.info("removing(" + session + ") " + path);
-            }
-
-            @Override
-            public void removed(ServerSession session, Path path, Throwable 
thrown) {
-                removedCount.incrementAndGet();
-                log.info("removed(" + session + ") " + path
-                       + ((thrown == null) ? "" : (": " + 
thrown.getClass().getSimpleName() + ": " + thrown.getMessage())));
-            }
-
-            @Override
-            public void modifyingAttributes(ServerSession session, Path path, 
Map<String, ?> attrs) {
-                modifyingCount.incrementAndGet();
-                log.info("modifyingAttributes(" + session + ") " + path);
-            }
-
-            @Override
-            public void modifiedAttributes(ServerSession session, Path path, 
Map<String, ?> attrs, Throwable thrown) {
-                modifiedCount.incrementAndGet();
-                log.info("modifiedAttributes(" + session + ") " + path
-                       + ((thrown == null) ? "" : (": " + 
thrown.getClass().getSimpleName() + ": " + thrown.getMessage())));
-            }
-
-            @Override
-            public void read(ServerSession session, String remoteHandle, 
FileHandle localHandle, long offset, byte[] data,
-                    int dataOffset, int dataLen, int readLen, Throwable 
thrown) {
-                readSize.addAndGet(readLen);
-                if (log.isDebugEnabled()) {
-                    log.debug("read(" + session + ")[" + localHandle.getFile() 
+ "] offset=" + offset + ", requested=" + dataLen + ", read=" + readLen);
-                }
-            }
-
-            @Override
-            public void read(ServerSession session, String remoteHandle, 
DirectoryHandle localHandle, Map<String, Path> entries) {
-                int numEntries = GenericUtils.size(entries);
-                entriesCount.addAndGet(numEntries);
-
-                if (log.isDebugEnabled()) {
-                    log.debug("read(" + session + ")[" + localHandle.getFile() 
+ "] " + numEntries + " entries");
-                }
-
-                if ((numEntries > 0) && log.isTraceEnabled()) {
-                    entries.forEach((key, value) ->
-                        log.trace("read(" + session + ")[" + 
localHandle.getFile() + "] " + key + " - " + value));
-                }
-            }
-
-            @Override
-            public void open(ServerSession session, String remoteHandle, 
Handle localHandle) {
-                Path path = localHandle.getFile();
-                log.info("open(" + session + ")[" + remoteHandle + "] " + 
(Files.isDirectory(path) ? "directory" : "file") + " " + path);
-                openCount.incrementAndGet();
-            }
-
-            @Override
-            public void moving(ServerSession session, Path srcPath, Path 
dstPath, Collection<CopyOption> opts) {
-                log.info("moving(" + session + ")[" + opts + "]" + srcPath + " 
=> " + dstPath);
-            }
-
-            @Override
-            public void moved(ServerSession session, Path srcPath, Path 
dstPath, Collection<CopyOption> opts, Throwable thrown) {
-                log.info("moved(" + session + ")[" + opts + "]" + srcPath + " 
=> " + dstPath
-                       + ((thrown == null) ? "" : (": " + 
thrown.getClass().getSimpleName() + ": " + thrown.getMessage())));
-            }
-
-            @Override
-            public void linking(ServerSession session, Path src, Path target, 
boolean symLink) {
-                log.info("linking(" + session + ")[" + symLink + "]" + src + " 
=> " + target);
-            }
-
-            @Override
-            public void linked(ServerSession session, Path src, Path target, 
boolean symLink, Throwable thrown) {
-                log.info("linked(" + session + ")[" + symLink + "]" + src + " 
=> " + target
-                      + ((thrown == null) ? "" : (": " + 
thrown.getClass().getSimpleName() + ": " + thrown.getMessage())));
-            }
-
-            @Override
-            public void creating(ServerSession session, Path path, Map<String, 
?> attrs) {
-                creatingCount.incrementAndGet();
-                log.info("creating(" + session + ") " + 
(Files.isDirectory(path) ? "directory" : "file") + " " + path);
-            }
-
-            @Override
-            public void created(ServerSession session, Path path, Map<String, 
?> attrs, Throwable thrown) {
-                createdCount.incrementAndGet();
-                log.info("created(" + session + ") " + 
(Files.isDirectory(path) ? "directory" : "file") + " " + path
-                       + ((thrown == null) ? "" : (": " + 
thrown.getClass().getSimpleName() + ": " + thrown.getMessage())));
-            }
-
-            @Override
-            public void blocking(ServerSession session, String remoteHandle, 
FileHandle localHandle, long offset, long length, int mask) {
-                log.info("blocking(" + session + ")[" + localHandle.getFile() 
+ "]"
-                       + " offset=" + offset + ", length=" + length + ", 
mask=0x" + Integer.toHexString(mask));
-            }
-
-            @Override
-            public void blocked(ServerSession session, String remoteHandle, 
FileHandle localHandle,
-                                long offset, long length, int mask, Throwable 
thrown) {
-                log.info("blocked(" + session + ")[" + localHandle.getFile() + 
"]"
-                       + " offset=" + offset + ", length=" + length + ", 
mask=0x" + Integer.toHexString(mask)
-                       + ((thrown == null) ? "" : (": " + 
thrown.getClass().getSimpleName() + ": " + thrown.getMessage())));
-            }
-
-            @Override
-            public void unblocking(ServerSession session, String remoteHandle, 
FileHandle localHandle, long offset, long length) {
-                log.info("unblocking(" + session + ")[" + 
localHandle.getFile() + "] offset=" + offset + ", length=" + length);
-            }
-
-            @Override
-            public void unblocked(ServerSession session, String remoteHandle, 
FileHandle localHandle,
-                                  long offset, long length, Throwable thrown) {
-                log.info("unblocked(" + session + ")[" + localHandle.getFile() 
+ "]"
-                       + " offset=" + offset + ", length=" + length
-                       + ((thrown == null) ? "" : (": " + 
thrown.getClass().getSimpleName() + ": " + thrown.getMessage())));
-            }
-
-            @Override
-            public void close(ServerSession session, String remoteHandle, 
Handle localHandle) {
-                Path path = localHandle.getFile();
-                log.info("close(" + session + ")[" + remoteHandle + "] " + 
(Files.isDirectory(path) ? "directory" : "file") + " " + path);
-                closeCount.incrementAndGet();
-            }
-        };
-        factory.addSftpEventListener(listener);
-
-        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()) {
-                assertEquals("Mismatched negotiated version", 
sftp.getVersion(), versionHolder.get());
-                testClient(client, sftp);
-            }
-
-            assertEquals("Mismatched open/close count", openCount.get(), 
closeCount.get());
-            assertTrue("No entries read", entriesCount.get() > 0);
-            assertTrue("No data read", readSize.get() > 0L);
-            assertTrue("No data written", writeSize.get() > 0L);
-            assertEquals("Mismatched removal counts", removingCount.get(), 
removedCount.get());
-            assertTrue("No removals signalled", removedCount.get() > 0);
-            assertEquals("Mismatched creation counts", creatingCount.get(), 
createdCount.get());
-            assertTrue("No creations signalled", creatingCount.get() > 0);
-            assertEquals("Mismatched modification counts", 
modifyingCount.get(), modifiedCount.get());
-            assertTrue("No modifications signalled", modifiedCount.get() > 0);
-        } finally {
-            factory.removeSftpEventListener(listener);
-        }
-    }
-
-    /**
-     * this test is meant to test out write's logic, to ensure that internal 
chunking (based on Buffer.MAX_LEN) is
-     * functioning properly. To do this, we write a variety of file sizes, 
both smaller and larger than Buffer.MAX_LEN.
-     * in addition, this test ensures that improper arguments passed in get 
caught with an IllegalArgumentException
-     *
-     * @throws Exception upon any uncaught exception or failure
-     */
-    @Test
-    public void testWriteChunking() throws Exception {
-        try (ClientSession session = client.connect(getCurrentTestName(), 
TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
-            session.addPasswordIdentity(getCurrentTestName());
-            session.auth().verify(5L, TimeUnit.SECONDS);
-
-            Path targetPath = detectTargetFolder();
-            Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-            Utils.deleteRecursive(lclSftp);
-
-            Path parentPath = targetPath.getParent();
-            Path clientFolder = 
assertHierarchyTargetFolderExists(lclSftp).resolve("client");
-            String dir = Utils.resolveRelativeRemotePath(parentPath, 
clientFolder);
-
-            try (SftpClient sftp = session.createSftpClient()) {
-                sftp.mkdir(dir);
-
-                uploadAndVerifyFile(sftp, clientFolder, dir, 0, 
"emptyFile.txt");
-                uploadAndVerifyFile(sftp, clientFolder, dir, 1000, 
"smallFile.txt");
-                uploadAndVerifyFile(sftp, clientFolder, dir, 
ByteArrayBuffer.MAX_LEN - 1, "bufferMaxLenMinusOneFile.txt");
-                uploadAndVerifyFile(sftp, clientFolder, dir, 
ByteArrayBuffer.MAX_LEN, "bufferMaxLenFile.txt");
-                // were chunking not implemented, these would fail. these 
sizes should invoke our internal chunking mechanism
-                uploadAndVerifyFile(sftp, clientFolder, dir, 
ByteArrayBuffer.MAX_LEN + 1, "bufferMaxLenPlusOneFile.txt");
-                uploadAndVerifyFile(sftp, clientFolder, dir, (int) (1.5 * 
ByteArrayBuffer.MAX_LEN), "1point5BufferMaxLenFile.txt");
-                uploadAndVerifyFile(sftp, clientFolder, dir, (2 * 
ByteArrayBuffer.MAX_LEN) - 1, "2TimesBufferMaxLenMinusOneFile.txt");
-                uploadAndVerifyFile(sftp, clientFolder, dir, 2 * 
ByteArrayBuffer.MAX_LEN, "2TimesBufferMaxLenFile.txt");
-                uploadAndVerifyFile(sftp, clientFolder, dir, (2 * 
ByteArrayBuffer.MAX_LEN) + 1, "2TimesBufferMaxLenPlusOneFile.txt");
-                uploadAndVerifyFile(sftp, clientFolder, dir, 200000, 
"largerFile.txt");
-
-                // test erroneous calls that check for negative values
-                Path invalidPath = clientFolder.resolve(getCurrentTestName() + 
"-invalid");
-                testInvalidParams(sftp, invalidPath, 
Utils.resolveRelativeRemotePath(parentPath, invalidPath));
-
-                // cleanup
-                sftp.rmdir(dir);
-            }
-        }
-    }
-
-    private void testInvalidParams(SftpClient sftp, Path file, String 
filePath) throws Exception {
-        // generate random file and upload it
-        String randomData = randomString(5);
-        byte[] randomBytes = randomData.getBytes(StandardCharsets.UTF_8);
-        try (SftpClient.CloseableHandle handle = sftp.open(filePath, 
EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Create))) {
-            try {
-                sftp.write(handle, -1, randomBytes, 0, 0);
-                fail("should not have been able to write file with invalid 
file offset for " + filePath);
-            } catch (IllegalArgumentException e) {
-                // expected
-            }
-            try {
-                sftp.write(handle, 0, randomBytes, -1, 0);
-                fail("should not have been able to write file with invalid 
source offset for " + filePath);
-            } catch (IllegalArgumentException e) {
-                // expected
-            }
-            try {
-                sftp.write(handle, 0, randomBytes, 0, -1);
-                fail("should not have been able to write file with invalid 
length for " + filePath);
-            } catch (IllegalArgumentException e) {
-                // expected
-            }
-            try {
-                sftp.write(handle, 0, randomBytes, 0, randomBytes.length + 1);
-                fail("should not have been able to write file with length 
bigger than array itself (no offset) for " + filePath);
-            } catch (IllegalArgumentException e) {
-                // expected
-            }
-            try {
-                sftp.write(handle, 0, randomBytes, randomBytes.length, 1);
-                fail("should not have been able to write file with length 
bigger than array itself (with offset) for " + filePath);
-            } catch (IllegalArgumentException e) {
-                // expected
-            }
-        }
-
-        sftp.remove(filePath);
-        assertFalse("File should not be there: " + file.toString(), 
Files.exists(file));
-    }
-
-    private void uploadAndVerifyFile(SftpClient sftp, Path clientFolder, 
String remoteDir, int size, String filename) throws Exception {
-        // generate random file and upload it
-        String remotePath = remoteDir + "/" + filename;
-        String randomData = randomString(size);
-        try (SftpClient.CloseableHandle handle = sftp.open(remotePath, 
EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Create))) {
-            sftp.write(handle, 0, randomData.getBytes(StandardCharsets.UTF_8), 
0, randomData.length());
-        }
-
-        // verify results
-        Path resultPath = clientFolder.resolve(filename);
-        assertTrue("File should exist on disk: " + resultPath, 
Files.exists(resultPath));
-        assertTrue("Mismatched file contents: " + resultPath, 
randomData.equals(readFile(remotePath)));
-
-        // cleanup
-        sftp.remove(remotePath);
-        assertFalse("File should have been removed: " + resultPath, 
Files.exists(resultPath));
-    }
-
-    @Test
-    public void testSftp() throws Exception {
-        String d = getCurrentTestName() + "\n";
-
-        Path targetPath = detectTargetFolder();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Utils.deleteRecursive(lclSftp);
-
-        Path target = 
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
-        String remotePath = 
Utils.resolveRelativeRemotePath(targetPath.getParent(), target);
-
-        final int numIterations = 10;
-        StringBuilder sb = new StringBuilder(d.length() * numIterations * 
numIterations);
-        for (int j = 1; j <= numIterations; j++) {
-            if (sb.length() > 0) {
-                sb.setLength(0);
-            }
-
-            for (int i = 0; i < j; i++) {
-                sb.append(d);
-            }
-
-            sendFile(remotePath, sb.toString());
-            assertFileLength(target, sb.length(), 
TimeUnit.SECONDS.toMillis(5L));
-            Files.delete(target);
-        }
-    }
-
-    @Test
-    public void testReadWriteWithOffset() throws Exception {
-        Path targetPath = detectTargetFolder();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Utils.deleteRecursive(lclSftp);
-
-        Path localPath = 
assertHierarchyTargetFolderExists(lclSftp).resolve("file.txt");
-        String remotePath = 
Utils.resolveRelativeRemotePath(targetPath.getParent(), localPath);
-        String data = getCurrentTestName();
-        String extraData = "@" + getClass().getSimpleName();
-        int appendOffset = -5;
-
-        ChannelSftp c = (ChannelSftp) 
session.openChannel(SftpConstants.SFTP_SUBSYSTEM_NAME);
-        c.connect();
-        try {
-            c.put(new 
ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)), remotePath);
-
-            assertTrue("Remote file not created after initial write: " + 
localPath, Files.exists(localPath));
-            assertEquals("Mismatched data read from " + remotePath, data, 
readFile(remotePath));
-
-            try (OutputStream os = c.put(remotePath, null, ChannelSftp.APPEND, 
appendOffset)) {
-                os.write(extraData.getBytes(StandardCharsets.UTF_8));
-            }
-        } finally {
-            c.disconnect();
-        }
-
-        assertTrue("Remote file not created after data update: " + localPath, 
Files.exists(localPath));
-
-        String expected = data.substring(0, data.length() + appendOffset) + 
extraData;
-        String actual = readFile(remotePath);
-        assertEquals("Mismatched final file data in " + remotePath, expected, 
actual);
-    }
-
-    @Test
-    public void testReadDir() throws Exception {
-        Path cwdPath = 
Paths.get(System.getProperty("user.dir")).toAbsolutePath();
-        Path tgtPath = detectTargetFolder();
-        Collection<String> expNames = OsUtils.isUNIX()
-            ? new LinkedList<>()
-            : new TreeSet<>(String.CASE_INSENSITIVE_ORDER);
-        try (DirectoryStream<Path> ds = Files.newDirectoryStream(tgtPath)) {
-            for (Path p : ds) {
-                String n = Objects.toString(p.getFileName());
-                if (".".equals(n) || "..".equals(n)) {
-                    continue;
-                }
-
-                assertTrue("Failed to accumulate " + n, expNames.add(n));
-            }
-        }
-
-        Path baseDir = cwdPath.relativize(tgtPath);
-        String path = baseDir + "/";
-        path = path.replace('\\', '/');
-
-        ChannelSftp c = (ChannelSftp) 
session.openChannel(SftpConstants.SFTP_SUBSYSTEM_NAME);
-        c.connect();
-        try {
-            Vector<?> res = c.ls(path);
-            for (Object f : res) {
-                outputDebugMessage("LsEntry: %s", f);
-
-                ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) f;
-                String name = entry.getFilename();
-                if (".".equals(name) || "..".equals(name)) {
-                    continue;
-                }
-
-                assertTrue("Entry not found: " + name, expNames.remove(name));
-            }
-
-            assertTrue("Un-listed names: " + expNames, 
GenericUtils.isEmpty(expNames));
-        } finally {
-            c.disconnect();
-        }
-    }
-
-    @Test
-    public void testRename() throws Exception {
-        Path targetPath = detectTargetFolder();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Utils.deleteRecursive(lclSftp);
-
-        Path parentPath = targetPath.getParent();
-        Path clientFolder = 
assertHierarchyTargetFolderExists(lclSftp.resolve("client"));
-        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()) {
-                Path file1 = clientFolder.resolve("file-1.txt");
-                String file1Path = Utils.resolveRelativeRemotePath(parentPath, 
file1);
-                try (OutputStream os = sftp.write(file1Path, 
SftpClient.MIN_WRITE_BUFFER_SIZE)) {
-                    os.write((getCurrentTestName() + 
"\n").getBytes(StandardCharsets.UTF_8));
-                }
-
-                Path file2 = clientFolder.resolve("file-2.txt");
-                String file2Path = Utils.resolveRelativeRemotePath(parentPath, 
file2);
-                Path file3 = clientFolder.resolve("file-3.txt");
-                String file3Path = Utils.resolveRelativeRemotePath(parentPath, 
file3);
-                try {
-                    sftp.rename(file2Path, file3Path);
-                    fail("Unxpected rename success of " + file2Path + " => " + 
file3Path);
-                } catch (org.apache.sshd.common.subsystem.sftp.SftpException 
e) {
-                    assertEquals("Mismatched status for failed rename of " + 
file2Path + " => " + file3Path, SftpConstants.SSH_FX_NO_SUCH_FILE, 
e.getStatus());
-                }
-
-                try (OutputStream os = sftp.write(file2Path, 
SftpClient.MIN_WRITE_BUFFER_SIZE)) {
-                    os.write("h".getBytes(StandardCharsets.UTF_8));
-                }
-
-                try {
-                    sftp.rename(file1Path, file2Path);
-                    fail("Unxpected rename success of " + file1Path + " => " + 
file2Path);
-                } catch (org.apache.sshd.common.subsystem.sftp.SftpException 
e) {
-                    assertEquals("Mismatched status for failed rename of " + 
file1Path + " => " + file2Path, SftpConstants.SSH_FX_FILE_ALREADY_EXISTS, 
e.getStatus());
-                }
-
-                sftp.rename(file1Path, file2Path, 
SftpClient.CopyMode.Overwrite);
-            }
-        }
-    }
-
-    @Test
-    public void testServerExtensionsDeclarations() throws Exception {
-        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()) {
-                Map<String, byte[]> extensions = sftp.getServerExtensions();
-                for (String name : new String[]{
-                    SftpConstants.EXT_NEWLINE, SftpConstants.EXT_VERSIONS,
-                    SftpConstants.EXT_VENDOR_ID, 
SftpConstants.EXT_ACL_SUPPORTED,
-                    SftpConstants.EXT_SUPPORTED, SftpConstants.EXT_SUPPORTED2
-                }) {
-                    assertTrue("Missing extension=" + name, 
extensions.containsKey(name));
-                }
-
-                Map<String, ?> data = ParserUtils.parse(extensions);
-                data.forEach((extName, extValue) -> {
-                    outputDebugMessage("%s: %s", extName, extValue);
-                    if (SftpConstants.EXT_SUPPORTED.equalsIgnoreCase(extName)) 
{
-                        assertSupportedExtensions(extName, ((Supported) 
extValue).extensionNames);
-                    } else if 
(SftpConstants.EXT_SUPPORTED2.equalsIgnoreCase(extName)) {
-                        assertSupportedExtensions(extName, ((Supported2) 
extValue).extensionNames);
-                    } else if 
(SftpConstants.EXT_ACL_SUPPORTED.equalsIgnoreCase(extName)) {
-                        assertSupportedAclCapabilities((AclCapabilities) 
extValue);
-                    } else if 
(SftpConstants.EXT_VERSIONS.equalsIgnoreCase(extName)) {
-                        assertSupportedVersions((Versions) extValue);
-                    } else if 
(SftpConstants.EXT_NEWLINE.equalsIgnoreCase(extName)) {
-                        assertNewlineValue((Newline) extValue);
-                    }
-                });
-
-                for (String extName : extensions.keySet()) {
-                    if (!data.containsKey(extName)) {
-                        outputDebugMessage("No parser for extension=%s", 
extName);
-                    }
-                }
-
-                for (OpenSSHExtension expected : 
AbstractSftpSubsystemHelper.DEFAULT_OPEN_SSH_EXTENSIONS) {
-                    String name = expected.getName();
-                    Object value = data.get(name);
-                    assertNotNull("OpenSSH extension not declared: " + name, 
value);
-
-                    OpenSSHExtension actual = (OpenSSHExtension) value;
-                    assertEquals("Mismatched version for OpenSSH extension=" + 
name, expected.getVersion(), actual.getVersion());
-                }
-
-                for (BuiltinSftpClientExtensions type : 
BuiltinSftpClientExtensions.VALUES) {
-                    String extensionName = type.getName();
-                    boolean isOpenSSHExtension = 
extensionName.endsWith("@openssh.com");
-                    SftpClientExtension instance = 
sftp.getExtension(extensionName);
-
-                    assertNotNull("Extension not implemented:" + 
extensionName, instance);
-                    assertEquals("Mismatched instance name", extensionName, 
instance.getName());
-
-                    if (instance.isSupported()) {
-                        if (isOpenSSHExtension) {
-                            assertTrue("Unlisted default OpenSSH extension: " 
+ extensionName,
-                                
AbstractSftpSubsystemHelper.DEFAULT_OPEN_SSH_EXTENSIONS_NAMES.contains(extensionName));
-                        }
-                    } else {
-                        assertTrue("Unsupported non-OpenSSH extension: " + 
extensionName, isOpenSSHExtension);
-                        assertFalse("Unsupported default OpenSSH extension: " 
+ extensionName,
-                            
AbstractSftpSubsystemHelper.DEFAULT_OPEN_SSH_EXTENSIONS_NAMES.contains(extensionName));
-                    }
-                }
-            }
-        }
-    }
-
-    private static void assertSupportedExtensions(String extName, 
Collection<String> extensionNames) {
-        assertEquals(extName + "[count]", EXPECTED_EXTENSIONS.size(), 
GenericUtils.size(extensionNames));
-
-        EXPECTED_EXTENSIONS.forEach((name, f) -> {
-            if (!f.isSupported()) {
-                assertFalse(extName + " - unsupported feature reported: " + 
name, extensionNames.contains(name));
-            } else {
-                assertTrue(extName + " - missing " + name, 
extensionNames.contains(name));
-            }
-        });
-    }
-
-    private static void assertSupportedVersions(Versions vers) {
-        List<String> values = vers.getVersions();
-        assertEquals("Mismatched reported versions size: " + values,
-                     1 + SftpSubsystemEnvironment.HIGHER_SFTP_IMPL - 
SftpSubsystemEnvironment.LOWER_SFTP_IMPL,
-                     GenericUtils.size(values));
-        for (int expected = SftpSubsystemEnvironment.LOWER_SFTP_IMPL, index = 
0; expected <= SftpSubsystemEnvironment.HIGHER_SFTP_IMPL; expected++, index++) {
-            String e = Integer.toString(expected);
-            String a = values.get(index);
-            assertEquals("Missing value at index=" + index + ": " + values, e, 
a);
-        }
-    }
-
-    private static void assertNewlineValue(Newline nl) {
-        assertEquals("Mismatched NL value",
-                     BufferUtils.toHex(':', 
IoUtils.EOL.getBytes(StandardCharsets.UTF_8)),
-                     BufferUtils.toHex(':', 
nl.getNewline().getBytes(StandardCharsets.UTF_8)));
-    }
-
-    private static void assertSupportedAclCapabilities(AclCapabilities caps) {
-        Set<Integer> actual = 
AclCapabilities.deconstructAclCapabilities(caps.getCapabilities());
-        assertEquals("Mismatched ACL capabilities count", 
AbstractSftpSubsystemHelper.DEFAULT_ACL_SUPPORTED_MASK.size(), actual.size());
-        assertTrue("Missing capabilities - expected=" + 
AbstractSftpSubsystemHelper.DEFAULT_ACL_SUPPORTED_MASK + ", actual=" + actual,
-                   
actual.containsAll(AbstractSftpSubsystemHelper.DEFAULT_ACL_SUPPORTED_MASK));
-    }
-
-    @Test
-    public void testSftpVersionSelector() throws Exception {
-        final AtomicInteger selected = new AtomicInteger(-1);
-        SftpVersionSelector selector = (session, current, available) -> {
-            int value = GenericUtils.stream(available)
-                    .mapToInt(Integer::intValue)
-                    .filter(v -> v != current)
-                    .max()
-                    .orElseGet(() -> current);
-            selected.set(value);
-            return value;
-        };
-
-        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(selector)) {
-                assertEquals("Mismatched negotiated version", selected.get(), 
sftp.getVersion());
-                testClient(client, sftp);
-            }
-        }
-    }
-
-    @Test   // see SSHD-621
-    public void testServerDoesNotSupportSftp() throws Exception {
-        List<NamedFactory<Command>> factories = sshd.getSubsystemFactories();
-        assertEquals("Mismatched subsystem factories count", 1, 
GenericUtils.size(factories));
-
-        sshd.setSubsystemFactories(null);
-        try (ClientSession session = client.connect(getCurrentTestName(), 
TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
-            session.addPasswordIdentity(getCurrentTestName());
-            session.auth().verify(5L, TimeUnit.SECONDS);
-
-            PropertyResolverUtils.updateProperty(session, 
SftpClient.SFTP_CHANNEL_OPEN_TIMEOUT, TimeUnit.SECONDS.toMillis(4L));
-            try (SftpClient sftp = session.createSftpClient()) {
-                fail("Unexpected SFTP client creation success");
-            } catch (SocketTimeoutException | EOFException | 
WindowClosedException e) {
-                // expected - ignored
-            } finally {
-                PropertyResolverUtils.updateProperty(session, 
SftpClient.SFTP_CHANNEL_OPEN_TIMEOUT, SftpClient.DEFAULT_CHANNEL_OPEN_TIMEOUT);
-            }
-        } finally {
-            sshd.setSubsystemFactories(factories);
-        }
-    }
-
-    private void testClient(FactoryManager manager, SftpClient sftp) throws 
Exception {
-        Path targetPath = detectTargetFolder();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Utils.deleteRecursive(lclSftp);
-
-        Path parentPath = targetPath.getParent();
-        Path clientFolder = 
assertHierarchyTargetFolderExists(lclSftp).resolve("client");
-        String dir = Utils.resolveRelativeRemotePath(parentPath, clientFolder);
-        sftp.mkdir(dir);
-
-        String file = dir + "/" + getCurrentTestName() + "-file.txt";
-        try (SftpClient.CloseableHandle h = sftp.open(file, 
EnumSet.of(SftpClient.OpenMode.Write, SftpClient.OpenMode.Create))) {
-            byte[] d = "0123456789\n".getBytes(StandardCharsets.UTF_8);
-            sftp.write(h, 0, d, 0, d.length);
-            sftp.write(h, d.length, d, 0, d.length);
-
-            SftpClient.Attributes attrs = sftp.stat(h);
-            assertNotNull("No handle attributes", attrs);
-        }
-
-        try (SftpClient.CloseableHandle h = sftp.openDir(dir)) {
-            List<SftpClient.DirEntry> dirEntries = new ArrayList<>();
-            boolean dotFiltered = false;
-            boolean dotdotFiltered = false;
-            for (SftpClient.DirEntry entry : sftp.listDir(h)) {
-                String name = entry.getFilename();
-                outputDebugMessage("readDir(%s) initial file: %s", dir, name);
-                if (".".equals(name) && (!dotFiltered)) {
-                    dotFiltered = true;
-                } else if ("..".equals(name) && (!dotdotFiltered)) {
-                    dotdotFiltered = true;
-                } else {
-                    dirEntries.add(entry);
-                }
-            }
-
-            assertTrue("Dot entry not listed", dotFiltered);
-            assertTrue("Dot-dot entry not listed", dotdotFiltered);
-            assertEquals("Mismatched number of listed entries", 1, 
dirEntries.size());
-            assertNull("Unexpected extra entry read after listing ended", 
sftp.readDir(h));
-        }
-
-        sftp.remove(file);
-
-        final int sizeFactor = Short.SIZE;
-        byte[] workBuf = new byte[IoUtils.DEFAULT_COPY_SIZE * Short.SIZE];
-        Factory<? extends Random> factory = manager.getRandomFactory();
-        Random random = factory.create();
-        random.fill(workBuf);
-
-        try (OutputStream os = sftp.write(file)) {
-            os.write(workBuf);
-        }
-
-        // force several internal read cycles to satisfy the full read
-        try (InputStream is = sftp.read(file, workBuf.length / sizeFactor)) {
-            int readLen = is.read(workBuf);
-            assertEquals("Mismatched read data length", workBuf.length, 
readLen);
-
-            int i = is.read();
-            assertEquals("Unexpected read past EOF", -1, i);
-        }
-
-        SftpClient.Attributes attributes = sftp.stat(file);
-        assertTrue("Test file not detected as regular", 
attributes.isRegularFile());
-
-        attributes = sftp.stat(dir);
-        assertTrue("Test directory not reported as such", 
attributes.isDirectory());
-
-        int nb = 0;
-        boolean dotFiltered = false;
-        boolean dotdotFiltered = false;
-        for (SftpClient.DirEntry entry : sftp.readDir(dir)) {
-            assertNotNull("Unexpected null entry", entry);
-            String name = entry.getFilename();
-            outputDebugMessage("readDir(%s) overwritten file: %s", dir, name);
-
-            if (".".equals(name) && (!dotFiltered)) {
-                dotFiltered = true;
-            } else if ("..".equals(name) && (!dotdotFiltered)) {
-                dotdotFiltered = true;
-            } else {
-                nb++;
-            }
-        }
-        assertTrue("Dot entry not read", dotFiltered);
-        assertTrue("Dot-dot entry not read", dotdotFiltered);
-        assertEquals("Mismatched read dir entries", 1, nb);
-        sftp.remove(file);
-        sftp.rmdir(dir);
-    }
-
-    @Test
-    public void testCreateSymbolicLink() throws Exception {
-        // Do not execute on windows as the file system does not support 
symlinks
-        Assume.assumeTrue("Skip non-Unix O/S", OsUtils.isUNIX());
-        List<NamedFactory<Command>> factories = sshd.getSubsystemFactories();
-        assertEquals("Mismatched subsystem factories count", 1, 
GenericUtils.size(factories));
-
-        NamedFactory<Command> f = factories.get(0);
-        assertObjectInstanceOf("Not an SFTP subsystem factory", 
SftpSubsystemFactory.class, f);
-
-        SftpSubsystemFactory factory = (SftpSubsystemFactory) f;
-        final AtomicReference<LinkData> linkDataHolder = new 
AtomicReference<>();
-        SftpEventListener listener = new AbstractSftpEventListenerAdapter() {
-            @Override
-            public void linking(ServerSession session, Path src, Path target, 
boolean symLink) {
-                assertNull("Multiple linking calls", 
linkDataHolder.getAndSet(new LinkData(src, target, symLink)));
-            }
-
-            @Override
-            public void linked(ServerSession session, Path src, Path target, 
boolean symLink, Throwable thrown) {
-                LinkData data = linkDataHolder.get();
-                assertNotNull("No previous linking call", data);
-                assertSame("Mismatched source", data.getSource(), src);
-                assertSame("Mismatched target", data.getTarget(), target);
-                assertEquals("Mismatched link type", data.isSymLink(), 
symLink);
-                assertNull("Unexpected failure", thrown);
-            }
-        };
-
-        Path targetPath = detectTargetFolder();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName(), 
getCurrentTestName());
-        Utils.deleteRecursive(lclSftp);
-
-        /*
-         * NOTE !!! according to Jsch documentation
-         * (see 
http://epaul.github.io/jsch-documentation/simple.javadoc/com/jcraft/jsch/ChannelSftp.html#current-directory)
-         *
-         *
-         *         This sftp client has the concept of a current local 
directory and
-         *         a current remote directory. These are not inherent to the 
protocol,
-         *      but are used implicitly for all path-based commands sent to 
the server
-         *      for the remote directory) or accessing the local file system 
(for the local directory).
-         *
-         *  Therefore we are using "absolute" remote files for this test
-         */
-        Path parentPath = targetPath.getParent();
-        Path sourcePath = 
assertHierarchyTargetFolderExists(lclSftp).resolve("src.txt");
-        String remSrcPath = "/" + Utils.resolveRelativeRemotePath(parentPath, 
sourcePath);
-
-        factory.addSftpEventListener(listener);
-        try {
-            String data = getCurrentTestName();
-            ChannelSftp c = (ChannelSftp) 
session.openChannel(SftpConstants.SFTP_SUBSYSTEM_NAME);
-            c.connect();
-
-            try {
-                try (InputStream dataStream = new 
ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8))) {
-                    c.put(dataStream, remSrcPath);
-                }
-                assertTrue("Source file not created: " + sourcePath, 
Files.exists(sourcePath));
-                assertEquals("Mismatched stored data in " + remSrcPath, data, 
readFile(remSrcPath));
-
-                Path linkPath = lclSftp.resolve("link-" + 
sourcePath.getFileName());
-                String remLinkPath = "/" + 
Utils.resolveRelativeRemotePath(parentPath, linkPath);
-                LinkOption[] options = IoUtils.getLinkOptions(false);
-                if (Files.exists(linkPath, options)) {
-                    Files.delete(linkPath);
-                }
-                assertFalse("Target link exists before linking: " + linkPath, 
Files.exists(linkPath, options));
-
-                outputDebugMessage("Symlink %s => %s", remLinkPath, 
remSrcPath);
-                c.symlink(remSrcPath, remLinkPath);
-
-                assertTrue("Symlink not created: " + linkPath, 
Files.exists(linkPath, options));
-                assertEquals("Mismatched link data in " + remLinkPath, data, 
readFile(remLinkPath));
-
-                String str1 = c.readlink(remLinkPath);
-                String str2 = c.realpath(remSrcPath);
-                assertEquals("Mismatched link vs. real path", str1, str2);
-            } finally {
-                c.disconnect();
-            }
-        } finally {
-            factory.removeSftpEventListener(listener);
-        }
-
-        assertNotNull("No symlink signalled", linkDataHolder.getAndSet(null));
-    }
-
-    @Test   // see SSHD-697
-    public void testFileChannel() throws IOException {
-        Path targetPath = detectTargetFolder();
-        Path lclSftp = Utils.resolve(targetPath, 
SftpConstants.SFTP_SUBSYSTEM_NAME, getClass().getSimpleName());
-        Path lclFile = lclSftp.resolve(getCurrentTestName() + ".txt");
-        Files.deleteIfExists(lclFile);
-        byte[] expected = (getClass().getName() + "#" + getCurrentTestName() + 
"(" + new Date() + ")").getBytes(StandardCharsets.UTF_8);
-
-        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()) {
-                Path parentPath = targetPath.getParent();
-                String remFilePath = 
Utils.resolveRelativeRemotePath(parentPath, lclFile);
-
-                try (FileChannel fc = sftp.openRemotePathChannel(remFilePath, 
EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.READ, 
StandardOpenOption.WRITE))) {
-                    int writeLen = fc.write(ByteBuffer.wrap(expected));
-                    assertEquals("Mismatched written length", expected.length, 
writeLen);
-
-                    FileChannel fcPos = fc.position(0L);
-                    assertSame("Mismatched positioned file channel", fc, 
fcPos);
-
-                    byte[] actual = new byte[expected.length];
-                    int readLen = fc.read(ByteBuffer.wrap(actual));
-                    assertEquals("Mismatched read len", writeLen, readLen);
-                    assertArrayEquals("Mismatched read data", expected, 
actual);
-                }
-            }
-        }
-
-        byte[] actual = Files.readAllBytes(lclFile);
-        assertArrayEquals("Mismatched persisted data", expected, actual);
-    }
-
-    protected String readFile(String path) throws Exception {
-        ChannelSftp c = (ChannelSftp) 
session.openChannel(SftpConstants.SFTP_SUBSYSTEM_NAME);
-        c.connect();
-
-        try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
-             InputStream is = c.get(path)) {
-            byte[] buffer = new byte[256];
-            for (int count = is.read(buffer); count != -1; count = 
is.read(buffer)) {
-                bos.write(buffer, 0, count);
-            }
-
-            return bos.toString();
-        } finally {
-            c.disconnect();
-        }
-    }
-
-    protected void sendFile(String path, String data) throws Exception {
-        ChannelSftp c = (ChannelSftp) 
session.openChannel(SftpConstants.SFTP_SUBSYSTEM_NAME);
-        c.connect();
-        try {
-            c.put(new 
ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8)), path);
-        } finally {
-            c.disconnect();
-        }
-    }
-
-    private String randomString(int size) {
-        StringBuilder sb = new StringBuilder(size);
-        for (int i = 0; i < size; i++) {
-            sb.append((char) ((i % 10) + '0'));
-        }
-        return sb.toString();
-    }
-
-    static class LinkData {
-        private final Path source;
-        private final Path target;
-        private final boolean symLink;
-
-        LinkData(Path src, Path target, boolean symLink) {
-            this.source = Objects.requireNonNull(src, "No source");
-            this.target = Objects.requireNonNull(target, "No target");
-            this.symLink = symLink;
-        }
-
-        public Path getSource() {
-            return source;
-        }
-
-        public Path getTarget() {
-            return target;
-        }
-
-        public boolean isSymLink() {
-            return symLink;
-        }
-
-        @Override
-        public String toString() {
-            return (isSymLink() ? "Symbolic" : "Hard") + " " + getSource() + " 
=> " + getTarget();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/251db9b9/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelectorTest.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelectorTest.java
 
b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelectorTest.java
deleted file mode 100644
index afc1944..0000000
--- 
a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelectorTest.java
+++ /dev/null
@@ -1,134 +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;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Random;
-
-import org.apache.sshd.client.session.ClientSession;
-import org.apache.sshd.server.subsystem.sftp.SftpSubsystemEnvironment;
-import org.apache.sshd.util.test.BaseTestSupport;
-import org.apache.sshd.util.test.NoIoTestCase;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runners.MethodSorters;
-import org.mockito.Mockito;
-
-/**
- * @author <a href="mailto:d...@mina.apache.org";>Apache MINA SSHD Project</a>
- */
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-@Category({ NoIoTestCase.class })
-public class SftpVersionSelectorTest extends BaseTestSupport {
-    public SftpVersionSelectorTest() {
-        super();
-    }
-
-    @Test
-    public void testCurrentVersionSelector() {
-        List<Integer> available = new ArrayList<>();
-        Random rnd = new Random(System.nanoTime());
-        ClientSession session = Mockito.mock(ClientSession.class);
-        for (int expected = SftpSubsystemEnvironment.LOWER_SFTP_IMPL; expected 
<= SftpSubsystemEnvironment.HIGHER_SFTP_IMPL; expected++) {
-            assertEquals("Mismatched directly selected for available=" + 
available, expected, SftpVersionSelector.CURRENT.selectVersion(session, 
expected, available));
-            available.add(expected);
-        }
-
-        for (int expected = SftpSubsystemEnvironment.LOWER_SFTP_IMPL; expected 
<= SftpSubsystemEnvironment.HIGHER_SFTP_IMPL; expected++) {
-            for (int index = 0; index < available.size(); index++) {
-                Collections.shuffle(available, rnd);
-                assertEquals("Mismatched suffling selected for current=" + 
expected + ", available=" + available,
-                        expected, 
SftpVersionSelector.CURRENT.selectVersion(session, expected, available));
-            }
-        }
-    }
-
-    @Test
-    public void testFixedVersionSelector() {
-        final int fixedValue = 7365;
-        
testVersionSelector(SftpVersionSelector.fixedVersionSelector(fixedValue), 
fixedValue);
-    }
-
-    @Test
-    public void testPreferredVersionSelector() {
-        List<Integer> available = new ArrayList<>();
-        for (int version = SftpSubsystemEnvironment.LOWER_SFTP_IMPL; version 
<= SftpSubsystemEnvironment.HIGHER_SFTP_IMPL; version++) {
-            available.add(version);
-        }
-
-        List<Integer> preferred = new ArrayList<>(available);
-        List<Integer> unavailable = Arrays.asList(7365, 3777347);
-        Random rnd = new Random(System.nanoTime());
-        ClientSession session = Mockito.mock(ClientSession.class);
-        for (int index = 0; index < preferred.size(); index++) {
-            Collections.shuffle(preferred, rnd);
-            SftpVersionSelector selector = 
SftpVersionSelector.preferredVersionSelector(preferred);
-            int expected = preferred.get(0);
-
-            for (int current = SftpSubsystemEnvironment.LOWER_SFTP_IMPL; 
current <= SftpSubsystemEnvironment.HIGHER_SFTP_IMPL; current++) {
-                assertEquals("Mismatched selected for current= " + current + 
", available=" + available + ", preferred=" + preferred,
-                             expected, selector.selectVersion(session, 
current, available));
-
-                try {
-                    Collections.shuffle(unavailable, rnd);
-                    int version = unavailable.get(0);
-                    int actual = selector.selectVersion(session, version, 
unavailable);
-                    fail("Unexpected selected version (" + actual + ")"
-                            + " for current= " + version
-                            + ", available=" + unavailable
-                            + ", preferred=" + preferred);
-                } catch (IllegalStateException e) {
-                    // expected
-                }
-            }
-        }
-    }
-
-    @Test
-    public void testMaximumVersionSelector() {
-        testVersionSelector(SftpVersionSelector.MAXIMUM, 
SftpSubsystemEnvironment.HIGHER_SFTP_IMPL);
-    }
-
-    @Test
-    public void testMinimumVersionSelector() {
-        testVersionSelector(SftpVersionSelector.MINIMUM, 
SftpSubsystemEnvironment.LOWER_SFTP_IMPL);
-    }
-
-    private static void testVersionSelector(SftpVersionSelector selector, int 
expected) {
-        List<Integer> available = new ArrayList<>();
-        for (int version = SftpSubsystemEnvironment.LOWER_SFTP_IMPL; version 
<= SftpSubsystemEnvironment.HIGHER_SFTP_IMPL; version++) {
-            available.add(version);
-        }
-
-        Random rnd = new Random(System.nanoTime());
-        ClientSession session = Mockito.mock(ClientSession.class);
-        for (int current = SftpSubsystemEnvironment.LOWER_SFTP_IMPL; current 
<= SftpSubsystemEnvironment.HIGHER_SFTP_IMPL; current++) {
-            for (int index = 0; index < available.size(); index++) {
-                assertEquals("Mismatched selection for current=" + current + 
", available=" + available,
-                        expected, selector.selectVersion(session, current, 
available));
-                Collections.shuffle(available, rnd);
-            }
-        }
-    }
-}

Reply via email to