http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
----------------------------------------------------------------------
diff --git 
a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
 
b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
index 7426fec..3805b29 100644
--- 
a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
+++ 
b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
@@ -18,8 +18,6 @@
  */
 package org.apache.sshd.server.subsystem.sftp;
 
-import static org.apache.sshd.common.subsystem.sftp.SftpConstants.*;
-
 import java.io.EOFException;
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -28,12 +26,8 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.nio.channels.OverlappingFileLockException;
 import java.nio.file.AccessDeniedException;
 import java.nio.file.CopyOption;
-import java.nio.file.DirectoryNotEmptyException;
-import java.nio.file.DirectoryStream;
 import java.nio.file.FileAlreadyExistsException;
 import java.nio.file.FileStore;
 import java.nio.file.FileSystem;
@@ -42,17 +36,10 @@ import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.InvalidPathException;
 import java.nio.file.LinkOption;
-import java.nio.file.NoSuchFileException;
 import java.nio.file.NotDirectoryException;
-import java.nio.file.OpenOption;
 import java.nio.file.Path;
 import java.nio.file.StandardCopyOption;
 import java.nio.file.StandardOpenOption;
-import java.nio.file.attribute.AclEntry;
-import java.nio.file.attribute.AclEntryFlag;
-import java.nio.file.attribute.AclEntryPermission;
-import java.nio.file.attribute.AclEntryType;
-import java.nio.file.attribute.FileAttribute;
 import java.nio.file.attribute.FileTime;
 import java.nio.file.attribute.GroupPrincipal;
 import java.nio.file.attribute.PosixFilePermission;
@@ -62,14 +49,11 @@ import java.nio.file.attribute.UserPrincipalLookupService;
 import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Calendar;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.EnumSet;
-import java.util.GregorianCalendar;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -78,7 +62,6 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
 
 import org.apache.sshd.common.Factory;
 import org.apache.sshd.common.FactoryManager;
@@ -112,6 +95,81 @@ import org.apache.sshd.server.ExitCallback;
 import org.apache.sshd.server.SessionAware;
 import org.apache.sshd.server.session.ServerSession;
 
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_APPEND_DATA;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_READ_ATTRIBUTES;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_READ_DATA;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_WRITE_ATTRIBUTES;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_WRITE_DATA;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.EXT_NEWLINE;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.EXT_SUPPORTED;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.EXT_SUPPORTED2;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.EXT_VENDOR_ID;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.EXT_VERSIONS;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V3;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V4;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V5;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SFTP_V6;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FILEXFER_ATTR_ACCESSTIME;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FILEXFER_ATTR_ALL;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FILEXFER_ATTR_BITS;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FILEXFER_ATTR_CREATETIME;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FILEXFER_ATTR_MODIFYTIME;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FILEXFER_ATTR_OWNERGROUP;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FILEXFER_ATTR_PERMISSIONS;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FILEXFER_ATTR_SIZE;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_ACCESS_DISPOSITION;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_APPEND;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_APPEND_DATA;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_APPEND_DATA_ATOMIC;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_CREAT;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_CREATE_NEW;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_CREATE_TRUNCATE;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_EXCL;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_OPEN_EXISTING;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_OPEN_OR_CREATE;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_READ;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_TRUNC;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_TRUNCATE_EXISTING;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_WRITE;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_ATTRS;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_BLOCK;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_CLOSE;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_DATA;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_EXTENDED;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_EXTENDED_REPLY;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_FSETSTAT;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_FSTAT;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_HANDLE;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_INIT;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_LINK;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_LSTAT;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_MKDIR;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_NAME;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_OPEN;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_OPENDIR;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_READ;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_READDIR;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_READLINK;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_REALPATH;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_REALPATH_STAT_ALWAYS;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_REALPATH_STAT_IF;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_REMOVE;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_RENAME;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_RENAME_ATOMIC;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_RENAME_OVERWRITE;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_RMDIR;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_SETSTAT;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_STAT;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_STATUS;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_SYMLINK;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_UNBLOCK;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_VERSION;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXP_WRITE;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FX_FAILURE;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FX_NO_MATCHING_BYTE_RANGE_LOCK;
+import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FX_OK;
+import static 
org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FX_OP_UNSUPPORTED;
+
 /**
  * SFTP subsystem
  *
@@ -123,27 +181,29 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
      * Properties key for the maximum of available open handles per session.
      */
     public static final String MAX_OPEN_HANDLES_PER_SESSION = 
"max-open-handles-per-session";
-        public static final int DEFAULT_MAX_OPEN_HANDLES = Integer.MAX_VALUE;
+    public static final int DEFAULT_MAX_OPEN_HANDLES = Integer.MAX_VALUE;
 
     /**
      * Size in bytes of the opaque handle value
+     *
      * @see #DEFAULT_FILE_HANDLE_SIZE
      */
     public static final String FILE_HANDLE_SIZE = "sftp-handle-size";
-        public static final int MIN_FILE_HANDLE_SIZE = 4;  // ~uint32
-        public static final int DEFAULT_FILE_HANDLE_SIZE = 16;
-        public static final int MAX_FILE_HANDLE_SIZE = 64;  // ~sha512 
+    public static final int MIN_FILE_HANDLE_SIZE = 4;  // ~uint32
+    public static final int DEFAULT_FILE_HANDLE_SIZE = 16;
+    public static final int MAX_FILE_HANDLE_SIZE = 64;  // ~sha512
 
     /**
      * Max. rounds to attempt to create a unique file handle - if all handles
      * already in use after these many rounds, then an exception is thrown
-     * @see #generateFileHandle(Path) 
+     *
+     * @see #generateFileHandle(Path)
      * @see #DEFAULT_FILE_HANDLE_ROUNDS
      */
     public static final String MAX_FILE_HANDLE_RAND_ROUNDS = 
"sftp-handle-rand-max-rounds";
-        public static final int MIN_FILE_HANDLE_ROUNDS = 1;
-        public static final int DEFAULT_FILE_HANDLE_ROUNDS = 
MIN_FILE_HANDLE_SIZE;
-        public static final int MAX_FILE_HANDLE_ROUNDS = MAX_FILE_HANDLE_SIZE;
+    public static final int MIN_FILE_HANDLE_ROUNDS = 1;
+    public static final int DEFAULT_FILE_HANDLE_ROUNDS = MIN_FILE_HANDLE_SIZE;
+    public static final int MAX_FILE_HANDLE_ROUNDS = MAX_FILE_HANDLE_SIZE;
 
     /**
      * Force the use of a given sftp version
@@ -153,14 +213,15 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     public static final int LOWER_SFTP_IMPL = SFTP_V3; // Working 
implementation from v3
     public static final int HIGHER_SFTP_IMPL = SFTP_V6; //  .. up to
     public static final String ALL_SFTP_IMPL;
-    
+
     /**
      * Force the use of a max. packet length - especially for {@link 
#doReadDir(Buffer, int)}
+     *
      * @see #DEFAULT_MAX_PACKET_LENGTH
      */
     public static final String MAX_PACKET_LENGTH_PROP = 
"sftp-max-packet-length";
-        public static final int  DEFAULT_MAX_PACKET_LENGTH = 1024 * 16;
-   
+    public static final int DEFAULT_MAX_PACKET_LENGTH = 1024 * 16;
+
     /**
      * Allows controlling reports of which client extensions are supported
      * (and reported via "support" and "support2" server
@@ -168,52 +229,74 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
      * overriding the {@link #executeExtendedCommand(Buffer, int, String)}
      * command accordingly. If empty string is set then no server extensions
      * are reported
+     *
      * @see #DEFAULT_SUPPORTED_CLIENT_EXTENSIONS
      */
     public static final String CLIENT_EXTENSIONS_PROP = 
"sftp-client-extensions";
-        /**
-         * The default reported supported client extensions
-         */
-        public static final Set<String> DEFAULT_SUPPORTED_CLIENT_EXTENSIONS =
-                // TODO text-seek - see 
http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-13.txt
-                // TODO home-directory - see 
http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt
-                Collections.unmodifiableSet(
-                        GenericUtils.asSortedSet(String.CASE_INSENSITIVE_ORDER,
-                                Arrays.asList(
-                                        SftpConstants.EXT_VERSELECT,
-                                        SftpConstants.EXT_COPYFILE,
-                                        SftpConstants.EXT_MD5HASH,
-                                        SftpConstants.EXT_MD5HASH_HANDLE,
-                                        SftpConstants.EXT_CHKFILE_HANDLE,
-                                        SftpConstants.EXT_CHKFILE_NAME,
-                                        SftpConstants.EXT_COPYDATA,
-                                        SftpConstants.EXT_SPACE_AVAILABLE
-                                )));
+    /**
+     * The default reported supported client extensions
+     */
+    public static final Set<String> DEFAULT_SUPPORTED_CLIENT_EXTENSIONS =
+            // TODO text-seek - see 
http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-13.txt
+            // TODO home-directory - see 
http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt
+            Collections.unmodifiableSet(
+                    GenericUtils.asSortedSet(String.CASE_INSENSITIVE_ORDER,
+                            Arrays.asList(
+                                    SftpConstants.EXT_VERSION_SELECT,
+                                    SftpConstants.EXT_COPY_FILE,
+                                    SftpConstants.EXT_MD5_HASH,
+                                    SftpConstants.EXT_MD5_HASH_HANDLE,
+                                    SftpConstants.EXT_CHECK_FILE_HANDLE,
+                                    SftpConstants.EXT_CHECK_FILE_NAME,
+                                    SftpConstants.EXT_COPY_DATA,
+                                    SftpConstants.EXT_SPACE_AVAILABLE
+                            )));
 
     /**
      * Comma-separated list of which {@code OpenSSH} extensions are reported 
and
      * what version is reported for each - format: {@code name=version}. If 
empty
-     * value set, then no such extensions are reported. Otherwise, the 
-     * {@link DEFAULT_OPEN_SSH_EXTENSIONS} are used
+     * value set, then no such extensions are reported. Otherwise, the
+     * {@link #DEFAULT_OPEN_SSH_EXTENSIONS} are used
      */
     public static final String OPENSSH_EXTENSIONS_PROP = 
"sftp-openssh-extensions";
-        public static final List<OpenSSHExtension> DEFAULT_OPEN_SSH_EXTENSIONS 
=
-                Collections.unmodifiableList(
-                        Arrays.asList(
-                                    new 
OpenSSHExtension(FsyncExtensionParser.NAME, "1")
-                                ));
-
-        public static final List<String> DEFAULT_OPEN_SSH_EXTENSIONS_NAMES =
-                Collections.unmodifiableList(new 
ArrayList<String>(DEFAULT_OPEN_SSH_EXTENSIONS.size()) {
-                        private static final long serialVersionUID = 1L;    // 
we're not serializing it
-                        
-                        {
-                            for (OpenSSHExtension ext : 
DEFAULT_OPEN_SSH_EXTENSIONS) {
-                                add(ext.getName());
-                            }
-                        }
-                    
-                });
+    public static final List<OpenSSHExtension> DEFAULT_OPEN_SSH_EXTENSIONS =
+            Collections.unmodifiableList(
+                    Arrays.asList(
+                            new OpenSSHExtension(FsyncExtensionParser.NAME, 
"1")
+                    ));
+
+    public static final List<String> DEFAULT_OPEN_SSH_EXTENSIONS_NAMES =
+            Collections.unmodifiableList(new 
ArrayList<String>(DEFAULT_OPEN_SSH_EXTENSIONS.size()) {
+                private static final long serialVersionUID = 1L;    // we're 
not serializing it
+
+                {
+                    for (OpenSSHExtension ext : DEFAULT_OPEN_SSH_EXTENSIONS) {
+                        add(ext.getName());
+                    }
+                }
+
+            });
+
+    public static final List<String> DEFAULT_UNIX_VIEW = 
Collections.singletonList("unix:*");
+
+    /**
+     * A {@link Map} of {@link FileInfoExtractor}s to be used to complete
+     * attributes that are deemed important enough to warrant an extra
+     * effort if not accessible via the file system attributes views
+     */
+    public static final Map<String, FileInfoExtractor<?>> FILEATTRS_RESOLVERS =
+            Collections.unmodifiableMap(new TreeMap<String, 
FileInfoExtractor<?>>(String.CASE_INSENSITIVE_ORDER) {
+                private static final long serialVersionUID = 1L;    // we're 
not serializing it
+
+                {
+                    put("isRegularFile", FileInfoExtractor.ISREG);
+                    put("isDirectory", FileInfoExtractor.ISDIR);
+                    put("isSymbolicLink", FileInfoExtractor.ISSYMLINK);
+                    put("permissions", FileInfoExtractor.PERMISSIONS);
+                    put("size", FileInfoExtractor.SIZE);
+                    put("lastModifiedTime", FileInfoExtractor.LASTMODIFIED);
+                }
+            });
 
     static {
         StringBuilder sb = new StringBuilder(2 * (1 + (HIGHER_SFTP_IMPL - 
LOWER_SFTP_IMPL)));
@@ -237,10 +320,10 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     protected ServerSession session;
     protected boolean closed;
     protected ExecutorService executors;
-       protected boolean shutdownExecutor;
-       protected Future<?> pendingFuture;
-       protected byte[] workBuf = new byte[Math.max(DEFAULT_FILE_HANDLE_SIZE, 
Integer.SIZE / Byte.SIZE)]; // TODO in JDK-8 use Integer.BYTES
-       protected FileSystem fileSystem = FileSystems.getDefault();
+    protected boolean shutdownExecutor;
+    protected Future<?> pendingFuture;
+    protected byte[] workBuf = new byte[Math.max(DEFAULT_FILE_HANDLE_SIZE, 
Integer.SIZE / Byte.SIZE)]; // TODO in JDK-8 use Integer.BYTES
+    protected FileSystem fileSystem = FileSystems.getDefault();
     protected Path defaultDir = 
fileSystem.getPath(System.getProperty("user.dir"));
     protected long requestsCount;
     protected int version;
@@ -249,237 +332,6 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
 
     protected final UnsupportedAttributePolicy unsupportedAttributePolicy;
 
-    protected static abstract class Handle implements java.io.Closeable {
-        private Path file;
-
-        public Handle(Path file) {
-            this.file = file;
-        }
-
-        public Path getFile() {
-            return file;
-        }
-
-        @Override
-        public void close() throws IOException {
-            // ignored
-        }
-
-        @Override
-        public String toString() {
-            return Objects.toString(getFile());
-        }
-    }
-
-    protected static class InvalidHandleException extends IOException {
-        private static final long serialVersionUID = -1686077114375131889L;
-
-        public InvalidHandleException(String handle, Handle h, Class<? extends 
Handle> expected) {
-            super(handle + "[" + h + "] is not a " + expected.getSimpleName());
-        }
-    }
-
-    protected static class DirectoryHandle extends Handle implements 
Iterator<Path> {
-        private boolean done, sendDotDot, sendDot=true;
-        // the directory should be read once at "open directory"
-        private DirectoryStream<Path> ds;
-        private Iterator<Path> fileList;
-
-        public DirectoryHandle(Path file) throws IOException {
-            super(file);
-            ds = Files.newDirectoryStream(file);
-            
-            Path parent = file.getParent();
-            sendDotDot = (parent != null);  // if no parent then no need to 
send ".."
-            fileList = ds.iterator();
-        }
-
-        public boolean isDone() {
-            return done;
-        }
-
-        public void markDone() {
-            this.done = true;
-            // allow the garbage collector to do the job
-            this.fileList = null;
-        }
-
-        public boolean isSendDot() {
-            return sendDot;
-        }
-        
-        public void markDotSent() {
-            sendDot = false;
-        }
-
-        public boolean isSendDotDot() {
-            return sendDotDot;
-        }
-        
-        public void markDotDotSent() {
-            sendDotDot = false;
-        }
-
-        @Override
-        public boolean hasNext() {
-            return fileList.hasNext();
-        }
-
-        @Override
-        public Path next() {
-            return fileList.next();
-        }
-
-        @Override
-        public void remove() {
-            throw new UnsupportedOperationException("Not allowed to remove " + 
toString());
-        }
-
-        @Override
-        public void close() throws IOException {
-            markDone(); // just making sure
-            ds.close();
-        }
-    }
-
-    protected class FileHandle extends Handle {
-        private final int access;
-        private final FileChannel fileChannel;
-        private long pos;
-        private final List<FileLock> locks = new ArrayList<>();
-
-        public FileHandle(Path file, int flags, int access, Map<String, 
Object> attrs) throws IOException {
-            super(file);
-            this.access = access;
-
-            Set<OpenOption> options = new HashSet<>();
-            if (((access & ACE4_READ_DATA) != 0) || ((access & 
ACE4_READ_ATTRIBUTES) != 0)) {
-                options.add(StandardOpenOption.READ);
-            }
-            if (((access & ACE4_WRITE_DATA) != 0) || ((access & 
ACE4_WRITE_ATTRIBUTES) != 0)) {
-                options.add(StandardOpenOption.WRITE);
-            }
-            switch (flags & SSH_FXF_ACCESS_DISPOSITION) {
-                case SSH_FXF_CREATE_NEW:
-                    options.add(StandardOpenOption.CREATE_NEW);
-                    break;
-                case SSH_FXF_CREATE_TRUNCATE:
-                    options.add(StandardOpenOption.CREATE);
-                    options.add(StandardOpenOption.TRUNCATE_EXISTING);
-                    break;
-                case SSH_FXF_OPEN_EXISTING:
-                    break;
-                case SSH_FXF_OPEN_OR_CREATE:
-                    options.add(StandardOpenOption.CREATE);
-                    break;
-                case SSH_FXF_TRUNCATE_EXISTING:
-                    options.add(StandardOpenOption.TRUNCATE_EXISTING);
-                    break;
-                default:    // ignored
-            }
-            if ((flags & SSH_FXF_APPEND_DATA) != 0) {
-                options.add(StandardOpenOption.APPEND);
-            }
-            FileAttribute<?>[] attributes = new FileAttribute<?>[attrs.size()];
-            int index = 0;
-            for (Map.Entry<String, Object> attr : attrs.entrySet()) {
-                final String key = attr.getKey();
-                final Object val = attr.getValue();
-                attributes[index++] = new FileAttribute<Object>() {
-                    @Override
-                    public String name() {
-                        return key;
-                    }
-
-                    @Override
-                    public Object value() {
-                        return val;
-                    }
-                };
-            }
-            FileChannel channel;
-            try {
-                channel = FileChannel.open(file, options, attributes);
-            } catch (UnsupportedOperationException e) {
-                channel = FileChannel.open(file, options);
-                setAttributes(file, attrs);
-            }
-            this.fileChannel = channel;
-            this.pos = 0;
-        }
-
-        public final FileChannel getFileChannel() {
-            return fileChannel;
-        }
-
-        public int getAccessMask() {
-            return access;
-        }
-
-        public int read(byte[] data, long offset) throws IOException {
-            return read(data, 0, data.length, offset);
-        }
-
-        public int read(byte[] data, int doff, int length, long offset) throws 
IOException {
-            FileChannel channel = getFileChannel();
-            if (pos != offset) {
-                channel.position(offset);
-                pos = offset;
-            }
-            int read = channel.read(ByteBuffer.wrap(data, doff, length));
-            pos += read;
-            return read;
-        }
-
-        public void write(byte[] data, long offset) throws IOException {
-            write(data, 0, data.length, offset);
-        }
-
-        public void write(byte[] data, int doff, int length, long offset) 
throws IOException {
-            FileChannel channel = getFileChannel();
-            if (pos != offset) {
-                channel.position(offset);
-                pos = offset;
-            }
-            channel.write(ByteBuffer.wrap(data, doff, length));
-            pos += length;
-        }
-
-        @Override
-        public void close() throws IOException {
-            FileChannel channel = getFileChannel();
-            channel.close();
-        }
-
-        public void lock(long offset, long length, int mask) throws 
IOException {
-            FileChannel channel = getFileChannel();
-            long size = (length == 0L) ? channel.size() - offset : length;
-            FileLock lock = channel.tryLock(offset, size, false);
-            synchronized (locks) {
-                locks.add(lock);
-            }
-        }
-
-        public boolean unlock(long offset, long length) throws IOException {
-            FileChannel channel = getFileChannel();
-            long size = (length == 0) ? channel.size() - offset : length;
-            FileLock lock = null;
-            for (Iterator<FileLock> iterator = locks.iterator(); 
iterator.hasNext();) {
-                FileLock l = iterator.next();
-                if (l.position() == offset && l.size() == size) {
-                    iterator.remove();
-                    lock = l;
-                    break;
-                }
-            }
-            if (lock != null) {
-                lock.release();
-                return true;
-            }
-            return false;
-        }
-    }
-
     /**
      * @param executorService The {@link ExecutorService} to be used by
      *                        the {@link SftpSubsystem} command when starting 
execution. If
@@ -487,21 +339,23 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
      * @param shutdownOnExit  If {@code true} the {@link 
ExecutorService#shutdownNow()}
      *                        will be called when subsystem terminates - 
unless it is the ad-hoc
      *                        service, which will be shutdown regardless
-     * @param policy The {@link UnsupportedAttributePolicy} to use if failed 
to access
-     * some local file attributes
+     * @param policy          The {@link UnsupportedAttributePolicy} to use if 
failed to access
+     *                        some local file attributes
      * @see ThreadUtils#newSingleThreadExecutor(String)
      */
     public SftpSubsystem(ExecutorService executorService, boolean 
shutdownOnExit, UnsupportedAttributePolicy policy) {
-        if ((executors = executorService) == null) {
+        if (executorService == null) {
             executors = 
ThreadUtils.newSingleThreadExecutor(getClass().getSimpleName());
             shutdownExecutor = true;    // we always close the ad-hoc executor 
service
         } else {
+            executors = executorService;
             shutdownExecutor = shutdownOnExit;
         }
-        
-        if ((unsupportedAttributePolicy=policy) == null) {
+
+        if (policy == null) {
             throw new IllegalArgumentException("No policy provided");
         }
+        unsupportedAttributePolicy = policy;
     }
 
     public int getVersion() {
@@ -515,7 +369,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     @Override
     public void setSession(ServerSession session) {
         this.session = session;
-        
+
         FactoryManager manager = session.getFactoryManager();
         Factory<? extends Random> factory = manager.getRandomFactory();
         this.randomizer = factory.create();
@@ -527,7 +381,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         this.maxFileHandleRounds = FactoryManagerUtils.getIntProperty(manager, 
MAX_FILE_HANDLE_RAND_ROUNDS, DEFAULT_FILE_HANDLE_ROUNDS);
         ValidateUtils.checkTrue(this.maxFileHandleRounds >= 
MIN_FILE_HANDLE_ROUNDS, "File handle rounds too small: %d", 
this.maxFileHandleRounds);
         ValidateUtils.checkTrue(this.maxFileHandleRounds <= 
MAX_FILE_HANDLE_ROUNDS, "File handle rounds too big: %d", 
this.maxFileHandleRounds);
-        
+
         if (workBuf.length < this.fileHandleSize) {
             workBuf = new byte[this.fileHandleSize];
         }
@@ -575,13 +429,13 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     @Override
     public void run() {
         try {
-            for (long count = 1L; ; count++) {
+            for (long count = 1L;; count++) {
                 int length = BufferUtils.readInt(in, workBuf, 0, 
workBuf.length);
                 ValidateUtils.checkTrue(length >= ((Integer.SIZE / Byte.SIZE) 
+ 1 /* command */), "Bad length to read: %d", length);
 
                 Buffer buffer = new ByteArrayBuffer(length + (Integer.SIZE / 
Byte.SIZE) /* the length */);
                 buffer.putInt(length);
-                for (int remainLen = length; remainLen > 0; ) {
+                for (int remainLen = length; remainLen > 0;) {
                     int l = in.read(buffer.array(), buffer.wpos(), remainLen);
                     if (l < 0) {
                         throw new IllegalArgumentException("Premature EOF at 
buffer #" + count + " while read length=" + length + " and remain=" + 
remainLen);
@@ -709,31 +563,31 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     }
 
     /**
-     * @param buffer The command {@link Buffer}
-     * @param id  The request id
+     * @param buffer    The command {@link Buffer}
+     * @param id        The request id
      * @param extension The extension name
      * @throws IOException If failed to execute the extension
      */
     protected void executeExtendedCommand(Buffer buffer, int id, String 
extension) throws IOException {
         switch (extension) {
-            case "text-seek":
+            case SftpConstants.EXT_TEXT_SEEK:
                 doTextSeek(buffer, id);
                 break;
-            case SftpConstants.EXT_VERSELECT:
+            case SftpConstants.EXT_VERSION_SELECT:
                 doVersionSelect(buffer, id);
                 break;
-            case SftpConstants.EXT_COPYFILE:
+            case SftpConstants.EXT_COPY_FILE:
                 doCopyFile(buffer, id);
                 break;
-            case SftpConstants.EXT_COPYDATA:
+            case SftpConstants.EXT_COPY_DATA:
                 doCopyData(buffer, id);
                 break;
-            case SftpConstants.EXT_MD5HASH:
-            case SftpConstants.EXT_MD5HASH_HANDLE:
+            case SftpConstants.EXT_MD5_HASH:
+            case SftpConstants.EXT_MD5_HASH_HANDLE:
                 doMD5Hash(buffer, id, extension);
                 break;
-            case SftpConstants.EXT_CHKFILE_HANDLE:
-            case SftpConstants.EXT_CHKFILE_NAME:
+            case SftpConstants.EXT_CHECK_FILE_HANDLE:
+            case SftpConstants.EXT_CHECK_FILE_NAME:
                 doCheckFileHash(buffer, id, extension);
                 break;
             case FsyncExtensionParser.NAME:
@@ -753,8 +607,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         String path = buffer.getString();
         SpaceAvailableExtensionInfo info;
         try {
-             info = doSpaceAvailable(id, path);
-        } catch(IOException | RuntimeException e) {
+            info = doSpaceAvailable(id, path);
+        } catch (IOException | RuntimeException e) {
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
@@ -779,7 +633,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             log.trace("doSpaceAvailable(id={}) path={}[{}] - {}[{}]",
                     id, path, nrm, store.name(), store.type());
         }
-        
+
         return new SpaceAvailableExtensionInfo(store);
     }
 
@@ -789,7 +643,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         try {
             // TODO : implement text-seek - see 
https://tools.ietf.org/html/draft-ietf-secsh-filexfer-03#section-6.3
             doTextSeek(id, handle, line);
-        } catch(IOException | RuntimeException e) {
+        } catch (IOException | RuntimeException e) {
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
@@ -800,7 +654,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     protected void doTextSeek(int id, String handle, long line) throws 
IOException {
         Handle h = handles.get(handle);
         if (log.isDebugEnabled()) {
-            log.debug("Received SSH_FXP_EXTENDED(text-seek) (handle={}[{}], 
line={})", handle, h, Long.valueOf(line));
+            log.debug("Received SSH_FXP_EXTENDED(text-seek) (handle={}[{}], 
line={})", handle, h, line);
         }
 
         FileHandle fileHandle = validateHandle(handle, h, FileHandle.class);
@@ -812,7 +666,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         String handle = buffer.getString();
         try {
             doOpenSSHFsync(id, handle);
-        } catch(IOException | RuntimeException e) {
+        } catch (IOException | RuntimeException e) {
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
@@ -825,7 +679,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         if (log.isDebugEnabled()) {
             log.debug("doOpenSSHFsync({})[{}]", handle, h);
         }
-        
+
         FileHandle fileHandle = validateHandle(handle, h, FileHandle.class);
         FileChannel channel = fileHandle.getFileChannel();
         channel.force(false);
@@ -842,23 +696,23 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             buffer.clear();
             buffer.putByte((byte) SSH_FXP_EXTENDED_REPLY);
             buffer.putInt(id);
-            buffer.putString(SftpConstants.EXT_CHKFILE_RESPONSE);
+            buffer.putString(SftpConstants.EXT_CHECK_FILE);
             doCheckFileHash(id, targetType, target, Arrays.asList(algos), 
startOffset, length, blockSize, buffer);
-        } catch(Exception e) {
+        } catch (Exception e) {
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
-        
+
         send(buffer);
     }
 
     protected void doCheckFileHash(int id, String targetType, String target, 
Collection<String> algos,
                                    long startOffset, long length, int 
blockSize, Buffer buffer)
-                    throws Exception {
+            throws Exception {
         Path path;
-        if (SftpConstants.EXT_CHKFILE_HANDLE.equalsIgnoreCase(targetType)) {
+        if (SftpConstants.EXT_CHECK_FILE_HANDLE.equalsIgnoreCase(targetType)) {
             Handle h = handles.get(target);
-            FileHandle fileHandle = validateHandle(target, h, 
FileHandle.class); 
+            FileHandle fileHandle = validateHandle(target, h, 
FileHandle.class);
             path = fileHandle.getFile();
 
             /*
@@ -880,10 +734,10 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
              *      If 'check-file-name' refers to a 
SSH_FILEXFER_TYPE_SYMLINK, the
              *      target should be opened.
              */
-            for (int index=0; Files.isSymbolicLink(path) && (index < 
Byte.MAX_VALUE /* TODO make this configurable */); index++) {
+            for (int index = 0; Files.isSymbolicLink(path) && (index < 
Byte.MAX_VALUE /* TODO make this configurable */); index++) {
                 path = Files.readSymbolicLink(path);
             }
-            
+
             if (Files.isSymbolicLink(path)) {
                 throw new FileSystemLoopException(target + " yields a circular 
or too long chain of symlinks");
             }
@@ -894,10 +748,11 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         }
 
         ValidateUtils.checkNotNullAndNotEmpty(algos, "No hash algorithms 
specified");
-        
+
         NamedFactory<? extends Digest> factory = null;
         for (String a : algos) {
-            if ((factory = BuiltinDigests.fromFactoryName(a)) != null) {
+            factory = BuiltinDigests.fromFactoryName(a);
+            if (factory != null) {
                 break;
             }
         }
@@ -908,13 +763,13 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
 
     protected void doCheckFileHash(int id, Path file, NamedFactory<? extends 
Digest> factory,
                                    long startOffset, long length, int 
blockSize, Buffer buffer)
-                           throws Exception {
+            throws Exception {
         ValidateUtils.checkTrue(startOffset >= 0L, "Invalid start offset: %d", 
startOffset);
         ValidateUtils.checkTrue(length >= 0L, "Invalid length: %d", length);
         ValidateUtils.checkTrue((blockSize == 0) || (blockSize >= 
SftpConstants.MIN_CHKFILE_BLOCKSIZE), "Invalid block size: %d", blockSize);
         ValidateUtils.checkNotNull(factory, "No digest factory provided");
         buffer.putString(factory.getName());
-        
+
         long effectiveLength = length;
         long totalLength = Files.size(file);
         if (effectiveLength == 0L) {
@@ -928,18 +783,17 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         ValidateUtils.checkTrue(effectiveLength > 0L, "Non-positive effective 
hash data length: %d", effectiveLength);
 
         byte[] digestBuf = (blockSize == 0)
-                       ? new byte[Math.min((int) effectiveLength, 
IoUtils.DEFAULT_COPY_SIZE)]
-                       : new byte[Math.min((int) effectiveLength, blockSize)]
-                       ;
+                ? new byte[Math.min((int) effectiveLength, 
IoUtils.DEFAULT_COPY_SIZE)]
+                : new byte[Math.min((int) effectiveLength, blockSize)];
         ByteBuffer wb = ByteBuffer.wrap(digestBuf);
-        try(FileChannel channel = FileChannel.open(file, 
IoUtils.EMPTY_OPEN_OPTIONS)) {
+        try (FileChannel channel = FileChannel.open(file, 
IoUtils.EMPTY_OPEN_OPTIONS)) {
             channel.position(startOffset);
 
             Digest digest = factory.create();
             digest.init();
 
             if (blockSize == 0) {
-                while(effectiveLength > 0L) {
+                while (effectiveLength > 0L) {
                     int remainLen = Math.min(digestBuf.length, (int) 
effectiveLength);
                     ByteBuffer bb = wb;
                     if (remainLen < digestBuf.length) {
@@ -955,16 +809,16 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                     effectiveLength -= readLen;
                     digest.update(digestBuf, 0, readLen);
                 }
-                
+
                 byte[] hashValue = digest.digest();
                 if (log.isTraceEnabled()) {
                     log.trace("doCheckFileHash({}) offset={}, length={} - 
hash={}",
-                              file, Long.valueOf(startOffset), 
Long.valueOf(length),
-                              BufferUtils.printHex(':', hashValue));
+                            file, startOffset, length,
+                            BufferUtils.printHex(':', hashValue));
                 }
                 buffer.putBytes(hashValue);
             } else {
-                for (int count=0; effectiveLength > 0L; count++) {
+                for (int count = 0; effectiveLength > 0L; count++) {
                     int remainLen = Math.min(digestBuf.length, (int) 
effectiveLength);
                     ByteBuffer bb = wb;
                     if (remainLen < digestBuf.length) {
@@ -983,8 +837,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                     byte[] hashValue = digest.digest(); // NOTE: this also 
resets the hash for the next read
                     if (log.isTraceEnabled()) {
                         log.trace("doCheckFileHash({})[{}] offset={}, 
length={} - hash={}",
-                                  file, count, startOffset, length,
-                                  BufferUtils.printHex(':', hashValue));
+                                file, count, startOffset, length,
+                                BufferUtils.printHex(':', hashValue));
                     }
                     buffer.putBytes(hashValue);
                 }
@@ -996,17 +850,18 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         String target = buffer.getString();
         long startOffset = buffer.getLong();
         long length = buffer.getLong();
-        byte[] quickCheckHash = buffer.getBytes(), hashValue;
-        
+        byte[] quickCheckHash = buffer.getBytes();
+        byte[] hashValue;
+
         try {
             hashValue = doMD5Hash(id, targetType, target, startOffset, length, 
quickCheckHash);
             if (log.isTraceEnabled()) {
                 log.debug("doMD5Hash({})[{}] offset={}, length={}, 
quick-hash={} - hash={}",
-                          targetType, target, startOffset, length, 
BufferUtils.printHex(':', quickCheckHash),
-                          BufferUtils.printHex(':', hashValue));
+                        targetType, target, startOffset, length, 
BufferUtils.printHex(':', quickCheckHash),
+                        BufferUtils.printHex(':', hashValue));
             }
 
-        } catch(Exception e) {
+        } catch (Exception e) {
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
@@ -1022,13 +877,13 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     protected byte[] doMD5Hash(int id, String targetType, String target, long 
startOffset, long length, byte[] quickCheckHash) throws Exception {
         if (log.isDebugEnabled()) {
             log.debug("doMD5Hash({})[{}] offset={}, length={}, quick-hash={}",
-                      targetType, target, startOffset, length, 
BufferUtils.printHex(':', quickCheckHash));
+                    targetType, target, startOffset, length, 
BufferUtils.printHex(':', quickCheckHash));
         }
 
         Path path;
-        if (SftpConstants.EXT_MD5HASH_HANDLE.equalsIgnoreCase(targetType)) {
+        if (SftpConstants.EXT_MD5_HASH_HANDLE.equalsIgnoreCase(targetType)) {
             Handle h = handles.get(target);
-            FileHandle fileHandle = validateHandle(target, h, 
FileHandle.class); 
+            FileHandle fileHandle = validateHandle(target, h, 
FileHandle.class);
             path = fileHandle.getFile();
 
             /*
@@ -1054,7 +909,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
          *
          *      If both start-offset and length are zero, the entire file 
should be included
          */
-        long effectiveLength = length, totalSize = Files.size(path);
+        long effectiveLength = length;
+        long totalSize = Files.size(path);
         if ((startOffset == 0L) && (length == 0L)) {
             effectiveLength = totalSize;
         } else {
@@ -1080,7 +936,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         boolean hashMatches = false;
         byte[] hashValue = null;
 
-        try(FileChannel channel = FileChannel.open(path, 
StandardOpenOption.READ)) {
+        try (FileChannel channel = FileChannel.open(path, 
StandardOpenOption.READ)) {
             channel.position(startOffset);
 
             /*
@@ -1121,14 +977,14 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                 } else {
                     if (log.isTraceEnabled()) {
                         log.trace("doMD5Hash({}) offset={}, length={} - 
quick-hash mismatched expected={}, actual={}",
-                                  path, startOffset, length,
-                                  BufferUtils.printHex(':', quickCheckHash), 
BufferUtils.printHex(':', hashValue));
+                                path, startOffset, length,
+                                BufferUtils.printHex(':', quickCheckHash), 
BufferUtils.printHex(':', hashValue));
                     }
                 }
             }
 
             if (hashMatches) {
-                while(effectiveLength > 0L) {
+                while (effectiveLength > 0L) {
                     int remainLen = Math.min(digestBuf.length, (int) 
effectiveLength);
                     ByteBuffer bb = wb;
                     if (remainLen < digestBuf.length) {
@@ -1143,7 +999,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                     effectiveLength -= readLen;
                     digest.update(digestBuf, 0, readLen);
                 }
-                
+
                 if (hashValue == null) {    // check if did any more 
iterations after the quick hash
                     hashValue = digest.digest();
                 }
@@ -1154,8 +1010,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
 
         if (log.isTraceEnabled()) {
             log.trace("doMD5Hash({}) offset={}, length={} - matches={}, 
quick={} hash={}",
-                      path, startOffset, length, hashMatches,
-                      BufferUtils.printHex(':', quickCheckHash), 
BufferUtils.printHex(':', hashValue));
+                    path, startOffset, length, hashMatches,
+                    BufferUtils.printHex(':', quickCheckHash), 
BufferUtils.printHex(':', hashValue));
         }
 
         return hashValue;
@@ -1169,9 +1025,9 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
          * channel.
          */
         if (requestsCount > 0L) {
-           sendStatus(BufferUtils.clear(buffer), id, SSH_FX_FAILURE, "Version 
selection not the 1st request for proposal = " + proposed);
-           session.close(true);
-           return;
+            sendStatus(BufferUtils.clear(buffer), id, SSH_FX_FAILURE, "Version 
selection not the 1st request for proposal = " + proposed);
+            session.close(true);
+            return;
         }
 
         Boolean result = validateProposedVersion(buffer, id, proposed);
@@ -1181,7 +1037,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         if (result == null) {   // response sent internally
             session.close(true);
             return;
-        } if (result) {
+        }
+        if (result) {
             version = Integer.parseInt(proposed);
             sendStatus(BufferUtils.clear(buffer), id, SSH_FX_OK, "");
         } else {
@@ -1191,8 +1048,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     }
 
     /**
-     * @param buffer The {@link Buffer} holding the request
-     * @param id The request id
+     * @param buffer   The {@link Buffer} holding the request
+     * @param id       The request id
      * @param proposed The proposed value
      * @return A {@link Boolean} indicating whether to accept/reject the 
proposal.
      * If {@code null} then rejection response has been sent, otherwise and
@@ -1203,7 +1060,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_EXTENDED(version-select) 
(version={})", proposed);
         }
-        
+
         if (GenericUtils.length(proposed) != 1) {
             return Boolean.FALSE;
         }
@@ -1226,10 +1083,11 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
      * Checks if a proposed version is within supported range. <B>Note:</B>
      * if the user forced a specific value via the {@link #SFTP_VERSION}
      * property, then it is used to validate the proposed value
-     * @param buffer The {@link Buffer} containing the request
-     * @param id The SSH message ID to be used to send the failure message
-     * if required
-     * @param proposed The proposed version value
+     *
+     * @param buffer        The {@link Buffer} containing the request
+     * @param id            The SSH message ID to be used to send the failure 
message
+     *                      if required
+     * @param proposed      The proposed version value
      * @param failureOpcode The failure opcode to send if validation fails
      * @return A {@link String} of comma separated values representing all
      * the supported version - {@code null} if validation failed and an
@@ -1247,7 +1105,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             if ((forcedValue < LOWER_SFTP_IMPL) || (forcedValue > 
HIGHER_SFTP_IMPL)) {
                 throw new IllegalStateException("Forced SFTP version (" + 
sftpVersion + ") not within supported values: " + available);
             }
-            low = hig = sftpVersion;
+            hig = sftpVersion;
+            low = hig;
             available = sftpVersion.toString();
         }
 
@@ -1269,7 +1128,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         long offset = buffer.getLong();
         long length = buffer.getLong();
         int mask = buffer.getInt();
-        
+
         try {
             doBlock(id, handle, offset, length, mask);
         } catch (IOException | RuntimeException e) {
@@ -1284,9 +1143,9 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         Handle p = handles.get(handle);
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_BLOCK (handle={}[{}], offset={}, 
length={}, mask=0x{})",
-                      handle, p, offset, length, Integer.toHexString(mask));
+                    handle, p, offset, length, Integer.toHexString(mask));
         }
-        
+
         FileHandle fileHandle = validateHandle(handle, p, FileHandle.class);
         fileHandle.lock(offset, length, mask);
     }
@@ -1310,7 +1169,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         Handle p = handles.get(handle);
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_UNBLOCK (handle={}[{}], offset={}, 
length={})",
-                      handle, p, offset, length);
+                    handle, p, offset, length);
         }
 
         FileHandle fileHandle = validateHandle(handle, p, FileHandle.class);
@@ -1328,16 +1187,16 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
-        
+
         sendStatus(BufferUtils.clear(buffer), id, SSH_FX_OK, "");
     }
 
     protected void doLink(int id, String targetPath, String linkPath, boolean 
symLink) throws IOException {
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_LINK (linkpath={}, targetpath={}, 
symlink={})",
-                      linkPath, targetPath, symLink);
+                    linkPath, targetPath, symLink);
         }
-        
+
         Path link = resolveFile(linkPath);
         Path target = fileSystem.getPath(targetPath);
         if (symLink) {
@@ -1368,9 +1227,10 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     }
 
     protected void doReadLink(Buffer buffer, int id) throws IOException {
-        String path = buffer.getString(), l;
+        String path = buffer.getString();
+        String l;
         try {
-             l = doReadLink(id, path);
+            l = doReadLink(id, path);
         } catch (IOException | RuntimeException e) {
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
@@ -1382,7 +1242,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     protected String doReadLink(int id, String path) throws IOException {
         Path f = resolveFile(path);
         log.debug("Received SSH_FXP_READLINK (path={}[{}])", path, f);
-        
+
         Path t = Files.readSymbolicLink(f);
         return t.toString();
     }
@@ -1407,7 +1267,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     protected void doRename(int id, String oldPath, String newPath, int flags) 
throws IOException {
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_RENAME (oldPath={}, newPath={}, 
flags=0x{})",
-                       oldPath, newPath, Integer.toHexString(flags));
+                    oldPath, newPath, Integer.toHexString(flags));
         }
 
         Collection<CopyOption> opts = Collections.emptyList();
@@ -1420,10 +1280,10 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                 opts.add(StandardCopyOption.REPLACE_EXISTING);
             }
         }
-        
+
         doRename(id, oldPath, newPath, opts);
     }
-    
+
     protected void doRename(int id, String oldPath, String newPath, 
Collection<CopyOption> opts) throws IOException {
         Path o = resolveFile(oldPath);
         Path n = resolveFile(newPath);
@@ -1454,9 +1314,9 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         Handle wh = inPlaceCopy ? rh : handles.get(writeHandle);
         if (log.isDebugEnabled()) {
             log.debug("SSH_FXP_EXTENDED[{}] read={}[{}], read-offset={}, 
read-length={}, write={}[{}], write-offset={})",
-                      SftpConstants.EXT_COPYDATA,
-                      readHandle, rh, readOffset, readLength,
-                      writeHandle, wh, writeOffset);
+                    SftpConstants.EXT_COPY_DATA,
+                    readHandle, rh, readOffset, readLength,
+                    writeHandle, wh, writeOffset);
         }
 
         FileHandle srcHandle = validateHandle(readHandle, rh, 
FileHandle.class);
@@ -1494,19 +1354,19 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             if (maxRead > totalSize) {
                 maxRead = totalSize;
             }
-            
+
             long maxWrite = writeOffset + effectiveLength;
             if (maxWrite > readOffset) {
                 throw new IllegalArgumentException("Write range end [" + 
writeOffset + "-" + maxWrite + "]"
-                                                 + " overlaps with read range 
[" + readOffset + "-" +  maxRead + "]");
+                        + " overlaps with read range [" + readOffset + "-" + 
maxRead + "]");
             } else if (maxRead > writeOffset) {
-                throw new IllegalArgumentException("Read range end [" + 
readOffset + "-" +  maxRead + "]"
-                                                 + " overlaps with write range 
[" + writeOffset + "-" + maxWrite + "]");
+                throw new IllegalArgumentException("Read range end [" + 
readOffset + "-" + maxRead + "]"
+                        + " overlaps with write range [" + writeOffset + "-" + 
maxWrite + "]");
             }
         }
-        
+
         byte[] copyBuf = new byte[Math.min(IoUtils.DEFAULT_COPY_SIZE, (int) 
effectiveLength)];
-        while(effectiveLength > 0L) {
+        while (effectiveLength > 0L) {
             int remainLength = Math.min(copyBuf.length, (int) effectiveLength);
             int readLen = srcHandle.read(copyBuf, 0, remainLength, readOffset);
             if (readLen < 0) {
@@ -1539,13 +1399,13 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     protected void doCopyFile(int id, String srcFile, String dstFile, boolean 
overwriteDestination) throws IOException {
         if (log.isDebugEnabled()) {
             log.debug("SSH_FXP_EXTENDED[{}] (src={}, dst={}, overwrite=0x{})",
-                      SftpConstants.EXT_COPYFILE, srcFile, dstFile, 
overwriteDestination);
+                    SftpConstants.EXT_COPY_FILE, srcFile, dstFile, 
overwriteDestination);
         }
-        
+
         doCopyFile(id, srcFile, dstFile,
-                   overwriteDestination
-                  ? 
Collections.<CopyOption>singletonList(StandardCopyOption.REPLACE_EXISTING)
-                  : Collections.<CopyOption>emptyList());
+                overwriteDestination
+                        ? 
Collections.<CopyOption>singletonList(StandardCopyOption.REPLACE_EXISTING)
+                        : Collections.<CopyOption>emptyList());
     }
 
     protected void doCopyFile(int id, String srcFile, String dstFile, 
Collection<CopyOption> opts) throws IOException {
@@ -1561,18 +1421,18 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             flags = buffer.getInt();
         }
 
-        Map<String,Object> attrs;
+        Map<String, Object> attrs;
         try {
-             attrs = doStat(id, path, flags);
-        } catch(IOException | RuntimeException e) {
+            attrs = doStat(id, path, flags);
+        } catch (IOException | RuntimeException e) {
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
-        
+
         sendAttrs(BufferUtils.clear(buffer), id, attrs);
     }
 
-    protected Map<String,Object> doStat(int id, String path, int flags) throws 
IOException {
+    protected Map<String, Object> doStat(int id, String path, int flags) 
throws IOException {
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_STAT (path={}, flags=0x{})", path, 
Integer.toHexString(flags));
         }
@@ -1588,8 +1448,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             path = ".";
         }
 
-        Map<String,?> attrs = Collections.<String, Object>emptyMap();
-        Pair<Path,Boolean> result;
+        Map<String, ?> attrs = Collections.<String, Object>emptyMap();
+        Pair<Path, Boolean> result;
         try {
             LinkOption[] options = IoUtils.getLinkOptions(false);
             if (version < SFTP_V6) {
@@ -1627,7 +1487,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                         } catch (IOException e) {
                             if (log.isDebugEnabled()) {
                                 log.debug("Failed ({}) to retrieve attributes 
of {}: {}",
-                                          e.getClass().getSimpleName(), p, 
e.getMessage());
+                                        e.getClass().getSimpleName(), p, 
e.getMessage());
                             }
                         }
                     } else {
@@ -1653,9 +1513,9 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         sendPath(BufferUtils.clear(buffer), id, result.getFirst(), attrs);
     }
 
-    protected Pair<Path,Boolean> doRealPathV6(int id, String path, 
Collection<String> extraPaths, LinkOption ... options) throws IOException {
+    protected Pair<Path, Boolean> doRealPathV6(int id, String path, 
Collection<String> extraPaths, LinkOption... options) throws IOException {
         Path p = resolveFile(path);
-        int numExtra = GenericUtils.size(extraPaths); 
+        int numExtra = GenericUtils.size(extraPaths);
         if (numExtra > 0) {
             StringBuilder sb = new StringBuilder(GenericUtils.length(path) + 
numExtra * 8);
             sb.append(path);
@@ -1664,28 +1524,28 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                 p = p.resolve(p2);
                 sb.append('/').append(p2);
             }
-            
+
             path = sb.toString();
         }
 
         return validateRealPath(id, path, p, options);
     }
 
-    protected Pair<Path,Boolean> doRealPathV345(int id, String path, 
LinkOption ... options) throws IOException {
+    protected Pair<Path, Boolean> doRealPathV345(int id, String path, 
LinkOption... options) throws IOException {
         return validateRealPath(id, path, resolveFile(path), options);
     }
 
     /**
-     * @param id The request identifier
-     * @param path The original path
-     * @param f The resolve {@link Path}
+     * @param id      The request identifier
+     * @param path    The original path
+     * @param f       The resolve {@link Path}
      * @param options The {@link LinkOption}s to use to verify file existence 
and access
      * @return A {@link Pair} whose left-hand is the <U>absolute 
<B>normalized</B></U>
      * {@link Path} and right-hand is a {@link Boolean} indicating its status
      * @throws IOException If failed to validate the file
      * @see IoUtils#checkFileExists(Path, LinkOption...)
      */
-    protected Pair<Path,Boolean> validateRealPath(int id, String path, Path f, 
LinkOption ... options) throws IOException {
+    protected Pair<Path, Boolean> validateRealPath(int id, String path, Path 
f, LinkOption... options) throws IOException {
         Path abs = f.toAbsolutePath();
         Path p = abs.normalize();
         Boolean status = IoUtils.checkFileExists(p, options);
@@ -1700,11 +1560,11 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
-        
+
         sendStatus(BufferUtils.clear(buffer), id, SSH_FX_OK, "");
     }
 
-    protected void doRemoveDirectory(int id, String path, LinkOption ... 
options) throws IOException {
+    protected void doRemoveDirectory(int id, String path, LinkOption... 
options) throws IOException {
         Path p = resolveFile(path);
         log.debug("Received SSH_FXP_RMDIR (path={})[{}]", path, p);
         if (Files.isDirectory(p, options)) {
@@ -1727,13 +1587,13 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         sendStatus(BufferUtils.clear(buffer), id, SSH_FX_OK, "");
     }
 
-    protected void doMakeDirectory(int id, String path, Map<String,?> attrs, 
LinkOption ... options) throws IOException {
+    protected void doMakeDirectory(int id, String path, Map<String, ?> attrs, 
LinkOption... options) throws IOException {
         Path p = resolveFile(path);
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_MKDIR (path={}[{}], attrs={})", path, 
p, attrs);
         }
-        
-        Boolean  status = IoUtils.checkFileExists(p, options);
+
+        Boolean status = IoUtils.checkFileExists(p, options);
         if (status == null) {
             throw new AccessDeniedException("Cannot validate make-directory 
existence for " + p);
         }
@@ -1762,12 +1622,12 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         sendStatus(BufferUtils.clear(buffer), id, SSH_FX_OK, "");
     }
 
-    protected void doRemove(int id, String path, LinkOption ... options) 
throws IOException {
+    protected void doRemove(int id, String path, LinkOption... options) throws 
IOException {
         Path p = resolveFile(path);
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_REMOVE (path={}[{}])", path, p);
         }
-        
+
         Boolean status = IoUtils.checkFileExists(p, options);
         if (status == null) {
             throw new AccessDeniedException("Cannot determine existence of 
remove candidate: " + p);
@@ -1812,7 +1672,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                 // There is at least one file in the directory or we need to 
send the "..".
                 // Send only a few files at a time to not create packets of a 
too
                 // large size or have a timeout to occur.
-                
+
                 reply = BufferUtils.clear(buffer);
                 reply.putByte((byte) SSH_FXP_NAME);
                 reply.putInt(id);
@@ -1833,18 +1693,19 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                 dh.markDone();
                 throw new EOFException("Empty directory");
             }
-            
+
             ValidateUtils.checkNotNull(reply, "No reply buffer created");
         } catch (IOException | RuntimeException e) {
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
-        
+
         send(reply);
     }
 
     protected void doOpenDir(Buffer buffer, int id) throws IOException {
-        String path = buffer.getString(), handle;
+        String path = buffer.getString();
+        String handle;
 
         try {
             handle = doOpenDir(id, path, IoUtils.getLinkOptions(false));
@@ -1856,12 +1717,12 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         sendHandle(BufferUtils.clear(buffer), id, handle);
     }
 
-    protected String doOpenDir(int id, String path, LinkOption ... options) 
throws IOException {
+    protected String doOpenDir(int id, String path, LinkOption... options) 
throws IOException {
         Path f = resolveFile(path);
         Path abs = f.toAbsolutePath();
         Path p = abs.normalize();
         log.debug("Received SSH_FXP_OPENDIR (path={})[{}]", path, p);
-        
+
         Boolean status = IoUtils.checkFileExists(p, options);
         if (status == null) {
             throw new AccessDeniedException("Cannot determine open-dir 
existence for " + p);
@@ -1889,11 +1750,11 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
-        
+
         sendStatus(BufferUtils.clear(buffer), id, SSH_FX_OK, "");
     }
 
-    protected void doFSetStat(int id, String handle, Map<String,?> attrs) 
throws IOException {
+    protected void doFSetStat(int id, String handle, Map<String, ?> attrs) 
throws IOException {
         Handle h = handles.get(handle);
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_FSETSTAT (handle={}[{}], attrs={})", 
handle, h, attrs);
@@ -1915,7 +1776,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         sendStatus(BufferUtils.clear(buffer), id, SSH_FX_OK, "");
     }
 
-    protected void doSetStat(int id, String path, Map<String,?> attrs) throws 
IOException {
+    protected void doSetStat(int id, String path, Map<String, ?> attrs) throws 
IOException {
         log.debug("Received SSH_FXP_SETSTAT (path={}, attrs={})", path, attrs);
         Path p = resolveFile(path);
         setAttributes(p, attrs);
@@ -1927,8 +1788,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         if (version >= SFTP_V4) {
             flags = buffer.getInt();
         }
-        
-        Map<String,?> attrs;
+
+        Map<String, ?> attrs;
         try {
             attrs = doFStat(id, handle, flags);
         } catch (IOException | RuntimeException e) {
@@ -1939,12 +1800,12 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         sendAttrs(BufferUtils.clear(buffer), id, attrs);
     }
 
-    protected Map<String,Object> doFStat(int id, String handle, int flags) 
throws IOException {
+    protected Map<String, Object> doFStat(int id, String handle, int flags) 
throws IOException {
         Handle h = handles.get(handle);
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_FSTAT (handle={}[{}], flags=0x{})", 
handle, h, Integer.toHexString(flags));
         }
-        
+
         return resolveFileAttributes(validateHandle(handle, h, 
Handle.class).getFile(), flags, IoUtils.getLinkOptions(true));
     }
 
@@ -1954,8 +1815,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         if (version >= SFTP_V4) {
             flags = buffer.getInt();
         }
-        
-        Map<String,?> attrs;
+
+        Map<String, ?> attrs;
         try {
             attrs = doLStat(id, path, flags);
         } catch (IOException | RuntimeException e) {
@@ -1966,7 +1827,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         sendAttrs(BufferUtils.clear(buffer), id, attrs);
     }
 
-    protected Map<String,Object> doLStat(int id, String path, int flags) 
throws IOException {
+    protected Map<String, Object> doLStat(int id, String path, int flags) 
throws IOException {
         Path p = resolveFile(path);
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_LSTAT (path={}[{}], flags=0x{})", 
path, p, Integer.toHexString(flags));
@@ -1993,9 +1854,9 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         Handle h = handles.get(handle);
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_WRITE (handle={}[{}], offset={}, 
data=byte[{}])",
-                      handle, h, offset, length);
+                    handle, h, offset, length);
         }
-        
+
         FileHandle fh = validateHandle(handle, h, FileHandle.class);
         if (length < 0) {
             throw new IllegalStateException("Bad length (" + length + ") for 
writing to " + fh);
@@ -2032,7 +1893,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             sendStatus(BufferUtils.clear(buffer), id, e);
             return;
         }
-        
+
         send(buffer);
     }
 
@@ -2040,11 +1901,11 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         Handle h = handles.get(handle);
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_READ (handle={}[{}], offset={}, 
length={})",
-                      handle, h, offset, length);
+                    handle, h, offset, length);
         }
         ValidateUtils.checkTrue(length > 0, "Invalid read length: %d", length);
         FileHandle fh = validateHandle(handle, h, FileHandle.class);
-        
+
         return fh.read(data, doff, length, offset);
     }
 
@@ -2073,7 +1934,8 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
          */
         int access = 0;
         if (version >= SFTP_V5) {
-            if ((access=buffer.getInt()) == 0) {
+            access = buffer.getInt();
+            if (access == 0) {
                 access = ACE4_READ_DATA | ACE4_READ_ATTRIBUTES;
             }
         }
@@ -2132,35 +1994,35 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     }
 
     /**
-     * @param id Request id
-     * @param path Path
+     * @param id     Request id
+     * @param path   Path
      * @param pflags Open mode flags - see {@code SSH_FXF_XXX} flags
      * @param access Access mode flags - see {@code ACE4_XXX} flags
-     * @param attrs Requested attributes
+     * @param attrs  Requested attributes
      * @return The assigned (opaque) handle
      * @throws IOException if failed to execute
      */
     protected String doOpen(int id, String path, int pflags, int access, 
Map<String, Object> attrs) throws IOException {
         if (log.isDebugEnabled()) {
             log.debug("Received SSH_FXP_OPEN (path={}, access=0x{}, 
pflags=0x{}, attrs={})",
-                      path, Integer.toHexString(access), 
Integer.toHexString(pflags), attrs);
+                    path, Integer.toHexString(access), 
Integer.toHexString(pflags), attrs);
         }
         int curHandleCount = handles.size();
         int maxHandleCount = FactoryManagerUtils.getIntProperty(session, 
MAX_OPEN_HANDLES_PER_SESSION, DEFAULT_MAX_OPEN_HANDLES);
         if (curHandleCount > maxHandleCount) {
             throw new IllegalStateException("Too many open handles: current=" 
+ curHandleCount + ", max.=" + maxHandleCount);
         }
-        
+
         Path file = resolveFile(path);
         String handle = generateFileHandle(file);
-        handles.put(handle, new FileHandle(file, pflags, access, attrs));
+        handles.put(handle, new FileHandle(this, file, pflags, access, attrs));
         return handle;
     }
 
     // we stringify our handles and treat them as such on decoding as well as 
it is easier to use as a map key
     protected String generateFileHandle(Path file) {
         // use several rounds in case the file handle size is relatively small 
so we might get conflicts
-        for (int index=0; index < maxFileHandleRounds; index++) {
+        for (int index = 0; index < maxFileHandleRounds; index++) {
             randomizer.fill(workBuf, 0, fileHandleSize);
             String handle = BufferUtils.printHex(workBuf, 0, fileHandleSize, 
BufferUtils.EMPTY_HEX_SEPARATOR);
             if (handles.containsKey(handle)) {
@@ -2175,7 +2037,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             }
             return handle;
         }
-        
+
         throw new IllegalStateException("Failed to generate a unique file 
handle for " + file);
     }
 
@@ -2223,16 +2085,16 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     }
 
     protected List<OpenSSHExtension> appendOpenSSHExtensions(Buffer buffer) {
-        List<OpenSSHExtension> extList = resolveOpenSSHExtensions(); 
+        List<OpenSSHExtension> extList = resolveOpenSSHExtensions();
         if (GenericUtils.isEmpty(extList)) {
             return extList;
         }
-        
+
         for (OpenSSHExtension ext : extList) {
             buffer.putString(ext.getName());
             buffer.putString(ext.getVersion());
         }
-        
+
         return extList;
     }
 
@@ -2247,21 +2109,21 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         if (numExts <= 0) {     // User does not want to report ANY extensions
             return Collections.emptyList();
         }
-                
+
         List<OpenSSHExtension> extList = new ArrayList<>(numExts);
         for (String nvp : pairs) {
             nvp = GenericUtils.trimToEmpty(nvp);
             if (GenericUtils.isEmpty(nvp)) {
                 continue;
             }
-            
+
             int pos = nvp.indexOf('=');
             ValidateUtils.checkTrue((pos > 0) && (pos < (nvp.length() - 1)), 
"Malformed OpenSSH extension spec: %s", nvp);
             String name = GenericUtils.trimToEmpty(nvp.substring(0, pos));
             String version = GenericUtils.trimToEmpty(nvp.substring(pos + 1));
             extList.add(new OpenSSHExtension(name, 
ValidateUtils.checkNotNullAndNotEmpty(version, "No version specified for 
OpenSSH extension %s", name)));
         }
-        
+
         return extList;
     }
 
@@ -2270,7 +2132,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         if (value == null) {
             return DEFAULT_SUPPORTED_CLIENT_EXTENSIONS;
         }
-        
+
         if (value.length() <= 0) {  // means don't report any extensions
             return Collections.emptyList();
         }
@@ -2278,12 +2140,14 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         String[] comps = GenericUtils.split(value, ',');
         return Arrays.asList(comps);
     }
+
     /**
      * Appends the &quot;versions&quot; extension to the buffer. <B>Note:</B>
      * if overriding this method make sure you either do not append anything
      * or use the correct extension name
+     *
      * @param buffer The {@link Buffer} to append to
-     * @param value The recommended value
+     * @param value  The recommended value
      * @see SftpConstants#EXT_VERSIONS
      */
     protected void appendVersionsExtension(Buffer buffer, String value) {
@@ -2295,27 +2159,29 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
      * Appends the &quot;newline&quot; extension to the buffer. <B>Note:</B>
      * if overriding this method make sure you either do not append anything
      * or use the correct extension name
+     *
      * @param buffer The {@link Buffer} to append to
-     * @param value The recommended value
+     * @param value  The recommended value
      * @see SftpConstants#EXT_NEWLINE
      */
     protected void appendNewlineExtension(Buffer buffer, String value) {
         buffer.putString(EXT_NEWLINE);
         buffer.putString(value);
     }
-    
+
     /**
      * Appends the &quot;vendor-id&quot; extension to the buffer. <B>Note:</B>
      * if overriding this method make sure you either do not append anything
      * or use the correct extension name
-     * @param buffer The {@link Buffer} to append to
+     *
+     * @param buffer            The {@link Buffer} to append to
      * @param versionProperties The currently available version properties
-     * @see SftpConstants#EXT_VENDORID
+     * @see SftpConstants#EXT_VENDOR_ID
      * @see <A 
HREF="http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-09.txt";>DRAFT
 09 - section 4.4</A>
      */
-    protected void appendVendorIdExtension(Buffer buffer, Map<String,?> 
versionProperties) {
-        buffer.putString(EXT_VENDORID);
-        
+    protected void appendVendorIdExtension(Buffer buffer, Map<String, ?> 
versionProperties) {
+        buffer.putString(EXT_VENDOR_ID);
+
         // placeholder for length
         int lenPos = buffer.wpos();
         buffer.putInt(0);
@@ -2330,13 +2196,14 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
      * Appends the &quot;supported&quot; extension to the buffer. <B>Note:</B>
      * if overriding this method make sure you either do not append anything
      * or use the correct extension name
+     *
      * @param buffer The {@link Buffer} to append to
      * @param extras The extra extensions that are available and can be 
reported
-     * - may be {@code null}/empty
+     *               - may be {@code null}/empty
      */
     protected void appendSupportedExtension(Buffer buffer, Collection<String> 
extras) {
         buffer.putString(EXT_SUPPORTED);
-        
+
         int lenPos = buffer.wpos();
         buffer.putInt(0); // length placeholder
         // supported-attribute-mask
@@ -2355,23 +2222,24 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         buffer.putInt(0);
         // supported extensions
         buffer.putStringList(extras, false);
-        
+
         BufferUtils.updateLengthPlaceholder(buffer, lenPos);
     }
-    
+
     /**
      * Appends the &quot;supported2&quot; extension to the buffer. <B>Note:</B>
      * if overriding this method make sure you either do not append anything
      * or use the correct extension name
+     *
      * @param buffer The {@link Buffer} to append to
      * @param extras The extra extensions that are available and can be 
reported
-     * - may be {@code null}/empty
+     *               - may be {@code null}/empty
      * @see SftpConstants#EXT_SUPPORTED
      * @see <A 
HREF="https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-10";>DRAFT 
13 section 5.4</A>
      */
     protected void appendSupported2Extension(Buffer buffer, Collection<String> 
extras) {
         buffer.putString(EXT_SUPPORTED2);
-        
+
         int lenPos = buffer.wpos();
         buffer.putInt(0); // length placeholder
         // supported-attribute-mask
@@ -2406,14 +2274,14 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         send(buffer);
     }
 
-    protected void sendAttrs(Buffer buffer, int id, Map<String,?> attributes) 
throws IOException {
+    protected void sendAttrs(Buffer buffer, int id, Map<String, ?> attributes) 
throws IOException {
         buffer.putByte((byte) SSH_FXP_ATTRS);
         buffer.putInt(id);
         writeAttrs(buffer, attributes);
         send(buffer);
     }
 
-    protected void sendPath(Buffer buffer, int id, Path f, Map<String,?> 
attrs) throws IOException {
+    protected void sendPath(Buffer buffer, int id, Path f, Map<String, ?> 
attrs) throws IOException {
         buffer.putByte((byte) SSH_FXP_NAME);
         buffer.putInt(id);
         buffer.putInt(1);   // one reply
@@ -2452,9 +2320,9 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
     }
 
     /**
-     * @param id Request id
-     * @param dir The {@link DirectoryHandle}
-     * @param buffer The {@link Buffer} to write the results
+     * @param id      Request id
+     * @param dir     The {@link DirectoryHandle}
+     * @param buffer  The {@link Buffer} to write the results
      * @param maxSize Max. buffer size
      * @return Number of written entries
      * @throws IOException If failed to generate an entry
@@ -2476,26 +2344,26 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
 
             nb++;
         }
-        
+
         return nb;
     }
 
     /**
-     * @param id Request id
-     * @param dir The {@link DirectoryHandle}
-     * @param buffer The {@link Buffer} to write the results
-     * @param index Zero-based index of the entry to be written
-     * @param f The entry {@link Path}
+     * @param id        Request id
+     * @param dir       The {@link DirectoryHandle}
+     * @param buffer    The {@link Buffer} to write the results
+     * @param index     Zero-based index of the entry to be written
+     * @param f         The entry {@link Path}
      * @param shortName The entry short name
-     * @param options The {@link LinkOption}s to use for querying the entry-s 
attributes
+     * @param options   The {@link LinkOption}s to use for querying the 
entry-s attributes
      * @throws IOException If failed to generate the entry data
      */
-    protected void writeDirEntry(int id, DirectoryHandle dir, Buffer buffer, 
int index, Path f, String shortName, LinkOption ... options) throws IOException 
{
-        Map<String,?> attrs = resolveFileAttributes(f, SSH_FILEXFER_ATTR_ALL, 
options);
+    protected void writeDirEntry(int id, DirectoryHandle dir, Buffer buffer, 
int index, Path f, String shortName, LinkOption... options) throws IOException {
+        Map<String, ?> attrs = resolveFileAttributes(f, SSH_FILEXFER_ATTR_ALL, 
options);
 
         buffer.putString(shortName);
         if (version == SFTP_V3) {
-            String  longName = getLongName(f, options);
+            String longName = getLongName(f, options);
             buffer.putString(longName);
             if (log.isTraceEnabled()) {
                 log.trace("writeDirEntry(id=" + id + ")[" + index + "] - " + 
shortName + " [" + longName + "]: " + attrs);
@@ -2505,15 +2373,15 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
                 log.trace("writeDirEntry(id=" + id + ")[" + index + "] - " + 
shortName + ": " + attrs);
             }
         }
-        
+
         writeAttrs(buffer, attrs);
     }
 
-    protected String getLongName(Path f, LinkOption ... options) throws 
IOException {
+    protected String getLongName(Path f, LinkOption... options) throws 
IOException {
         return getLongName(f, true, options);
     }
 
-    private String getLongName(Path f, boolean sendAttrs, LinkOption ... 
options) throws IOException {
+    private String getLongName(Path f, boolean sendAttrs, LinkOption... 
options) throws IOException {
         Map<String, Object> attributes;
         if (sendAttrs) {
             attributes = getAttributes(f, options);
@@ -2523,7 +2391,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         return getLongName(f, attributes);
     }
 
-    private String getLongName(Path f, Map<String,?> attributes) throws 
IOException {
+    private String getLongName(Path f, Map<String, ?> attributes) throws 
IOException {
         String username;
         if (attributes.containsKey("owner")) {
             username = Objects.toString(attributes.get("owner"));
@@ -2565,13 +2433,12 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
             perms = EnumSet.noneOf(PosixFilePermission.class);
         }
 
-        return (getBool(isDirectory) ? "d" :
-                (getBool(isLink) ? "l" : "-"))
-                    + PosixFilePermissions.toString(perms) + "  "
-                    + (attributes.containsKey("nlink") ? 
attributes.get("nlink") : "1")
-                    + " " + username + " " + group + " " + lengthString + " "
-                    + getUnixDate((FileTime) 
attributes.get("lastModifiedTime"))
-                    + " " + getShortName(f);
+        return (SftpHelper.getBool(isDirectory) ? "d" : 
(SftpHelper.getBool(isLink) ? "l" : "-"))
+                + PosixFilePermissions.toString(perms) + "  "
+                + (attributes.containsKey("nlink") ? attributes.get("nlink") : 
"1")
+                + " " + username + " " + group + " " + lengthString + " "
+                + UnixDateFormat.getUnixDate((FileTime) 
attributes.get("lastModifiedTime"))
+                + " " + getShortName(f);
     }
 
     protected String getShortName(Path f) throws IOException {
@@ -2612,49 +2479,7 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         }
     }
 
-    protected int attributesToPermissions(boolean isReg, boolean isDir, 
boolean isLnk, Collection<PosixFilePermission> perms) {
-        int pf = 0;
-        if (perms != null) {
-            for (PosixFilePermission p : perms) {
-                switch (p) {
-                    case OWNER_READ:
-                        pf |= S_IRUSR;
-                        break;
-                    case OWNER_WRITE:
-                        pf |= S_IWUSR;
-                        break;
-                    case OWNER_EXECUTE:
-                        pf |= S_IXUSR;
-                        break;
-                    case GROUP_READ:
-                        pf |= S_IRGRP;
-                        break;
-                    case GROUP_WRITE:
-                        pf |= S_IWGRP;
-                        break;
-                    case GROUP_EXECUTE:
-                        pf |= S_IXGRP;
-                        break;
-                    case OTHERS_READ:
-                        pf |= S_IROTH;
-                        break;
-                    case OTHERS_WRITE:
-                        pf |= S_IWOTH;
-                        break;
-                    case OTHERS_EXECUTE:
-                        pf |= S_IXOTH;
-                        break;
-                    default: // ignored
-                }
-            }
-        }
-        pf |= isReg ? S_IFREG : 0;
-        pf |= isDir ? S_IFDIR : 0;
-        pf |= isLnk ? S_IFLNK : 0;
-        return pf;
-    }
-
-    protected Map<String, Object> resolveFileAttributes(Path file, int flags, 
LinkOption ... options) throws IOException {
+    protected Map<String, Object> resolveFileAttributes(Path file, int flags, 
LinkOption... options) throws IOException {
         Boolean status = IoUtils.checkFileExists(file, options);
         if (status == null) {
             return handleUnknownStatusFileAttributes(file, flags, options);
@@ -2665,98 +2490,16 @@ public class SftpSubsystem extends AbstractLoggingBean 
implements Command, Runna
         }
     }
 
-    protected void writeAttrs(Buffer buffer, Map<String,?> attributes) throws 
IOException {
-        boolean isReg = getBool((Boolean) attributes.get("isRegularFile"));
-        boolean isDir = getBool((Boolean) attributes.get("isDirectory"));
-        boolean isLnk = getBool((Boolean) attributes.get("isSymbolicLink"));
-        @SuppressWarnings("unchecked")
-        Collection<PosixFilePermission

<TRUNCATED>

Reply via email to