You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gg...@apache.org on 2019/03/31 15:39:31 UTC

[commons-vfs] branch master updated: [VFS-497] Ported filters from Commons IO #9.

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-vfs.git


The following commit(s) were added to refs/heads/master by this push:
     new 6332c76  [VFS-497] Ported filters from Commons IO #9.
6332c76 is described below

commit 6332c76779773ae8d88986488d8d63dd99654bdf
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Sun Mar 31 11:39:22 2019 -0400

    [VFS-497] Ported filters from Commons IO #9.
    
    Patch from Michael Schnell adapted to different folder names. Also clean
    ups like removing extra generics in object creation not needed since
    Java 7.
---
 .../vfs2/example/filter/AgeFileFilterExample.java  |  51 +++
 .../example/filter/CanReadFileFilterExample.java   |  76 ++++
 .../example/filter/CanWriteFileFilterExample.java  |  65 ++++
 .../example/filter/DirectoryFileFilterExample.java |  46 +++
 .../example/filter/EmptyFileFilterExample.java     |  62 ++++
 .../vfs2/example/filter/FileFileFilterExample.java |  46 +++
 .../example/filter/HiddenFileFilterExample.java    |  62 ++++
 .../vfs2/example/filter/NameFileFilterExample.java |  47 +++
 .../example/filter/PrefixFileFilterExample.java    |  47 +++
 .../example/filter/RegexFileFilterExample.java     |  48 +++
 .../vfs2/example/filter/SizeFileFilterExample.java |  49 +++
 .../example/filter/SuffixFileFilterExample.java    |  47 +++
 .../example/filter/WildcardFileFilterExample.java  |  48 +++
 .../apache/commons/vfs2/filter/AgeFileFilter.java  | 211 +++++++++++
 .../apache/commons/vfs2/filter/AndFileFilter.java  | 141 ++++++++
 .../commons/vfs2/filter/CanReadFileFilter.java     | 106 ++++++
 .../commons/vfs2/filter/CanWriteFileFilter.java    | 106 ++++++
 .../commons/vfs2/filter/ConditionalFileFilter.java |  67 ++++
 .../commons/vfs2/filter/DirectoryFileFilter.java   |  76 ++++
 .../commons/vfs2/filter/EmptyFileFilter.java       | 109 ++++++
 .../commons/vfs2/filter/FalseFileFilter.java       |  58 +++
 .../apache/commons/vfs2/filter/FileFileFilter.java |  74 ++++
 .../commons/vfs2/filter/HiddenFileFilter.java      |  94 +++++
 .../org/apache/commons/vfs2/filter/IOCase.java     | 264 ++++++++++++++
 .../apache/commons/vfs2/filter/NameFileFilter.java | 153 ++++++++
 .../apache/commons/vfs2/filter/NotFileFilter.java  |  74 ++++
 .../apache/commons/vfs2/filter/OrFileFilter.java   | 138 ++++++++
 .../commons/vfs2/filter/PrefixFileFilter.java      | 153 ++++++++
 .../commons/vfs2/filter/RegexFileFilter.java       | 136 ++++++++
 .../apache/commons/vfs2/filter/SizeFileFilter.java | 131 +++++++
 .../commons/vfs2/filter/SizeRangeFileFilter.java   |  53 +++
 .../commons/vfs2/filter/SuffixFileFilter.java      | 151 ++++++++
 .../apache/commons/vfs2/filter/TrueFileFilter.java |  58 +++
 .../commons/vfs2/filter/WildcardFileFilter.java    | 312 +++++++++++++++++
 .../commons/vfs2/impl/DefaultFileMonitor.java      |   2 +-
 .../vfs2/impl/DefaultFileSystemManager.java        |   4 +-
 .../apache/commons/vfs2/provider/UriParser.java    |   4 +-
 .../commons/vfs2/provider/ftp/FtpFileObject.java   |   2 +-
 .../vfs2/provider/sftp/SftpClientFactory.java      |   8 +-
 .../provider/sftp/SftpFileSystemConfigBuilder.java |   4 +-
 .../apache/commons/vfs2/util/PosixPermissions.java |   2 +-
 .../commons/vfs2/cache/NullFilesCacheTests.java    |   4 +-
 .../commons/vfs2/filter/AgeFileFilterTest.java     | 209 +++++++++++
 .../commons/vfs2/filter/AndFileFilterTest.java     | 184 ++++++++++
 .../apache/commons/vfs2/filter/BaseFilterTest.java | 387 +++++++++++++++++++++
 .../commons/vfs2/filter/CanReadFileFilterTest.java | 166 +++++++++
 .../vfs2/filter/CanWriteFileFilterTest.java        | 151 ++++++++
 .../vfs2/filter/DirectoryAndFileFilterTest.java    | 161 +++++++++
 .../commons/vfs2/filter/EmptyFileFilterTest.java   | 165 +++++++++
 .../commons/vfs2/filter/HiddenFileFilterTest.java  | 144 ++++++++
 .../commons/vfs2/filter/NameFileFilterTest.java    | 128 +++++++
 .../commons/vfs2/filter/NotFileFilterTest.java     |  42 +++
 .../commons/vfs2/filter/OrFileFilterTest.java      | 182 ++++++++++
 .../commons/vfs2/filter/PrefixFileFilterTest.java  | 127 +++++++
 .../vfs2/filter/RegexFileFilterTestCase.java       | 112 ++++++
 .../commons/vfs2/filter/SizeFileFilterTest.java    | 207 +++++++++++
 .../commons/vfs2/filter/SuffixFileFilterTest.java  | 128 +++++++
 .../vfs2/filter/WildcardFileFilterTest.java        | 172 +++++++++
 .../commons/vfs2/provider/UriParserTestCase.java   |   4 +-
 .../provider/ram/test/CustomRamProviderTest.java   |   4 +-
 .../zip/ZipProviderWithCharsetNullTestCase.java    |   6 +-
 .../zip/ZipProviderWithCharsetTestCase.java        |   6 +-
 .../vfs2/test/AbstractProviderTestCase.java        |   2 +-
 .../commons/vfs2/test/AbstractTestSuite.java       |   8 +-
 src/changes/changes.xml                            |   3 +
 65 files changed, 6057 insertions(+), 30 deletions(-)

diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/AgeFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/AgeFileFilterExample.java
new file mode 100644
index 0000000..e10b561
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/AgeFileFilterExample.java
@@ -0,0 +1,51 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.AgeFileFilter;
+
+/**
+ * Example for using {@link AgeFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class AgeFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        FileSystemManager fsManager = VFS.getManager();
+        FileObject dir = fsManager.toFileObject(new File("."));
+
+        // We are interested in files older than one day
+        long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
+        AgeFileFilter filter = new AgeFileFilter(cutoff);
+
+        FileObject[] files = dir.findFiles(new FileFilterSelector(filter));
+        for (int i = 0; i < files.length; i++) {
+            System.out.println(files[i]);
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
+
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/CanReadFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/CanReadFileFilterExample.java
new file mode 100644
index 0000000..8aac7a9
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/CanReadFileFilterExample.java
@@ -0,0 +1,76 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.CanReadFileFilter;
+
+/**
+ * Example for using {@link CanReadFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class CanReadFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, showing how to print out a list of the current directory's
+        // readable files:
+        {
+            System.out.println("---CAN_READ---");
+            FileSystemManager fsManager = VFS.getManager();
+            FileObject dir = fsManager.toFileObject(new File("."));
+            FileObject[] files = dir.findFiles(new FileFilterSelector(CanReadFileFilter.CAN_READ));
+            for (int i = 0; i < files.length; i++) {
+                System.out.println(files[i]);
+            }
+        }
+
+        // Example, showing how to print out a list of the current directory's
+        // un-readable files:
+        {
+            System.out.println("---CANNOT_READ---");
+            FileSystemManager fsManager = VFS.getManager();
+            FileObject dir = fsManager.toFileObject(new File("."));
+            FileObject[] files = dir
+                    .findFiles(new FileFilterSelector(CanReadFileFilter.CANNOT_READ));
+            for (int i = 0; i < files.length; i++) {
+                System.out.println(files[i]);
+            }
+        }
+
+        // Example, showing how to print out a list of the current directory's
+        // read-only files:
+        {
+            System.out.println("---READ_ONLY---");
+            FileSystemManager fsManager = VFS.getManager();
+            FileObject dir = fsManager.toFileObject(new File("."));
+            FileObject[] files = dir.findFiles(new FileFilterSelector(CanReadFileFilter.READ_ONLY));
+            for (int i = 0; i < files.length; i++) {
+                System.out.println(files[i]);
+            }
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
+
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/CanWriteFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/CanWriteFileFilterExample.java
new file mode 100644
index 0000000..13200ef
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/CanWriteFileFilterExample.java
@@ -0,0 +1,65 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.CanWriteFileFilter;
+
+/**
+ * Example for using {@link CanWriteFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class CanWriteFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, showing how to print out a list of the current directory's
+        // writable files:
+        {
+            System.out.println("---CAN_WRITE---");
+            FileSystemManager fsManager = VFS.getManager();
+            FileObject dir = fsManager.toFileObject(new File("."));
+            FileObject[] files = dir
+                    .findFiles(new FileFilterSelector(CanWriteFileFilter.CAN_WRITE));
+            for (int i = 0; i < files.length; i++) {
+                System.out.println(files[i]);
+            }
+        }
+
+        // Example, showing how to print out a list of the current directory's
+        // un-writable files:
+        {
+            System.out.println("---CANNOT_WRITE---");
+            FileSystemManager fsManager = VFS.getManager();
+            FileObject dir = fsManager.toFileObject(new File("."));
+            FileObject[] files = dir.findFiles(new FileFilterSelector(
+                    CanWriteFileFilter.CANNOT_WRITE));
+            for (int i = 0; i < files.length; i++) {
+                System.out.println(files[i]);
+            }
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
+
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/DirectoryFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/DirectoryFileFilterExample.java
new file mode 100644
index 0000000..425e217
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/DirectoryFileFilterExample.java
@@ -0,0 +1,46 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.DirectoryFileFilter;
+
+/**
+ * Example for using {@link DirectoryFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class DirectoryFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, how to print out a list of the current directory's
+        // subdirectories
+        FileSystemManager fsManager = VFS.getManager();
+        FileObject dir = fsManager.toFileObject(new File("."));
+        FileObject[] files = dir.findFiles(new FileFilterSelector(DirectoryFileFilter.DIRECTORY));
+        for (int i = 0; i < files.length; i++) {
+            System.out.println(files[i]);
+        }
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/EmptyFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/EmptyFileFilterExample.java
new file mode 100644
index 0000000..ecec8e2
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/EmptyFileFilterExample.java
@@ -0,0 +1,62 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.EmptyFileFilter;
+
+/**
+ * Example for using {@link EmptyFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class EmptyFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, showing how to print out a list of the current directory's
+        // empty files/directories
+        {
+            System.out.println("---EMPTY---");
+            FileSystemManager fsManager = VFS.getManager();
+            FileObject dir = fsManager.toFileObject(new File("."));
+            FileObject[] files = dir.findFiles(new FileFilterSelector(EmptyFileFilter.EMPTY));
+            for (int i = 0; i < files.length; i++) {
+                System.out.println(files[i]);
+            }
+        }
+
+        // Example, showing how to print out a list of the current directory's
+        // non-empty files/directories
+        {
+            System.out.println("---NOT_EMPTY---");
+            FileSystemManager fsManager = VFS.getManager();
+            FileObject dir = fsManager.toFileObject(new File("."));
+            FileObject[] files = dir.findFiles(new FileFilterSelector(EmptyFileFilter.NOT_EMPTY));
+            for (int i = 0; i < files.length; i++) {
+                System.out.println(files[i]);
+            }
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/FileFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/FileFileFilterExample.java
new file mode 100644
index 0000000..e484857
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/FileFileFilterExample.java
@@ -0,0 +1,46 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.FileFileFilter;
+
+/**
+ * Example for using {@link FileFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class FileFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, how to print out a list of the real files within the current
+        // directory
+        FileSystemManager fsManager = VFS.getManager();
+        FileObject dir = fsManager.toFileObject(new File("."));
+        FileObject[] files = dir.findFiles(new FileFilterSelector(FileFileFilter.FILE));
+        for (int i = 0; i < files.length; i++) {
+            System.out.println(files[i]);
+        }
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/HiddenFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/HiddenFileFilterExample.java
new file mode 100644
index 0000000..ff9a960
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/HiddenFileFilterExample.java
@@ -0,0 +1,62 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.HiddenFileFilter;
+
+/**
+ * Example for using {@link HiddenFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class HiddenFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, showing how to print out a list of the current directory's
+        // hidden files
+        {
+            System.out.println("---HIDDEN---");
+            FileSystemManager fsManager = VFS.getManager();
+            FileObject dir = fsManager.toFileObject(new File("."));
+            FileObject[] files = dir.findFiles(new FileFilterSelector(HiddenFileFilter.HIDDEN));
+            for (int i = 0; i < files.length; i++) {
+                System.out.println(files[i]);
+            }
+        }
+
+        // Example, showing how to print out a list of the current directory's
+        // visible (i.e. not hidden) files
+        {
+            System.out.println("---VISIBLE---");
+            FileSystemManager fsManager = VFS.getManager();
+            FileObject dir = fsManager.toFileObject(new File("."));
+            FileObject[] files = dir.findFiles(new FileFilterSelector(HiddenFileFilter.VISIBLE));
+            for (int i = 0; i < files.length; i++) {
+                System.out.println(files[i]);
+            }
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/NameFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/NameFileFilterExample.java
new file mode 100644
index 0000000..b9616c0
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/NameFileFilterExample.java
@@ -0,0 +1,47 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.NameFileFilter;
+
+/**
+ * Example for using {@link NameFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class NameFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, to print all files and directories in the current directory
+        // whose name is Test
+        FileSystemManager fsManager = VFS.getManager();
+        FileObject dir = fsManager.toFileObject(new File("."));
+        FileObject[] files = dir.findFiles(new FileFilterSelector(new NameFileFilter("Test")));
+        for (int i = 0; i < files.length; i++) {
+            System.out.println(files[i]);
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/PrefixFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/PrefixFileFilterExample.java
new file mode 100644
index 0000000..8983f83
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/PrefixFileFilterExample.java
@@ -0,0 +1,47 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.PrefixFileFilter;
+
+/**
+ * Example for using {@link PrefixFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class PrefixFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, to print all files and directories in the current directory
+        // whose name starts with a <code>.</code>
+        FileSystemManager fsManager = VFS.getManager();
+        FileObject dir = fsManager.toFileObject(new File("."));
+        FileObject[] files = dir.findFiles(new FileFilterSelector(new PrefixFileFilter(".")));
+        for (int i = 0; i < files.length; i++) {
+            System.out.println(files[i]);
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/RegexFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/RegexFileFilterExample.java
new file mode 100644
index 0000000..c7169fd
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/RegexFileFilterExample.java
@@ -0,0 +1,48 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.RegexFileFilter;
+
+/**
+ * Example for using {@link RegexFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class RegexFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, to retrieve and print all java files where the name matched
+        // the regular expression in the current directory
+        FileSystemManager fsManager = VFS.getManager();
+        FileObject dir = fsManager.toFileObject(new File("."));
+        FileObject[] files = dir.findFiles(new FileFilterSelector(new RegexFileFilter(
+                "ˆ.*[tT]est(-\\d+)?\\.java$")));
+        for (int i = 0; i < files.length; i++) {
+            System.out.println(files[i]);
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/SizeFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/SizeFileFilterExample.java
new file mode 100644
index 0000000..0ddda99
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/SizeFileFilterExample.java
@@ -0,0 +1,49 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.SizeFileFilter;
+
+/**
+ * Example for using {@link SizeFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class SizeFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, to print all files and directories in the current directory
+        // whose size is greater than 1 MB
+        FileSystemManager fsManager = VFS.getManager();
+        FileObject dir = fsManager.toFileObject(new File("."));
+        SizeFileFilter filter = new SizeFileFilter(1024 * 1024);
+        FileObject[] files = dir.findFiles(new FileFilterSelector(filter));
+        for (int i = 0; i < files.length; i++) {
+            System.out.println(files[i]);
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
+
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/SuffixFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/SuffixFileFilterExample.java
new file mode 100644
index 0000000..401e8ec
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/SuffixFileFilterExample.java
@@ -0,0 +1,47 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.SuffixFileFilter;
+
+/**
+ * Example for using {@link SuffixFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class SuffixFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, to retrieve and print all *.java files in the current
+        // directory
+        FileSystemManager fsManager = VFS.getManager();
+        FileObject dir = fsManager.toFileObject(new File("."));
+        FileObject[] files = dir.findFiles(new FileFilterSelector(new SuffixFileFilter(".java")));
+        for (int i = 0; i < files.length; i++) {
+            System.out.println(files[i]);
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/WildcardFileFilterExample.java b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/WildcardFileFilterExample.java
new file mode 100644
index 0000000..ca5ea95
--- /dev/null
+++ b/commons-vfs2-examples/src/main/java/org/apache/commons/vfs2/example/filter/WildcardFileFilterExample.java
@@ -0,0 +1,48 @@
+/*
+ * 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.commons.vfs2.example.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.apache.commons.vfs2.filter.WildcardFileFilter;
+
+/**
+ * Example for using {@link WildcardFileFilter}.
+ */
+// CHECKSTYLE:OFF Example code
+public class WildcardFileFilterExample {
+
+    public static void main(String[] args) throws Exception {
+
+        // Example, to retrieve and print all java files that have the
+        // expression test in the name in the current directory
+        FileSystemManager fsManager = VFS.getManager();
+        FileObject dir = fsManager.toFileObject(new File("."));
+        FileObject[] files = dir.findFiles(new FileFilterSelector(new WildcardFileFilter(
+                "*test*.java")));
+        for (int i = 0; i < files.length; i++) {
+            System.out.println(files[i]);
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/AgeFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/AgeFileFilter.java
new file mode 100644
index 0000000..205bfdc
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/AgeFileFilter.java
@@ -0,0 +1,211 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import org.apache.commons.vfs2.FileContent;
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+
+/**
+ * Filters files based on a cutoff time, can filter either newer files or files
+ * equal to or older.
+ * <p>
+ * For example, to print all files and directories in the current directory
+ * older than one day:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * // We are interested in files older than one day
+ * long cutoff = System.currentTimeMillis() - (24 * 60 * 60 * 1000);
+ * AgeFileFilter filter = new AgeFileFilter(cutoff);
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(filter));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class AgeFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Whether the files accepted will be older or newer. */
+    private final boolean acceptOlder;
+
+    /** The cutoff time threshold. */
+    private final long cutoff;
+
+    /**
+     * Tests if the specified <code>File</code> is newer than the specified time
+     * reference.
+     * 
+     * @param fileObject
+     *            the <code>File</code> of which the modification date must be
+     *            compared, must not be {@code null}
+     * @param timeMillis
+     *            the time reference measured in milliseconds since the epoch
+     *            (00:00:00 GMT, January 1, 1970)
+     * @return true if the <code>File</code> exists and has been modified after
+     *         the given time reference.
+     * @throws IllegalArgumentException
+     *             if the file is {@code null}
+     */
+    private static boolean isFileNewer(final FileObject fileObject, final long timeMillis) {
+        if (fileObject == null) {
+            throw new IllegalArgumentException("No specified file");
+        }
+        try {
+            if (!fileObject.exists()) {
+                return false;
+            }
+            final FileContent content = fileObject.getContent();
+            try {
+                final long lastModified = content.getLastModifiedTime();
+                return lastModified > timeMillis;
+            } finally {
+                content.close();
+            }
+        } catch (final FileSystemException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Constructs a new age file filter for files older than (at or before) a
+     * certain cutoff date.
+     * 
+     * @param cutoffDate
+     *            the threshold age of the files
+     */
+    public AgeFileFilter(final Date cutoffDate) {
+        this(cutoffDate, true);
+    }
+
+    /**
+     * Constructs a new age file filter for files on any one side of a certain
+     * cutoff date.
+     * 
+     * @param cutoffDate
+     *            the threshold age of the files
+     * @param acceptOlder
+     *            if true, older files (at or before the cutoff) are accepted,
+     *            else newer ones (after the cutoff).
+     */
+    public AgeFileFilter(final Date cutoffDate, final boolean acceptOlder) {
+        this(cutoffDate.getTime(), acceptOlder);
+    }
+
+    /**
+     * Constructs a new age file filter for files older than (at or before) a
+     * certain File (whose last modification time will be used as reference).
+     * 
+     * @param cutoffReference
+     *            the file whose last modification time is usesd as the
+     *            threshold age of the files
+     * 
+     * @throws FileSystemException
+     *             Error reading the last modification time from the reference
+     *             file object.
+     */
+    public AgeFileFilter(final FileObject cutoffReference) throws FileSystemException {
+        this(cutoffReference, true);
+    }
+
+    /**
+     * Constructs a new age file filter for files on any one side of a certain
+     * File (whose last modification time will be used as reference).
+     * 
+     * @param cutoffReference
+     *            the file whose last modification time is usesd as the
+     *            threshold age of the files
+     * @param acceptOlder
+     *            if true, older files (at or before the cutoff) are accepted,
+     *            else newer ones (after the cutoff).
+     * 
+     * @throws FileSystemException
+     *             Error reading the last modification time from the reference
+     *             file object.
+     */
+    public AgeFileFilter(final FileObject cutoffReference, final boolean acceptOlder)
+            throws FileSystemException {
+        this(cutoffReference.getContent().getLastModifiedTime(), acceptOlder);
+    }
+
+    /**
+     * Constructs a new age file filter for files equal to or older than a
+     * certain cutoff.
+     * 
+     * @param cutoff
+     *            the threshold age of the files
+     */
+    public AgeFileFilter(final long cutoff) {
+        this(cutoff, true);
+    }
+
+    /**
+     * Constructs a new age file filter for files on any one side of a certain
+     * cutoff.
+     * 
+     * @param cutoff
+     *            the threshold age of the files
+     * @param acceptOlder
+     *            if true, older files (at or before the cutoff) are accepted,
+     *            else newer ones (after the cutoff).
+     */
+    public AgeFileFilter(final long cutoff, final boolean acceptOlder) {
+        this.acceptOlder = acceptOlder;
+        this.cutoff = cutoff;
+    }
+
+    /**
+     * Checks to see if the last modification of the file matches cutoff
+     * favorably.
+     * <p>
+     * If last modification time equals cutoff and newer files are required,
+     * file <b>IS NOT</b> selected. If last modification time equals cutoff and
+     * older files are required, file <b>IS</b> selected.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return true if the filename matches
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        final boolean newer = isFileNewer(fileInfo.getFile(), cutoff);
+        return acceptOlder ? !newer : newer;
+    }
+
+    /**
+     * Provide a String representaion of this file filter.
+     * 
+     * @return a String representaion
+     */
+    @Override
+    public String toString() {
+        final String condition = acceptOlder ? "<=" : ">";
+        return super.toString() + "(" + condition + cutoff + ")";
+    }
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/AndFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/AndFileFilter.java
new file mode 100644
index 0000000..d3aa316
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/AndFileFilter.java
@@ -0,0 +1,141 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * A filter providing conditional AND logic across a list of file filters. This
+ * filter returns {@code true} if all filters in the list return {@code true}.
+ * Otherwise, it returns {@code false}. Checking of the file filter list stops
+ * when the first filter returns {@code false}.
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class AndFileFilter implements FileFilter, ConditionalFileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** The list of file filters. */
+    private final List<FileFilter> fileFilters;
+
+    /**
+     * Default constructor.
+     */
+    public AndFileFilter() {
+        this.fileFilters = new ArrayList<>();
+    }
+
+    /**
+     * Constructs a new file filter that ANDs the result of other filters.
+     * 
+     * @param filters
+     *            array of filters, must not be null or empty
+     */
+    public AndFileFilter(final FileFilter... filters) {
+        if (filters == null || filters.length == 0) {
+            throw new IllegalArgumentException("The filters must not be null or empty");
+        }
+        for (final FileFilter filter : filters) {
+            if (filter == null) {
+                throw new IllegalArgumentException("Null filters are not allowed");
+            }
+        }
+        this.fileFilters = new ArrayList<>(Arrays.asList(filters));
+    }
+
+    /**
+     * Constructs a new instance of <code>AndFileFilter</code> with the
+     * specified list of filters.
+     * 
+     * @param fileFilters
+     *            a List of FileFilter instances, copied, null ignored
+     */
+    public AndFileFilter(final List<FileFilter> fileFilters) {
+        if (fileFilters == null) {
+            this.fileFilters = new ArrayList<>();
+        } else {
+            this.fileFilters = new ArrayList<>(fileFilters);
+        }
+    }
+
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        if (this.fileFilters.isEmpty()) {
+            return false;
+        }
+        for (final FileFilter fileFilter : fileFilters) {
+            if (!fileFilter.accept(fileInfo)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void addFileFilter(final FileFilter fileFilter) {
+        this.fileFilters.add(fileFilter);
+    }
+
+    @Override
+    public List<FileFilter> getFileFilters() {
+        return Collections.unmodifiableList(this.fileFilters);
+    }
+
+    @Override
+    public boolean removeFileFilter(final FileFilter fileFilter) {
+        return this.fileFilters.remove(fileFilter);
+    }
+
+    @Override
+    public void setFileFilters(final List<FileFilter> fileFilters) {
+        this.fileFilters.clear();
+        this.fileFilters.addAll(fileFilters);
+    }
+
+    /**
+     * Provide a String representation of this file filter.
+     * 
+     * @return a String representation
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder();
+        buffer.append(super.toString());
+        buffer.append("(");
+        if (fileFilters != null) {
+            for (int i = 0; i < fileFilters.size(); i++) {
+                if (i > 0) {
+                    buffer.append(",");
+                }
+                final Object filter = fileFilters.get(i);
+                buffer.append(filter == null ? "null" : filter.toString());
+            }
+        }
+        buffer.append(")");
+        return buffer.toString();
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/CanReadFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/CanReadFileFilter.java
new file mode 100644
index 0000000..bb0d1f3
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/CanReadFileFilter.java
@@ -0,0 +1,106 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+
+/**
+ * This filter accepts <code>File</code>s that can be read.
+ * <p>
+ * Example, showing how to print out a list of the current directory's
+ * <i>readable</i> files:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(CanReadFileFilter.CAN_READ));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * <p>
+ * Example, showing how to print out a list of the current directory's
+ * <i>un-readable</i> files:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(CanReadFileFilter.CANNOT_READ));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * <p>
+ * Example, showing how to print out a list of the current directory's
+ * <i>read-only</i> files:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(CanReadFileFilter.READ_ONLY));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class CanReadFileFilter implements FileFilter, Serializable {
+
+    /** Singleton instance of <i>readable</i> filter. */
+    public static final FileFilter CAN_READ = new CanReadFileFilter();
+
+    /** Singleton instance of not <i>readable</i> filter. */
+    public static final FileFilter CANNOT_READ = new NotFileFilter(CAN_READ);
+
+    /** Singleton instance of <i>read-only</i> filter. */
+    public static final FileFilter READ_ONLY = new AndFileFilter(CAN_READ,
+            CanWriteFileFilter.CANNOT_WRITE);
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Restrictive constructor.
+     */
+    protected CanReadFileFilter() {
+    }
+
+    /**
+     * Checks to see if the file can be read.
+     * 
+     * @param fileInfo
+     *            the File to check.
+     * 
+     * @return {@code true} if the file can be read, otherwise {@code false}.
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        try {
+            return fileInfo.getFile().isReadable();
+        } catch (final FileSystemException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/CanWriteFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/CanWriteFileFilter.java
new file mode 100644
index 0000000..ea1bfcf
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/CanWriteFileFilter.java
@@ -0,0 +1,106 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.Capability;
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystem;
+import org.apache.commons.vfs2.FileSystemException;
+
+/**
+ * This filter accepts <code>File</code>s that can be written to.
+ * <p>
+ * Example, showing how to print out a list of the current directory's
+ * <i>writable</i> files:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(CanWriteFileFilter.CAN_WRITE));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * <p>
+ * Example, showing how to print out a list of the current directory's
+ * <i>un-writable</i> files:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(CanWriteFileFilter.CANNOT_WRITE));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * <p>
+ * <b>N.B.</b> For read-only files, use <code>CanReadFileFilter.READ_ONLY</code>.
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class CanWriteFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Singleton instance of <i>writable</i> filter. */
+    public static final FileFilter CAN_WRITE = new CanWriteFileFilter();
+
+    /** Singleton instance of not <i>writable</i> filter. */
+    public static final FileFilter CANNOT_WRITE = new NotFileFilter(CAN_WRITE);
+
+    /**
+     * Restrictive constructor.
+     */
+    protected CanWriteFileFilter() {
+    }
+
+    /**
+     * Checks to see if the file can be written to.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return {@code true} if the file can be written to, otherwise
+     *         {@code false}.
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        try {
+            final FileSystem fileSystem = fileInfo.getFile().getFileSystem();
+            if (fileInfo.getFile().exists()) {
+                if (!fileSystem.hasCapability(Capability.WRITE_CONTENT)) {
+                    return false;
+                }
+                return fileInfo.getFile().isWriteable();
+            } else {
+                if (!fileSystem.hasCapability(Capability.CREATE)) {
+                    return false;
+                }
+                return fileInfo.getFile().getParent().isWriteable();
+            }
+        } catch (final FileSystemException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/ConditionalFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/ConditionalFileFilter.java
new file mode 100644
index 0000000..dfb0a55
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/ConditionalFileFilter.java
@@ -0,0 +1,67 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.util.List;
+
+import org.apache.commons.vfs2.FileFilter;
+
+/**
+ * Defines operations for conditional file filters.
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public interface ConditionalFileFilter {
+
+    /**
+     * Adds the specified file filter to the list of file filters at the end of
+     * the list.
+     * 
+     * @param fileFilter
+     *            the filter to be added
+     */
+    void addFileFilter(FileFilter fileFilter);
+
+    /**
+     * Returns this conditional file filter's list of file filters.
+     * 
+     * @return the file filter list
+     */
+    List<FileFilter> getFileFilters();
+
+    /**
+     * Removes the specified file filter.
+     * 
+     * @param fileFilter
+     *            filter to be removed
+     * 
+     * @return {@code true} if the filter was found in the list, {@code false}
+     *         otherwise
+     */
+    boolean removeFileFilter(FileFilter fileFilter);
+
+    /**
+     * Sets the list of file filters, replacing any previously configured file
+     * filters on this filter.
+     * 
+     * @param fileFilters
+     *            the list of filters
+     */
+    void setFileFilters(List<FileFilter> fileFilters);
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/DirectoryFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/DirectoryFileFilter.java
new file mode 100644
index 0000000..a14c4c1
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/DirectoryFileFilter.java
@@ -0,0 +1,76 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileType;
+
+/**
+ * This filter accepts <code>File</code>s that are directories.
+ * <p>
+ * For example, here is how to print out a list of the current directory's sub
+ * directories:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(DirectoryFileFilter.DIRECTORY));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class DirectoryFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Singleton instance of directory filter.
+     */
+    public static final FileFilter DIRECTORY = new DirectoryFileFilter();
+
+    /**
+     * Restrictive constructor.
+     */
+    protected DirectoryFileFilter() {
+    }
+
+    /**
+     * Checks to see if the file is a directory.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return {@code true} if the file is a directory
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        try {
+            return fileInfo.getFile().getType() == FileType.FOLDER;
+        } catch (final FileSystemException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/EmptyFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/EmptyFileFilter.java
new file mode 100644
index 0000000..1b3141f
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/EmptyFileFilter.java
@@ -0,0 +1,109 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileContent;
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileType;
+
+/**
+ * This filter accepts files or directories that are empty.
+ * <p>
+ * If the <code>File</code> is a directory it checks that it contains no files.
+ * <p>
+ * Example, showing how to print out a list of the current directory's empty
+ * files/directories:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(EmptyFileFilter.EMPTY));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * <p>
+ * Example, showing how to print out a list of the current directory's non-empty
+ * files/directories:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(EmptyFileFilter.NOT_EMPTY));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class EmptyFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Singleton instance of <i>empty</i> filter. */
+    public static final FileFilter EMPTY = new EmptyFileFilter();
+
+    /** Singleton instance of <i>not-empty</i> filter. */
+    public static final FileFilter NOT_EMPTY = new NotFileFilter(EMPTY);
+
+    /**
+     * Restrictive constructor.
+     */
+    protected EmptyFileFilter() {
+    }
+
+    /**
+     * Checks to see if the file is empty. A non-existing file is also
+     * considered empty.
+     * 
+     * @param fileInfo
+     *            the file or directory to check
+     * 
+     * @return {@code true} if the file or directory is <i>empty</i>, otherwise
+     *         {@code false}.
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        final FileObject file = fileInfo.getFile();
+        try {
+            if (!file.exists()) {
+                return true;
+            }
+            if (file.getType() == FileType.FOLDER) {
+                final FileObject[] files = file.getChildren();
+                return files == null || files.length == 0;
+            }
+            final FileContent content = file.getContent();
+            try {
+                return content.getSize() == 0;
+            } finally {
+                content.close();
+            }
+        } catch (final FileSystemException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/FalseFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/FalseFileFilter.java
new file mode 100644
index 0000000..8c59b31
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/FalseFileFilter.java
@@ -0,0 +1,58 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * A file filter that always returns false.
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class FalseFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Singleton instance of false filter.
+     */
+    public static final FileFilter FALSE = new FalseFileFilter();
+
+    /**
+     * Restrictive constructor.
+     */
+    protected FalseFileFilter() {
+    }
+
+    /**
+     * Returns false.
+     * 
+     * @param fileInfo
+     *            the file to check (ignored)
+     * 
+     * @return Always {@code false}
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        return false;
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/FileFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/FileFileFilter.java
new file mode 100644
index 0000000..48fa8fa
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/FileFileFilter.java
@@ -0,0 +1,74 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileType;
+
+/**
+ * This filter accepts <code>File</code>s that are files (not directories).
+ * <p>
+ * For example, here is how to print out a list of the real files within the
+ * current directory:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(FileFileFilter.FILE));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class FileFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Singleton instance of file filter. */
+    public static final FileFilter FILE = new FileFileFilter();
+
+    /**
+     * Restrictive constructor.
+     */
+    protected FileFileFilter() {
+    }
+
+    /**
+     * Checks to see if the file is a file.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return true if the file is a file
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        try {
+            return fileInfo.getFile().getType() == FileType.FILE;
+        } catch (final FileSystemException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/HiddenFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/HiddenFileFilter.java
new file mode 100644
index 0000000..a66e151
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/HiddenFileFilter.java
@@ -0,0 +1,94 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+
+/**
+ * This filter accepts <code>File</code>s that are hidden.
+ * <p>
+ * Example, showing how to print out a list of the current directory's
+ * <i>hidden</i> files:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(HiddenFileFilter.HIDDEN));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * <p>
+ * Example, showing how to print out a list of the current directory's
+ * <i>visible</i> (i.e. not hidden) files:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(HiddenFileFilter.VISIBLE));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class HiddenFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Singleton instance of <i>hidden</i> filter. */
+    public static final FileFilter HIDDEN = new HiddenFileFilter();
+
+    /** Singleton instance of <i>visible</i> filter. */
+    public static final FileFilter VISIBLE = new NotFileFilter(HIDDEN);
+
+    /**
+     * Restrictive constructor.
+     */
+    protected HiddenFileFilter() {
+    }
+
+    /**
+     * Checks to see if the file is hidden. Non existing files won't be
+     * accepted.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return {@code true} if the file is <i>hidden</i>, otherwise
+     *         {@code false}.
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        try {
+            if (!fileInfo.getFile().exists()) {
+                return false;
+            }
+            return fileInfo.getFile().isHidden();
+        } catch (final FileSystemException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/IOCase.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/IOCase.java
new file mode 100644
index 0000000..391b305
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/IOCase.java
@@ -0,0 +1,264 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * Enumeration of IO case sensitivity.
+ * <p>
+ * Different filing systems have different rules for case-sensitivity. Windows
+ * is case-insensitive, Unix is case-sensitive.
+ * <p>
+ * This class captures that difference, providing an enumeration to control how
+ * filename comparisons should be performed. It also provides methods that use
+ * the enumeration to perform comparisons.
+ * <p>
+ * Wherever possible, you should use the <code>check</code> methods in this
+ * class to compare filenames.
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public final class IOCase implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * The constant for case insensitive regardless of operating system.
+     */
+    public static final IOCase INSENSITIVE = new IOCase("Insensitive", false);
+
+    /**
+     * The constant for case sensitive regardless of operating system.
+     */
+    public static final IOCase SENSITIVE = new IOCase("Sensitive", true);
+
+    /**
+     * The constant for case sensitivity determined by the current operating
+     * system. Windows is case-insensitive when comparing filenames, Unix is
+     * case-sensitive.
+     * <p>
+     * <strong>Note:</strong> This only caters for Windows and Unix. Other
+     * operating systems (e.g. OSX and OpenVMS) are treated as case sensitive if
+     * they use the Unix file separator and case-insensitive if they use the
+     * Windows file separator (see {@link java.io.File#separatorChar}).
+     * <p>
+     * If you derialize this constant of Windows, and deserialize on Unix, or
+     * vice versa, then the value of the case-sensitivity flag will change.
+     */
+    public static final IOCase SYSTEM = new IOCase("System", !(File.separatorChar == '\\'));
+
+    /**
+     * Factory method to create an IOCase from a name.
+     * 
+     * @param name
+     *            the name to find
+     * @return the IOCase object
+     */
+    public static IOCase forName(final String name) {
+        if (IOCase.SENSITIVE.name.equals(name)) {
+            return IOCase.SENSITIVE;
+        }
+        if (IOCase.INSENSITIVE.name.equals(name)) {
+            return IOCase.INSENSITIVE;
+        }
+        if (IOCase.SYSTEM.name.equals(name)) {
+            return IOCase.SYSTEM;
+        }
+        throw new IllegalArgumentException("Invalid IOCase name: " + name);
+    }
+
+    /** The enumeration name. */
+    private final String name;
+
+    /** The sensitivity flag. */
+    private final transient boolean sensitive;
+
+    /**
+     * Private constructor.
+     * 
+     * @param name
+     *            the name
+     * @param sensitive
+     *            the sensitivity
+     */
+    private IOCase(final String name, final boolean sensitive) {
+        this.name = name;
+        this.sensitive = sensitive;
+    }
+
+    /**
+     * Compares two strings using the case-sensitivity rule.
+     * <p>
+     * This method mimics {@link String#compareTo} but takes case-sensitivity
+     * into account.
+     * 
+     * @param str1
+     *            the first string to compare, not null
+     * @param str2
+     *            the second string to compare, not null
+     * @return true if equal using the case rules
+     */
+    public int checkCompareTo(final String str1, final String str2) {
+        if (str1 == null || str2 == null) {
+            throw new NullPointerException("The strings must not be null");
+        }
+        return sensitive ? str1.compareTo(str2) : str1.compareToIgnoreCase(str2);
+    }
+
+    /**
+     * Checks if one string ends with another using the case-sensitivity rule.
+     * <p>
+     * This method mimics {@link String#endsWith} but takes case-sensitivity
+     * into account.
+     * 
+     * @param str
+     *            the string to check, not null
+     * @param end
+     *            the end to compare against, not null
+     * @return true if equal using the case rules
+     */
+    public boolean checkEndsWith(final String str, final String end) {
+        final int endLen = end.length();
+        return str.regionMatches(!sensitive, str.length() - endLen, end, 0, endLen);
+    }
+
+    /**
+     * Compares two strings using the case-sensitivity rule.
+     * <p>
+     * This method mimics {@link String#equals} but takes case-sensitivity into
+     * account.
+     * 
+     * @param str1
+     *            the first string to compare, not null
+     * @param str2
+     *            the second string to compare, not null
+     * @return true if equal using the case rules
+     */
+    public boolean checkEquals(final String str1, final String str2) {
+        if (str1 == null || str2 == null) {
+            throw new NullPointerException("The strings must not be null");
+        }
+        return sensitive ? str1.equals(str2) : str1.equalsIgnoreCase(str2);
+    }
+
+    /**
+     * Checks if one string contains another starting at a specific index using
+     * the case-sensitivity rule.
+     * <p>
+     * This method mimics parts of {@link String#indexOf(String, int)} but takes
+     * case-sensitivity into account.
+     * 
+     * @param str
+     *            the string to check, not null
+     * @param strStartIndex
+     *            the index to start at in str
+     * @param search
+     *            the start to search for, not null
+     * @return the first index of the search String, -1 if no match or
+     *         {@code null} string input
+     * @since 2.0
+     */
+    public int checkIndexOf(final String str, final int strStartIndex, final String search) {
+        final int endIndex = str.length() - search.length();
+        if (endIndex >= strStartIndex) {
+            for (int i = strStartIndex; i <= endIndex; i++) {
+                if (checkRegionMatches(str, i, search)) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Checks if one string contains another at a specific index using the
+     * case-sensitivity rule.
+     * <p>
+     * This method mimics parts of
+     * {@link String#regionMatches(boolean, int, String, int, int)} but takes
+     * case-sensitivity into account.
+     * 
+     * @param str
+     *            the string to check, not null
+     * @param strStartIndex
+     *            the index to start at in str
+     * @param search
+     *            the start to search for, not null
+     * @return true if equal using the case rules
+     */
+    public boolean checkRegionMatches(final String str, final int strStartIndex, final String search) {
+        return str.regionMatches(!sensitive, strStartIndex, search, 0, search.length());
+    }
+
+    /**
+     * Checks if one string starts with another using the case-sensitivity rule.
+     * <p>
+     * This method mimics {@link String#startsWith(String)} but takes
+     * case-sensitivity into account.
+     * 
+     * @param str
+     *            the string to check, not null
+     * @param start
+     *            the start to compare against, not null
+     * @return true if equal using the case rules
+     */
+    public boolean checkStartsWith(final String str, final String start) {
+        return str.regionMatches(!sensitive, 0, start, 0, start.length());
+    }
+
+    /**
+     * Gets the name of the constant.
+     * 
+     * @return the name of the constant
+     */
+    public String getName() {
+        return name;
+    }
+
+    /**
+     * Does the object represent case sensitive comparison.
+     * 
+     * @return true if case sensitive
+     */
+    public boolean isCaseSensitive() {
+        return sensitive;
+    }
+
+    /**
+     * Replaces the enumeration from the stream with a real one. This ensures
+     * that the correct flag is set for SYSTEM.
+     * 
+     * @return the resolved object
+     */
+    private Object readResolve() {
+        return forName(name);
+    }
+
+    /**
+     * Gets a string describing the sensitivity.
+     * 
+     * @return a string describing the sensitivity
+     */
+    @Override
+    public String toString() {
+        return name;
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/NameFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/NameFileFilter.java
new file mode 100644
index 0000000..a7b7750
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/NameFileFilter.java
@@ -0,0 +1,153 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * Filters filenames for a certain name.
+ * <p>
+ * For example, to print all files and directories in the current directory
+ * whose name is <code>Test</code>:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(new NameFileFilter(&quot;Test&quot;)));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class NameFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Whether the comparison is case sensitive. */
+    private final IOCase caseSensitivity;
+
+    /** The file names to search for. */
+    private final List<String> names;
+
+    /**
+     * Constructs a new case-sensitive name file filter for a list of names.
+     * 
+     * @param names
+     *            the names to allow, must not be null
+     */
+    public NameFileFilter(final List<String> names) {
+        this((IOCase) null, names);
+    }
+
+    /**
+     * Constructs a new name file filter for a list of names specifying
+     * case-sensitivity.
+     * 
+     * @param caseSensitivity
+     *            how to handle case sensitivity, null means case-sensitive
+     * @param names
+     *            the names to allow, must not be null
+     */
+    public NameFileFilter(final IOCase caseSensitivity, final List<String> names) {
+        if (names == null) {
+            throw new IllegalArgumentException("The list of names must not be null");
+        }
+        this.names = new ArrayList<>(names);
+        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+    }
+
+    /**
+     * Constructs a new case-sensitive name file filter for an array of names.
+     * <p>
+     * The array is not cloned, so could be changed after constructing the
+     * instance. This would be inadvisable however.
+     * 
+     * @param names
+     *            the names to allow, must not be null
+     */
+    public NameFileFilter(final String... names) {
+        this((IOCase) null, names);
+    }
+
+    /**
+     * Constructs a new name file filter for an array of names specifying
+     * case-sensitivity.
+     * 
+     * @param caseSensitivity
+     *            how to handle case sensitivity, null means case-sensitive
+     * @param names
+     *            the names to allow, must not be null
+     */
+    public NameFileFilter(final IOCase caseSensitivity, final String... names) {
+        if (names == null) {
+            throw new IllegalArgumentException("The array of names must not be null");
+        }
+        this.names = new ArrayList<>(Arrays.asList(names));
+        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+    }
+
+    /**
+     * Checks to see if the filename matches.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return true if the filename matches
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        final String name = fileInfo.getFile().getName().getBaseName();
+        for (final String name2 : this.names) {
+            if (caseSensitivity.checkEquals(name, name2)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Provide a String representation of this file filter.
+     * 
+     * @return a String representation
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder();
+        buffer.append(super.toString());
+        buffer.append("(");
+        if (names != null) {
+            for (int i = 0; i < names.size(); i++) {
+                if (i > 0) {
+                    buffer.append(",");
+                }
+                buffer.append(names.get(i));
+            }
+        }
+        buffer.append(")");
+        return buffer.toString();
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/NotFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/NotFileFilter.java
new file mode 100644
index 0000000..d69fc24
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/NotFileFilter.java
@@ -0,0 +1,74 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * This filter produces a logical NOT of the filters specified.
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class NotFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** The filter. */
+    private final FileFilter filter;
+
+    /**
+     * Constructs a new file filter that NOTs the result of another filter.
+     * 
+     * @param filter
+     *            the filter, must not be null
+     */
+    public NotFileFilter(final FileFilter filter) {
+        if (filter == null) {
+            throw new IllegalArgumentException("The filter must not be null");
+        }
+        this.filter = filter;
+    }
+
+    /**
+     * Returns the logical NOT of the underlying filter's return value for the
+     * same File.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return {@code true} if the filter returns {@code false}
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        return !filter.accept(fileInfo);
+    }
+
+    /**
+     * Provide a String representation of this file filter.
+     * 
+     * @return a String representation
+     */
+    @Override
+    public String toString() {
+        return super.toString() + "(" + filter.toString() + ")";
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/OrFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/OrFileFilter.java
new file mode 100644
index 0000000..22d7181
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/OrFileFilter.java
@@ -0,0 +1,138 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * A {@link java.io.FileFilter} providing conditional OR logic across a list of
+ * file filters. This filter returns {@code true} if any filters in the list
+ * return {@code true}. Otherwise, it returns {@code false}. Checking of the
+ * file filter list stops when the first filter returns {@code true}.
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class OrFileFilter implements FileFilter, ConditionalFileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** The list of file filters. */
+    private final List<FileFilter> fileFilters;
+
+    /**
+     * Default constructor.
+     */
+    public OrFileFilter() {
+        this.fileFilters = new ArrayList<>();
+    }
+
+    /**
+     * Constructs a new file filter that ORs the result of other filters.
+     * 
+     * @param filters
+     *            array of filters, must not be null or empty
+     */
+    public OrFileFilter(final FileFilter... filters) {
+        if (filters == null || filters.length == 0) {
+            throw new IllegalArgumentException("The filters must not be null or empty");
+        }
+        for (final FileFilter filter : filters) {
+            if (filter == null) {
+                throw new IllegalArgumentException("Null filters are not allowed");
+            }
+        }
+        this.fileFilters = new ArrayList<>(Arrays.asList(filters));
+    }
+
+    /**
+     * Constructs a new instance of <code>OrFileFilter</code> with the specified
+     * filters.
+     * 
+     * @param fileFilters
+     *            the file filters for this filter, copied, null ignored
+     */
+    public OrFileFilter(final List<FileFilter> fileFilters) {
+        if (fileFilters == null) {
+            this.fileFilters = new ArrayList<>();
+        } else {
+            this.fileFilters = new ArrayList<>(fileFilters);
+        }
+    }
+
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        for (final FileFilter fileFilter : fileFilters) {
+            if (fileFilter.accept(fileInfo)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void addFileFilter(final FileFilter fileFilter) {
+        this.fileFilters.add(fileFilter);
+    }
+
+    @Override
+    public List<FileFilter> getFileFilters() {
+        return Collections.unmodifiableList(this.fileFilters);
+    }
+
+    @Override
+    public boolean removeFileFilter(final FileFilter fileFilter) {
+        return this.fileFilters.remove(fileFilter);
+    }
+
+    @Override
+    public void setFileFilters(final List<FileFilter> fileFilters) {
+        this.fileFilters.clear();
+        this.fileFilters.addAll(fileFilters);
+    }
+
+    /**
+     * Provide a String representation of this file filter.
+     * 
+     * @return a String representation
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder();
+        buffer.append(super.toString());
+        buffer.append("(");
+        if (fileFilters != null) {
+            for (int i = 0; i < fileFilters.size(); i++) {
+                if (i > 0) {
+                    buffer.append(",");
+                }
+                final Object filter = fileFilters.get(i);
+                buffer.append(filter == null ? "null" : filter.toString());
+            }
+        }
+        buffer.append(")");
+        return buffer.toString();
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/PrefixFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/PrefixFileFilter.java
new file mode 100644
index 0000000..23682f2
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/PrefixFileFilter.java
@@ -0,0 +1,153 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * Filters filenames for a certain prefix.
+ * <p>
+ * For example, to print all files and directories in the current directory
+ * whose name starts with a <code>.</code>:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(new PrefixFileFilter(&quot;.&quot;)));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class PrefixFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Whether the comparison is case sensitive. */
+    private final IOCase caseSensitivity;
+
+    /** The filename prefixes to search for. */
+    private final List<String> prefixes;
+
+    /**
+     * Constructs a new Prefix file filter for a list of prefixes.
+     * 
+     * @param prefixes
+     *            the prefixes to allow, must not be null
+     */
+    public PrefixFileFilter(final List<String> prefixes) {
+        this(IOCase.SENSITIVE, prefixes);
+    }
+
+    /**
+     * Constructs a new Prefix file filter for a list of prefixes specifying
+     * case-sensitivity.
+     * 
+     * @param caseSensitivity
+     *            how to handle case sensitivity, null means case-sensitive
+     * @param prefixes
+     *            the prefixes to allow, must not be null
+     */
+    public PrefixFileFilter(final IOCase caseSensitivity, final List<String> prefixes) {
+        if (prefixes == null) {
+            throw new IllegalArgumentException("The list of prefixes must not be null");
+        }
+        this.prefixes = new ArrayList<>(prefixes);
+        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+    }
+
+    /**
+     * Constructs a new Prefix file filter for any of an array of prefixes.
+     * <p>
+     * The array is not cloned, so could be changed after constructing the
+     * instance. This would be inadvisable however.
+     * 
+     * @param prefixes
+     *            the prefixes to allow, must not be null
+     */
+    public PrefixFileFilter(final String... prefixes) {
+        this(IOCase.SENSITIVE, prefixes);
+    }
+
+    /**
+     * Constructs a new Prefix file filter for any of an array of prefixes
+     * specifying case-sensitivity.
+     * 
+     * @param prefixes
+     *            the prefixes to allow, must not be null
+     * @param caseSensitivity
+     *            how to handle case sensitivity, null means case-sensitive
+     */
+    public PrefixFileFilter(final IOCase caseSensitivity, final String... prefixes) {
+        if (prefixes == null) {
+            throw new IllegalArgumentException("The array of prefixes must not be null");
+        }
+        this.prefixes = new ArrayList<>(Arrays.asList(prefixes));
+        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+    }
+
+    /**
+     * Checks to see if the filename starts with the prefix.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return true if the filename starts with one of our prefixes
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        final String name = fileInfo.getFile().getName().getBaseName();
+        for (final String prefix : this.prefixes) {
+            if (caseSensitivity.checkStartsWith(name, prefix)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Provide a String representation of this file filter.
+     * 
+     * @return a String representation
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder();
+        buffer.append(super.toString());
+        buffer.append("(");
+        if (prefixes != null) {
+            for (int i = 0; i < prefixes.size(); i++) {
+                if (i > 0) {
+                    buffer.append(",");
+                }
+                buffer.append(prefixes.get(i));
+            }
+        }
+        buffer.append(")");
+        return buffer.toString();
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/RegexFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/RegexFileFilter.java
new file mode 100644
index 0000000..a464540
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/RegexFileFilter.java
@@ -0,0 +1,136 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+import java.util.regex.Pattern;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * Filters files using supplied regular expression(s).
+ * <p/>
+ * See java.util.regex.Pattern for regex matching rules
+ * <p/>
+ * 
+ * <p/>
+ * For example, to retrieve and print all java files where the name matched the
+ * regular expression in the current directory:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(new RegexFileFilter(
+ *         &quot;ˆ.*[tT]est(-\\d+)?\\.java$&quot;)));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class RegexFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Exception message when no pattern is given in the constructor. */
+    public static final String PATTERN_IS_MISSING = "Pattern is missing";
+
+    /** The regular expression pattern that will be used to match filenames. */
+    private final Pattern pattern;
+
+    /**
+     * Construct a new regular expression filter for a compiled regular
+     * expression.
+     * 
+     * @param pattern
+     *            regular expression to match - Cannot be null
+     */
+    public RegexFileFilter(final Pattern pattern) {
+        if (pattern == null) {
+            throw new IllegalArgumentException(PATTERN_IS_MISSING);
+        }
+
+        this.pattern = pattern;
+    }
+
+    /**
+     * Construct a new regular expression filter.
+     * 
+     * @param pattern
+     *            regular string expression to match - Cannot be null
+     */
+    public RegexFileFilter(final String pattern) {
+        if (pattern == null) {
+            throw new IllegalArgumentException(PATTERN_IS_MISSING);
+        }
+
+        this.pattern = Pattern.compile(pattern);
+    }
+
+    /**
+     * Construct a new regular expression filter with the specified flags.
+     * 
+     * @param pattern
+     *            regular string expression to match
+     * @param flags
+     *            pattern flags - e.g. {@link Pattern#CASE_INSENSITIVE}
+     */
+    public RegexFileFilter(final String pattern, final int flags) {
+        if (pattern == null) {
+            throw new IllegalArgumentException(PATTERN_IS_MISSING);
+        }
+        this.pattern = Pattern.compile(pattern, flags);
+    }
+
+    /**
+     * Construct a new regular expression filter with the specified flags case
+     * sensitivity.
+     * 
+     * @param pattern
+     *            regular string expression to match - Cannot be null
+     * @param caseSensitivity
+     *            how to handle case sensitivity, null means case-sensitive
+     */
+    public RegexFileFilter(final String pattern, final IOCase caseSensitivity) {
+        if (pattern == null) {
+            throw new IllegalArgumentException(PATTERN_IS_MISSING);
+        }
+        int flags = 0;
+        if (caseSensitivity != null && !caseSensitivity.isCaseSensitive()) {
+            flags = Pattern.CASE_INSENSITIVE;
+        }
+        this.pattern = Pattern.compile(pattern, flags);
+    }
+
+    /**
+     * Checks to see if the filename matches one of the regular expressions.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return true if the file matches one of the regular expressions
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        final String name = fileInfo.getFile().getName().getBaseName();
+        return pattern.matcher(name).matches();
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SizeFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SizeFileFilter.java
new file mode 100644
index 0000000..5335d92
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SizeFileFilter.java
@@ -0,0 +1,131 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileContent;
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+
+/**
+ * Filters files based on size, can filter either smaller files or files equal
+ * to or larger than a given threshold.
+ * <p>
+ * For example, to print all files and directories in the current directory
+ * whose size is greater than 1 MB:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * SizeFileFilter filter = new SizeFileFilter(1024 * 1024);
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(filter));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class SizeFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Whether the files accepted will be larger or smaller. */
+    private final boolean acceptLarger;
+
+    /** The size threshold. */
+    private final long size;
+
+    /**
+     * Constructs a new size file filter for files equal to or larger than a
+     * certain size.
+     * 
+     * @param size
+     *            the threshold size of the files - Must be non-negative.
+     */
+    public SizeFileFilter(final long size) {
+        this(size, true);
+    }
+
+    /**
+     * Constructs a new size file filter for files based on a certain size
+     * threshold.
+     * 
+     * @param size
+     *            the threshold size of the files - Must be non-negative.
+     * @param acceptLarger
+     *            if true, files equal to or larger are accepted, otherwise
+     *            smaller ones (but not equal to)
+     */
+    public SizeFileFilter(final long size, final boolean acceptLarger) {
+        if (size < 0) {
+            throw new IllegalArgumentException("The size must be non-negative");
+        }
+        this.size = size;
+        this.acceptLarger = acceptLarger;
+    }
+
+    /**
+     * Checks to see if the size of the file is favorable.
+     * <p>
+     * If size equals threshold and smaller files are required, file <b>IS
+     * NOT</b> selected. If size equals threshold and larger files are required,
+     * file <b>IS</b> selected.
+     * <p>
+     * Non-existing files return always false (will never be accepted).
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return true if the filename matches
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        try {
+            final FileObject file = fileInfo.getFile();
+            if (!file.exists()) {
+                return false;
+            }
+            final FileContent content = file.getContent();
+            try {
+                final long length = content.getSize();
+                final boolean smaller = length < size;
+                return acceptLarger ? !smaller : smaller;
+            } finally {
+                content.close();
+            }
+        } catch (final FileSystemException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Provide a String representation of this file filter.
+     * 
+     * @return a String representation
+     */
+    @Override
+    public String toString() {
+        final String condition = acceptLarger ? ">=" : "<";
+        return super.toString() + "(" + condition + size + ")";
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SizeRangeFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SizeRangeFileFilter.java
new file mode 100644
index 0000000..e4d4464
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SizeRangeFileFilter.java
@@ -0,0 +1,53 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * Filter that accepts files whose size is &gt;= minimum size and &lt;= maximum
+ * size.
+ */
+public class SizeRangeFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private final FileFilter filter;
+
+    /**
+     * Constructor with sizes.
+     * 
+     * @param minSizeInclusive
+     *            the minimum file size (inclusive)
+     * @param maxSizeInclusive
+     *            the maximum file size (inclusive)
+     */
+    public SizeRangeFileFilter(final long minSizeInclusive, final long maxSizeInclusive) {
+        final FileFilter minimumFilter = new SizeFileFilter(minSizeInclusive, true);
+        final FileFilter maximumFilter = new SizeFileFilter(maxSizeInclusive + 1L, false);
+        filter = new AndFileFilter(minimumFilter, maximumFilter);
+    }
+
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        return filter.accept(fileInfo);
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SuffixFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SuffixFileFilter.java
new file mode 100644
index 0000000..24cde11
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/SuffixFileFilter.java
@@ -0,0 +1,151 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * Filters files based on the suffix (what the filename ends with). This is used
+ * in retrieving all the files of a particular type.
+ * <p>
+ * For example, to retrieve and print all <code>*.java</code> files in the
+ * current directory:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files = dir.findFiles(new FileFilterSelector(new SuffixFileFilter(&quot;.java&quot;)));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class SuffixFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Whether the comparison is case sensitive. */
+    private final IOCase caseSensitivity;
+
+    /** The filename suffixes to search for. */
+    private final List<String> suffixes;
+
+    /**
+     * Constructs a new Suffix file filter for a list of suffixes.
+     * 
+     * @param suffixes
+     *            the suffixes to allow, must not be null
+     */
+    public SuffixFileFilter(final List<String> suffixes) {
+        this(IOCase.SENSITIVE, suffixes);
+    }
+
+    /**
+     * Constructs a new Suffix file filter for a list of suffixes specifying
+     * case-sensitivity.
+     * 
+     * @param suffixes
+     *            the suffixes to allow, must not be null
+     * @param caseSensitivity
+     *            how to handle case sensitivity, null means case-sensitive
+     */
+    public SuffixFileFilter(final IOCase caseSensitivity, final List<String> suffixes) {
+        if (suffixes == null) {
+            throw new IllegalArgumentException("The list of suffixes must not be null");
+        }
+        this.suffixes = new ArrayList<>(suffixes);
+        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+    }
+
+    /**
+     * Constructs a new Suffix file filter for an array of suffixes.
+     * 
+     * @param suffixes
+     *            the suffixes to allow, must not be null
+     */
+    public SuffixFileFilter(final String... suffixes) {
+        this(IOCase.SENSITIVE, suffixes);
+    }
+
+    /**
+     * Constructs a new Suffix file filter for an array of suffixs specifying
+     * case-sensitivity.
+     * 
+     * @param suffixes
+     *            the suffixes to allow, must not be null
+     * @param caseSensitivity
+     *            how to handle case sensitivity, null means case-sensitive
+     */
+    public SuffixFileFilter(final IOCase caseSensitivity, final String... suffixes) {
+        if (suffixes == null) {
+            throw new IllegalArgumentException("The array of suffixes must not be null");
+        }
+        this.suffixes = new ArrayList<>(Arrays.asList(suffixes));
+        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+    }
+
+    /**
+     * Checks to see if the filename ends with the suffix.
+     * 
+     * @param fileInfo
+     *            the File to check
+     * 
+     * @return true if the filename ends with one of our suffixes
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        final String name = fileInfo.getFile().getName().getBaseName();
+        for (final String suffix : this.suffixes) {
+            if (caseSensitivity.checkEndsWith(name, suffix)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Provide a String representation of this file filter.
+     * 
+     * @return a String representation
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder();
+        buffer.append(super.toString());
+        buffer.append("(");
+        if (suffixes != null) {
+            for (int i = 0; i < suffixes.size(); i++) {
+                if (i > 0) {
+                    buffer.append(",");
+                }
+                buffer.append(suffixes.get(i));
+            }
+        }
+        buffer.append(")");
+        return buffer.toString();
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/TrueFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/TrueFileFilter.java
new file mode 100644
index 0000000..165e291
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/TrueFileFilter.java
@@ -0,0 +1,58 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * A file filter that always returns true.
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class TrueFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Singleton instance of true filter.
+     */
+    public static final FileFilter TRUE = new TrueFileFilter();
+
+    /**
+     * Restrictive constructor.
+     */
+    protected TrueFileFilter() {
+    }
+
+    /**
+     * Returns true.
+     * 
+     * @param fileInfo
+     *            the file to check (ignored)
+     * 
+     * @return Always {@code true}
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        return true;
+    }
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/WildcardFileFilter.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/WildcardFileFilter.java
new file mode 100644
index 0000000..5e5c254
--- /dev/null
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/filter/WildcardFileFilter.java
@@ -0,0 +1,312 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Stack;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+
+/**
+ * Filters files using the supplied wildcards.
+ * <p>
+ * This filter selects files and directories based on one or more wildcards.
+ * Testing is case-sensitive by default, but this can be configured.
+ * <p>
+ * The wildcard matcher uses the characters '?' and '*' to represent a single or
+ * multiple wildcard characters. This is the same as often found on Dos/Unix
+ * command lines. The extension check is case-sensitive by . See
+ * {@link FilenameUtils#wildcardMatchOnSystem} for more information.
+ * <p>
+ * For example, to retrieve and print all java files that have the expression
+ * test in the name in the current directory:
+ * 
+ * <pre>
+ * FileSystemManager fsManager = VFS.getManager();
+ * FileObject dir = fsManager.toFileObject(new File(&quot;.&quot;));
+ * FileObject[] files;
+ * files = dir.findFiles(new FileFilterSelector(new WildcardFileFilter(&quot;*test*.java&quot;)));
+ * for (int i = 0; i &lt; files.length; i++) {
+ *     System.out.println(files[i]);
+ * }
+ * </pre>
+ * 
+ * @author This code was originally ported from Apache Commons IO File Filter
+ * @see "http://commons.apache.org/proper/commons-io/"
+ */
+public class WildcardFileFilter implements FileFilter, Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** Whether the comparison is case sensitive. */
+    private final IOCase caseSensitivity;
+
+    /** The wildcards that will be used to match filenames. */
+    private final List<String> wildcards;
+
+    /**
+     * Construct a new case-sensitive wildcard filter for a list of wildcards.
+     * 
+     * @param wildcards
+     *            the list of wildcards to match, not null
+     */
+    public WildcardFileFilter(final List<String> wildcards) {
+        this((IOCase) null, wildcards);
+    }
+
+    /**
+     * Construct a new wildcard filter for a list of wildcards specifying
+     * case-sensitivity.
+     * 
+     * @param caseSensitivity
+     *            how to handle case sensitivity, null means case-sensitive
+     * @param wildcards
+     *            the list of wildcards to match, not null
+     */
+    public WildcardFileFilter(final IOCase caseSensitivity, final List<String> wildcards) {
+        if (wildcards == null) {
+            throw new IllegalArgumentException("The wildcard list must not be null");
+        }
+        this.wildcards = new ArrayList<>(wildcards);
+        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+    }
+
+    /**
+     * Construct a new case-sensitive wildcard filter for an array of wildcards.
+     * <p>
+     * The array is not cloned, so could be changed after constructing the
+     * instance. This would be inadvisable however.
+     * 
+     * @param wildcards
+     *            the array of wildcards to match
+     */
+    public WildcardFileFilter(final String... wildcards) {
+        this((IOCase) null, wildcards);
+    }
+
+    /**
+     * Construct a new wildcard filter for an array of wildcards specifying
+     * case-sensitivity.
+     * 
+     * @param caseSensitivity
+     *            how to handle case sensitivity, null means case-sensitive
+     * @param wildcards
+     *            the array of wildcards to match, not null
+     */
+    public WildcardFileFilter(final IOCase caseSensitivity, final String... wildcards) {
+        if (wildcards == null) {
+            throw new IllegalArgumentException("The wildcard array must not be null");
+        }
+        this.wildcards = new ArrayList<>(Arrays.asList(wildcards));
+        this.caseSensitivity = caseSensitivity == null ? IOCase.SENSITIVE : caseSensitivity;
+    }
+
+    /**
+     * Checks to see if the filename matches one of the wildcards.
+     * 
+     * @param fileInfo
+     *            the file to check
+     * 
+     * @return true if the filename matches one of the wildcards
+     */
+    @Override
+    public boolean accept(final FileSelectInfo fileInfo) {
+        final String name = fileInfo.getFile().getName().getBaseName();
+        for (final String wildcard : wildcards) {
+            if (wildcardMatch(name, wildcard, caseSensitivity)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Provide a String representation of this file filter.
+     * 
+     * @return a String representation
+     */
+    @Override
+    public String toString() {
+        final StringBuilder buffer = new StringBuilder();
+        buffer.append(super.toString());
+        buffer.append("(");
+        if (wildcards != null) {
+            for (int i = 0; i < wildcards.size(); i++) {
+                if (i > 0) {
+                    buffer.append(",");
+                }
+                buffer.append(wildcards.get(i));
+            }
+        }
+        buffer.append(")");
+        return buffer.toString();
+    }
+
+    /**
+     * Splits a string into a number of tokens. The text is split by '?' and
+     * '*'. Where multiple '*' occur consecutively they are collapsed into a
+     * single '*'.
+     * 
+     * @param text
+     *            the text to split
+     * @return the array of tokens, never null
+     */
+    // CHECKSTYLE:OFF Cyclomatic complexity of 12 is OK here
+    static String[] splitOnTokens(final String text) {
+        // used by wildcardMatch
+        // package level so a unit test may run on this
+
+        if (text.indexOf('?') == -1 && text.indexOf('*') == -1) {
+            return new String[] { text };
+        }
+
+        final char[] array = text.toCharArray();
+        final ArrayList<String> list = new ArrayList<>();
+        final StringBuilder buffer = new StringBuilder();
+        for (int i = 0; i < array.length; i++) {
+            if (array[i] == '?' || array[i] == '*') {
+                if (buffer.length() != 0) {
+                    list.add(buffer.toString());
+                    buffer.setLength(0);
+                }
+                if (array[i] == '?') {
+                    list.add("?");
+                } else if (list.isEmpty() || i > 0 && !list.get(list.size() - 1).equals("*")) {
+                    list.add("*");
+                }
+            } else {
+                buffer.append(array[i]);
+            }
+        }
+        if (buffer.length() != 0) {
+            list.add(buffer.toString());
+        }
+
+        return list.toArray(new String[list.size()]);
+    }
+
+    // CHECKSTYLE:ON
+
+    /**
+     * Checks a filename to see if it matches the specified wildcard matcher
+     * allowing control over case-sensitivity.
+     * <p>
+     * The wildcard matcher uses the characters '?' and '*' to represent a
+     * single or multiple (zero or more) wildcard characters. N.B. the sequence
+     * "*?" does not work properly at present in match strings.
+     * 
+     * @param filename
+     *            the filename to match on
+     * @param wildcardMatcher
+     *            the wildcard string to match against
+     * @param caseSensitivity
+     *            what case sensitivity rule to use, null means case-sensitive
+     * 
+     * @return true if the filename matches the wilcard string
+     */
+    // CHECKSTYLE:OFF TODO xxx Cyclomatic complexity of 19 should be refactored
+    static boolean wildcardMatch(final String filename, final String wildcardMatcher,
+            IOCase caseSensitivity) {
+        if (filename == null && wildcardMatcher == null) {
+            return true;
+        }
+        if (filename == null || wildcardMatcher == null) {
+            return false;
+        }
+        if (caseSensitivity == null) {
+            caseSensitivity = IOCase.SENSITIVE;
+        }
+        final String[] wcs = splitOnTokens(wildcardMatcher);
+        boolean anyChars = false;
+        int textIdx = 0;
+        int wcsIdx = 0;
+        final Stack<int[]> backtrack = new Stack<>();
+
+        // loop around a backtrack stack, to handle complex * matching
+        do {
+            if (backtrack.size() > 0) {
+                final int[] array = backtrack.pop();
+                wcsIdx = array[0];
+                textIdx = array[1];
+                anyChars = true;
+            }
+
+            // loop whilst tokens and text left to process
+            while (wcsIdx < wcs.length) {
+
+                if (wcs[wcsIdx].equals("?")) {
+                    // ? so move to next text char
+                    textIdx++;
+                    if (textIdx > filename.length()) {
+                        break;
+                    }
+                    anyChars = false;
+
+                } else if (wcs[wcsIdx].equals("*")) {
+                    // set any chars status
+                    anyChars = true;
+                    if (wcsIdx == wcs.length - 1) {
+                        textIdx = filename.length();
+                    }
+
+                } else {
+                    // matching text token
+                    if (anyChars) {
+                        // any chars then try to locate text token
+                        textIdx = caseSensitivity.checkIndexOf(filename, textIdx, wcs[wcsIdx]);
+                        if (textIdx == -1) {
+                            // token not found
+                            break;
+                        }
+                        final int repeat = caseSensitivity.checkIndexOf(filename, textIdx + 1,
+                                wcs[wcsIdx]);
+                        if (repeat >= 0) {
+                            backtrack.push(new int[] { wcsIdx, repeat });
+                        }
+                    } else {
+                        // matching from current position
+                        if (!caseSensitivity.checkRegionMatches(filename, textIdx, wcs[wcsIdx])) {
+                            // couldnt match token
+                            break;
+                        }
+                    }
+
+                    // matched text token, move text index to end of matched
+                    // token
+                    textIdx += wcs[wcsIdx].length();
+                    anyChars = false;
+                }
+
+                wcsIdx++;
+            }
+
+            // full match
+            if (wcsIdx == wcs.length && textIdx == filename.length()) {
+                return true;
+            }
+
+        } while (backtrack.size() > 0);
+
+        return false;
+    }
+    // CHECKSTYLE:ON
+
+}
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileMonitor.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileMonitor.java
index 99e1e77..daed3ac 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileMonitor.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileMonitor.java
@@ -474,7 +474,7 @@ public class DefaultFileMonitor implements Runnable, FileMonitor {
                         final Map<FileName, Object> newChildrenMap = new HashMap<>();
                         final Stack<FileObject> missingChildren = new Stack<>();
 
-                        for (FileObject element : newChildren) {
+                        for (final FileObject element : newChildren) {
                             newChildrenMap.put(element.getName(), new Object()); // null ?
                             // If the child's not there
                             if (!this.children.containsKey(element.getName())) {
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
index 9ddad5a..8d5a8ad 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/impl/DefaultFileSystemManager.java
@@ -930,7 +930,7 @@ public class DefaultFileSystemManager implements FileSystemManager, AutoCloseabl
      */
     @Override
     public FileObject createVirtualFileSystem(final FileObject rootFile) throws FileSystemException {
-        FileObject fileObject = vfsProvider.createFileSystem(rootFile);
+        final FileObject fileObject = vfsProvider.createFileSystem(rootFile);
         addVirtualFileSystemScheme(rootFile.getName().getScheme());
         return fileObject;
     }
@@ -944,7 +944,7 @@ public class DefaultFileSystemManager implements FileSystemManager, AutoCloseabl
      */
     @Override
     public FileObject createVirtualFileSystem(final String rootUri) throws FileSystemException {
-        FileObject fileObject = vfsProvider.createFileSystem(rootUri);
+        final FileObject fileObject = vfsProvider.createFileSystem(rootUri);
         addVirtualFileSystemScheme(rootUri);
         return fileObject;
     }
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/UriParser.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/UriParser.java
index 84ec829..7ba22da 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/UriParser.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/UriParser.java
@@ -329,12 +329,12 @@ public final class UriParser {
      * @return The scheme name. Returns null if there is no scheme.
      * @since 2.3
      */
-    public static String extractScheme(final String[] schemes, final String uri, StringBuilder buffer) {
+    public static String extractScheme(final String[] schemes, final String uri, final StringBuilder buffer) {
         if (buffer != null) {
             buffer.setLength(0);
             buffer.append(uri);
         }
-        for(String scheme : schemes) {
+        for(final String scheme : schemes) {
             if(uri.startsWith(scheme + ":")) {
                 if (buffer != null) {
                     buffer.delete(0, uri.indexOf(':') + 1);
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileObject.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileObject.java
index 8f0bac6..9e89fb2 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileObject.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/ftp/FtpFileObject.java
@@ -589,7 +589,7 @@ public class FtpFileObject extends AbstractFileObject<FtpFileSystem> {
         }
 
         private boolean isTransferAbortedOkReplyCode() throws IOException {
-            List<Integer> transferAbortedOkReplyCodes = FtpFileSystemConfigBuilder
+            final List<Integer> transferAbortedOkReplyCodes = FtpFileSystemConfigBuilder
                 .getInstance()
                 .getTransferAbortedOkReplyCodes(getAbstractFileSystem().getFileSystemOptions());
             return transferAbortedOkReplyCodes != null && transferAbortedOkReplyCodes.contains(client.getReplyCode());
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpClientFactory.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpClientFactory.java
index 6cb6d79..6be9cc2 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpClientFactory.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpClientFactory.java
@@ -135,8 +135,8 @@ public final class SftpClientFactory {
             if (proxyHost != null) {
                 final int proxyPort = builder.getProxyPort(fileSystemOptions);
                 final SftpFileSystemConfigBuilder.ProxyType proxyType = builder.getProxyType(fileSystemOptions);
-                String proxyUser =  builder.getProxyUser(fileSystemOptions);
-                String proxyPassword = builder.getProxyPassword(fileSystemOptions);
+                final String proxyUser =  builder.getProxyUser(fileSystemOptions);
+                final String proxyPassword = builder.getProxyPassword(fileSystemOptions);
                 Proxy proxy = null;
                 if (SftpFileSystemConfigBuilder.PROXY_HTTP.equals(proxyType)) {
                     proxy = createProxyHTTP(proxyHost, proxyPort);
@@ -181,7 +181,7 @@ public final class SftpClientFactory {
         }
     }
 
-    private static void setConfigRepository(final JSch jsch, final File sshDir, final ConfigRepository configRepository, boolean loadOpenSSHConfig) throws FileSystemException {
+    private static void setConfigRepository(final JSch jsch, final File sshDir, final ConfigRepository configRepository, final boolean loadOpenSSHConfig) throws FileSystemException {
         if (configRepository != null) {
             jsch.setConfigRepository(configRepository);
         } else if (loadOpenSSHConfig) {
@@ -189,7 +189,7 @@ public final class SftpClientFactory {
                 // loading openssh config (~/.ssh/config)
                 final ConfigRepository openSSHConfig = OpenSSHConfig.parseFile(new File(sshDir, OPENSSH_CONFIG_NAME).getAbsolutePath());
                 jsch.setConfigRepository(openSSHConfig);
-            } catch (IOException e) {
+            } catch (final IOException e) {
                 throw new FileSystemException("vfs.provider.sftp/load-openssh-config.error", e);
             }
         }
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileSystemConfigBuilder.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileSystemConfigBuilder.java
index 128a349..93ba4fe 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileSystemConfigBuilder.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/provider/sftp/SftpFileSystemConfigBuilder.java
@@ -375,7 +375,7 @@ public final class SftpFileSystemConfigBuilder extends FileSystemConfigBuilder {
     * @return the option value for spesific key exchange algorithm
     * @see #setKeyExchangeAlgorithm(FileSystemOptions, String)
     **/
-    public String getKeyExchangeAlgorithm(FileSystemOptions opts) {
+    public String getKeyExchangeAlgorithm(final FileSystemOptions opts) {
         return this.getString(opts, KEY_EXCHANGE_ALGORITHM);
     }
 
@@ -646,7 +646,7 @@ public final class SftpFileSystemConfigBuilder extends FileSystemConfigBuilder {
       * @param opts The FileSystem options.
       * @param keyExchangeAlgoritm The key exchange algoritm picked.
     **/
-        public void setKeyExchangeAlgorithm(FileSystemOptions opts, String keyExchangeAlgoritm) {
+        public void setKeyExchangeAlgorithm(final FileSystemOptions opts, final String keyExchangeAlgoritm) {
       setParam(opts, KEY_EXCHANGE_ALGORITHM, keyExchangeAlgoritm);
     }
     
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/PosixPermissions.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/PosixPermissions.java
index 55a3a22..ddc8de1 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/PosixPermissions.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/util/PosixPermissions.java
@@ -30,7 +30,7 @@ public class PosixPermissions {
     /**
      * Permission types.
      */
-    public static enum Type {
+    public enum Type {
         /**
          * User right readable.
          */
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/NullFilesCacheTests.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/NullFilesCacheTests.java
index 0f9548b..68a5985 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/NullFilesCacheTests.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/NullFilesCacheTests.java
@@ -40,7 +40,7 @@ public class NullFilesCacheTests extends AbstractFilesCacheTestsBase {
 
     @Override
     public void testBasicCacheOps() throws Exception {
-        DefaultFileSystemManager manager = getManager();
+        final DefaultFileSystemManager manager = getManager();
         Assert.assertNotNull("This test should not have a null DefaultFileSystemManager", manager);
         // the basic test looks different for a null cache:
         final FilesCache cache = manager.getFilesCache();
@@ -62,7 +62,7 @@ public class NullFilesCacheTests extends AbstractFilesCacheTestsBase {
     }
 
     public void testClass() {
-        DefaultFileSystemManager manager = getManager();
+        final DefaultFileSystemManager manager = getManager();
         Assert.assertNotNull("This test should not have a null DefaultFileSystemManager", manager);
         assertTrue(manager.getFilesCache() instanceof NullFilesCache);
     }
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/AgeFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/AgeFileFilterTest.java
new file mode 100644
index 0000000..114b2d6
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/AgeFileFilterTest.java
@@ -0,0 +1,209 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test for {@link AgeFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class AgeFileFilterTest extends BaseFilterTest {
+
+    private static long DAY_MILLIS = 24 * 60 * 60 * 1000;
+
+    private static long NOW = System.currentTimeMillis();
+
+    private static long TWO_DAYS_AGO = NOW - (2 * DAY_MILLIS);
+
+    private static long TWO_DAYS_LATER = NOW + (2 * DAY_MILLIS);
+
+    private static File testDir;
+
+    private static File oldFile;
+
+    private static FileSelectInfo oldFileInfo;
+
+    private static File newFile;
+
+    private static FileSelectInfo newFileInfo;
+
+    private static File currentFile;
+
+    private static FileSelectInfo currentFileInfo;
+
+    private static File zipFile;
+
+    private static FileObject zipFileObj;
+
+    @BeforeClass
+    public static void beforeClass() throws IOException {
+        testDir = getTestDir(AgeFileFilterTest.class.getName());
+
+        // Set the file's time stamp two days back
+        oldFile = new File(testDir, "old.txt");
+        FileUtils.touch(oldFile);
+        oldFile.setLastModified(TWO_DAYS_AGO);
+        oldFileInfo = createFSI(oldFile);
+
+        // Reference file
+        currentFile = new File(testDir, "current.txt");
+        FileUtils.touch(currentFile);
+        currentFile.setLastModified(NOW);
+        currentFileInfo = createFSI(currentFile);
+
+        // Set the file's time stamp two days into the future
+        newFile = new File(testDir, "new.txt");
+        FileUtils.touch(newFile);
+        newFile.setLastModified(TWO_DAYS_LATER);
+        newFileInfo = createFSI(newFile);
+
+        // Zip the test directory
+        zipFile = new File(getTempDir(), AgeFileFilterTest.class.getName()
+                + ".zip");
+        zipDir(testDir, "", zipFile);
+        zipFileObj = getZipFileObject(zipFile);
+
+    }
+
+    @AfterClass
+    public static void afterClass() throws IOException {
+        newFileInfo = null;
+        newFile = null;
+
+        currentFileInfo = null;
+        currentFile = null;
+
+        oldFileInfo = null;
+        oldFile = null;
+
+        zipFileObj.close();
+        FileUtils.deleteQuietly(zipFile);
+        zipFile = null;
+
+        FileUtils.deleteDirectory(testDir);
+        testDir = null;
+    }
+
+    @Test
+    public void testAgeFileFilterDate() {
+
+        final AgeFileFilter testee = new AgeFileFilter(new Date());
+        Assert.assertTrue(testee.accept(oldFileInfo));
+        Assert.assertTrue(testee.accept(currentFileInfo));
+        Assert.assertFalse(testee.accept(newFileInfo));
+
+    }
+
+    @Test
+    public void testAgeFileFilterDateBoolean() {
+
+        AgeFileFilter testee;
+
+        testee = new AgeFileFilter(new Date(), true);
+        Assert.assertTrue(testee.accept(oldFileInfo));
+        Assert.assertTrue(testee.accept(currentFileInfo));
+        Assert.assertFalse(testee.accept(newFileInfo));
+
+        testee = new AgeFileFilter(new Date(), false);
+        Assert.assertFalse(testee.accept(oldFileInfo));
+        Assert.assertFalse(testee.accept(currentFileInfo));
+        Assert.assertTrue(testee.accept(newFileInfo));
+
+    }
+
+    @Test
+    public void testAgeFileFilterFile() throws FileSystemException {
+
+        final AgeFileFilter testee = new AgeFileFilter(currentFileInfo.getFile());
+        Assert.assertTrue(testee.accept(oldFileInfo));
+        Assert.assertTrue(testee.accept(currentFileInfo));
+        Assert.assertFalse(testee.accept(newFileInfo));
+
+    }
+
+    @Test
+    public void testAgeFileFilterFileBoolean() throws FileSystemException {
+
+        AgeFileFilter testee;
+
+        testee = new AgeFileFilter(currentFileInfo.getFile(), true);
+        Assert.assertTrue(testee.accept(oldFileInfo));
+        Assert.assertTrue(testee.accept(currentFileInfo));
+        Assert.assertFalse(testee.accept(newFileInfo));
+
+        testee = new AgeFileFilter(currentFileInfo.getFile(), false);
+        Assert.assertFalse(testee.accept(oldFileInfo));
+        Assert.assertFalse(testee.accept(currentFileInfo));
+        Assert.assertTrue(testee.accept(newFileInfo));
+
+    }
+
+    @Test
+    public void testAgeFileFilterLong() {
+
+        final AgeFileFilter testee = new AgeFileFilter(NOW);
+        Assert.assertTrue(testee.accept(oldFileInfo));
+        Assert.assertTrue(testee.accept(currentFileInfo));
+        Assert.assertFalse(testee.accept(newFileInfo));
+
+    }
+
+    @Test
+    public void testAgeFileFilterLongBoolean() throws FileSystemException {
+
+        AgeFileFilter testee;
+
+        testee = new AgeFileFilter(NOW, true);
+        Assert.assertTrue(testee.accept(oldFileInfo));
+        Assert.assertTrue(testee.accept(currentFileInfo));
+        Assert.assertFalse(testee.accept(newFileInfo));
+
+        testee = new AgeFileFilter(NOW, false);
+        Assert.assertFalse(testee.accept(oldFileInfo));
+        Assert.assertFalse(testee.accept(currentFileInfo));
+        Assert.assertTrue(testee.accept(newFileInfo));
+
+        // Same test with ZIP file
+        FileObject[] files;
+
+        files = zipFileObj.findFiles(new FileFilterSelector(new AgeFileFilter(
+                NOW, true)));
+        assertContains(files, oldFile.getName(), currentFile.getName());
+        Assert.assertEquals(2, files.length);
+
+        files = zipFileObj.findFiles(new FileFilterSelector(new AgeFileFilter(
+                NOW, false)));
+        assertContains(files, newFile.getName());
+        Assert.assertEquals(1, files.length);
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/AndFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/AndFileFilterTest.java
new file mode 100644
index 0000000..e943eb1
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/AndFileFilterTest.java
@@ -0,0 +1,184 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.junit.Assert;
+import org.junit.Test;
+
+// CHECKSTYLE:OFF Test code
+public class AndFileFilterTest extends BaseFilterTest {
+
+    @Test
+    public void testAndFileFilterFileFilter() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+
+        // TEST
+        final AndFileFilter testee = new AndFileFilter(filter1, filter2, filter3);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter2, filter3);
+
+    }
+
+    @Test
+    public void testAndFileFilterList() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+        final List<FileFilter> list = new ArrayList<>();
+        list.add(filter1);
+        list.add(filter2);
+        list.add(filter3);
+
+        // TEST
+        final AndFileFilter testee = new AndFileFilter(list);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter2, filter3);
+
+    }
+
+    @Test
+    public void testAddFileFilter() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+
+        // TEST
+        final AndFileFilter testee = new AndFileFilter();
+        testee.addFileFilter(filter1);
+        testee.addFileFilter(filter2);
+        testee.addFileFilter(filter3);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter2, filter3);
+
+    }
+
+    @Test
+    public void testRemoveFileFilter() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+        final AndFileFilter testee = new AndFileFilter(filter1, filter2, filter3);
+
+        // TEST
+        testee.removeFileFilter(filter2);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter3);
+
+    }
+
+    @Test
+    public void testSetFileFilters() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+        final List<FileFilter> list = new ArrayList<>();
+        list.add(filter1);
+        list.add(filter2);
+        list.add(filter3);
+        final AndFileFilter testee = new AndFileFilter();
+
+        // TEST
+        testee.setFileFilters(list);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter2, filter3);
+
+    }
+
+    @Test
+    public void testAccept() {
+
+        final FileSelectInfo any = createFSI(new File("anyfile"));
+
+        // Empty
+        Assert.assertFalse(new AndFileFilter().accept(any));
+
+        // True
+        Assert.assertTrue(new AndFileFilter(new True()).accept(any));
+        Assert.assertTrue(new AndFileFilter(new True(), new True()).accept(any));
+
+        // False
+        Assert.assertFalse(new AndFileFilter(new False()).accept(any));
+        Assert.assertFalse(new AndFileFilter(new False(), new False())
+                .accept(any));
+        Assert.assertFalse(new AndFileFilter(new False(), new True())
+                .accept(any));
+        Assert.assertFalse(new AndFileFilter(new True(), new False())
+                .accept(any));
+
+    }
+
+    /**
+     * Just a filter class.
+     */
+    private static class DummyFilter implements FileFilter {
+
+        @Override
+        public boolean accept(final FileSelectInfo fileInfo) {
+            return false;
+        }
+
+    }
+
+    /**
+     * Always TRUE.
+     */
+    private static class True implements FileFilter {
+
+        @Override
+        public boolean accept(final FileSelectInfo fileInfo) {
+            return true;
+        }
+
+    }
+
+    /**
+     * Always FALSE.
+     */
+    private static class False implements FileFilter {
+
+        @Override
+        public boolean accept(final FileSelectInfo fileInfo) {
+            return false;
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/BaseFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/BaseFilterTest.java
new file mode 100644
index 0000000..ac0763c
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/BaseFilterTest.java
@@ -0,0 +1,387 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import static org.junit.Assert.fail;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.apache.commons.vfs2.FileSystemManager;
+import org.apache.commons.vfs2.VFS;
+import org.junit.Assert;
+
+/**
+ * Base class for test cases.
+ */
+public abstract class BaseFilterTest {
+
+    /**
+     * Creates a file select info object for the given file.
+     * 
+     * @param file
+     *            File to create an info for.
+     * 
+     * @return File selct info.
+     */
+    protected static FileSelectInfo createFSI(final File file) {
+        try {
+            final FileSystemManager fsManager = VFS.getManager();
+            final FileObject fileObject = fsManager.toFileObject(file);
+            return new FileSelectInfo() {
+                @Override
+                public FileObject getFile() {
+                    return fileObject;
+                }
+
+                @Override
+                public int getDepth() {
+                    return 0;
+                }
+
+                @Override
+                public FileObject getBaseFolder() {
+                    try {
+                        return fileObject.getParent();
+                    } catch (final FileSystemException ex) {
+                        throw new RuntimeException(ex);
+                    }
+                }
+            };
+        } catch (final FileSystemException ex) {
+            throw new RuntimeException(ex);
+        }
+    }
+
+    /**
+     * Returns a ZIP file object.
+     * 
+     * @param file
+     *            File to resolve.
+     * 
+     * @return File object.
+     * 
+     * @throws FileSystemException
+     *             Error resolving the file.
+     */
+    protected static FileObject getZipFileObject(final File file)
+            throws FileSystemException {
+        final FileSystemManager fsManager = VFS.getManager();
+        return fsManager.resolveFile("zip:" + file.toURI());
+    }
+
+    /**
+     * Asserts that the array contains the given file names.
+     * 
+     * @param files
+     *            Array to check.
+     * @param filenames
+     *            File names to find.
+     */
+    protected void assertContains(final FileObject[] files,
+            final String... filenames) {
+        for (final String filename : filenames) {
+            if (!find(files, filename)) {
+                fail("File '" + filename + "' not found in: "
+                        + Arrays.asList(files));
+            }
+        }
+    }
+
+    private boolean find(final FileObject[] files, final String filename) {
+        for (final FileObject file : files) {
+            final String name = file.getName().getBaseName();
+            if (name.equals(filename)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the temporary directory.
+     * 
+     * @return java.io.tmpdir
+     */
+    protected static File getTempDir() {
+        return new File(System.getProperty("java.io.tmpdir"));
+    }
+
+    /**
+     * Returns a sub directory of the temporary directory.
+     * 
+     * @param name
+     *            Name of the sub directory.
+     * 
+     * @return Sub directory of java.io.tmpdir.
+     */
+    protected static File getTestDir(final String name) {
+        return new File(getTempDir(), name);
+    }
+
+    /**
+     * Verifies at least all given objects are in the list.
+     * 
+     * @param list
+     *            List to use.
+     * @param objects
+     *            Objects to find.
+     */
+    protected static void assertContains(final List<?> list, final Object... objects) {
+        for (final Object obj : objects) {
+            Assert.assertTrue(
+                    "Couldn't find " + obj + " in " + Arrays.asList(objects),
+                    list.indexOf(obj) > -1);
+        }
+    }
+
+    /**
+     * Verifies only the given objects are in the list.
+     * 
+     * @param list
+     *            List to scan.
+     * @param objects
+     *            Objects to find.
+     */
+    protected static void assertContainsOnly(final List<?> list, final Object... objects) {
+        for (final Object obj : objects) {
+            Assert.assertTrue(
+                    "Couldn't find " + obj + " in " + Arrays.asList(objects),
+                    list.indexOf(obj) > -1);
+        }
+        Assert.assertEquals(objects.length, list.size());
+    }
+
+    /**
+     * Adds a file to a ZIP output stream.
+     * 
+     * @param srcFile
+     *            File to add - Cannot be <code>null</code>.
+     * @param destPath
+     *            Path to use for the file - May be <code>null</code> or empty.
+     * @param out
+     *            Destination stream - Cannot be <code>null</code>.
+     * 
+     * @throws IOException
+     *             Error writing to the output stream.
+     */
+    private static void zipFile(final File srcFile, final String destPath,
+            final ZipOutputStream out) throws IOException {
+
+        final byte[] buf = new byte[1024];
+        final InputStream in = new BufferedInputStream(new FileInputStream(
+                srcFile));
+        try {
+            final ZipEntry zipEntry = new ZipEntry(concatPathAndFilename(
+                    destPath, srcFile.getName(), File.separator));
+            zipEntry.setTime(srcFile.lastModified());
+            out.putNextEntry(zipEntry);
+            int len;
+            while ((len = in.read(buf)) > 0) {
+                out.write(buf, 0, len);
+            }
+            out.closeEntry();
+        } finally {
+            in.close();
+        }
+    }
+
+    /**
+     * Add a directory to a ZIP output stream.
+     * 
+     * @param srcDir
+     *            Directory to add - Cannot be <code>null</code> and must be a
+     *            valid directory.
+     * @param filter
+     *            Filter or <code>null</code> for all files.
+     * @param destPath
+     *            Path to use for the ZIP archive - May be <code>null</code> or
+     *            an empyt string.
+     * @param out
+     *            Destination stream - Cannot be <code>null</code>.
+     * 
+     * @throws IOException
+     *             Error writing to the output stream.
+     */
+    private static void zipDir(final File srcDir, final FileFilter filter,
+            final String destPath, final ZipOutputStream out)
+            throws IOException {
+
+        final File[] files = listFiles(srcDir, filter);
+        for (final File file : files) {
+            if (file.isDirectory()) {
+                zipDir(file,
+                        filter,
+                        concatPathAndFilename(destPath, file.getName(),
+                                File.separator), out);
+            } else {
+                zipFile(file, destPath, out);
+            }
+        }
+
+    }
+
+    /**
+     * Creates a ZIP file and adds all files in a directory and all it's sub
+     * directories to the archive. Only entries are added that comply to the
+     * file filter.
+     * 
+     * @param srcDir
+     *            Directory to add - Cannot be <code>null</code> and must be a
+     *            valid directory.
+     * @param filter
+     *            Filter or <code>null</code> for all files/directories.
+     * @param destPath
+     *            Path to use for the ZIP archive - May be <code>null</code> or
+     *            an empyt string.
+     * @param destFile
+     *            Target ZIP file - Cannot be <code>null</code>.
+     * 
+     * @throws IOException
+     *             Error writing to the output stream.
+     */
+    public static void zipDir(final File srcDir, final FileFilter filter,
+            final String destPath, final File destFile) throws IOException {
+
+        if (srcDir == null) {
+            throw new IllegalArgumentException("srcDir cannot be null");
+        }
+        if (!srcDir.exists()) {
+            throw new IllegalArgumentException("srcDir does not exist");
+        }
+        if (!srcDir.isDirectory()) {
+            throw new IllegalArgumentException("srcDir is not a directory");
+        }
+        if (destFile == null) {
+            throw new IllegalArgumentException("destFile cannot be null");
+        }
+
+        final ZipOutputStream out = new ZipOutputStream(
+                new BufferedOutputStream(new FileOutputStream(destFile)));
+        try {
+            zipDir(srcDir, filter, destPath, out);
+        } finally {
+            out.close();
+        }
+
+    }
+
+    /**
+     * Creates a ZIP file and adds all files in a directory and all it's sub
+     * directories to the archive.
+     * 
+     * @param srcDir
+     *            Directory to add - Cannot be <code>null</code> and must be a
+     *            valid directory.
+     * @param destPath
+     *            Path to use for the ZIP archive - May be <code>null</code> or
+     *            an empyt string.
+     * @param destFile
+     *            Target ZIP file - Cannot be <code>null</code>.
+     * 
+     * @throws IOException
+     *             Error writing to the output stream.
+     */
+    public static void zipDir(final File srcDir, final String destPath,
+            final File destFile) throws IOException {
+
+        zipDir(srcDir, null, destPath, destFile);
+
+    }
+
+    /**
+     * Concatenate a path and a filename taking <code>null</code> and empty
+     * string values into account.
+     * 
+     * @param path
+     *            Path - Can be <code>null</code> or an empty string.
+     * @param filename
+     *            Filename - Cannot be <code>null</code>.
+     * @param separator
+     *            Separator for directories - Can be <code>null</code> or an
+     *            empty string.
+     * 
+     * @return Path and filename divided by the separator.
+     */
+    public static String concatPathAndFilename(final String path,
+            final String filename, final String separator) {
+
+        if (filename == null) {
+            throw new IllegalArgumentException("filename cannot be null");
+        }
+        if (filename.trim().length() == 0) {
+            throw new IllegalArgumentException("filename cannot be empty");
+        }
+        if (separator == null) {
+            throw new IllegalArgumentException("separator cannot be null");
+        }
+        if (separator.trim().length() == 0) {
+            throw new IllegalArgumentException("separator cannot be empty");
+        }
+
+        if (path == null) {
+            return filename;
+        }
+        final String trimmedPath = path.trim();
+        if (trimmedPath.length() == 0) {
+            return filename;
+        }
+        final String trimmedFilename = filename.trim();
+        if (trimmedPath.endsWith(separator)) {
+            return trimmedPath + trimmedFilename;
+        }
+        return trimmedPath + separator + trimmedFilename;
+
+    }
+
+    /**
+     * List all files for a directory.
+     * 
+     * @param srcDir
+     *            Directory to list the files for - Cannot be <code>null</code>
+     *            and must be a valid directory.
+     * @param filter
+     *            Filter or <code>null</code> for all files.
+     * 
+     * @return List of child entries of the directory.
+     */
+    private static File[] listFiles(final File srcDir, final FileFilter filter) {
+
+        final File[] files;
+        if (filter == null) {
+            files = srcDir.listFiles();
+        } else {
+            files = srcDir.listFiles(filter);
+        }
+        return files;
+
+    }
+
+}
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/CanReadFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/CanReadFileFilterTest.java
new file mode 100644
index 0000000..5ca78a9
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/CanReadFileFilterTest.java
@@ -0,0 +1,166 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test for {@link CanReadFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class CanReadFileFilterTest extends BaseFilterTest {
+
+    private static final String WRITEABLE = "writeable.txt";
+
+    private static final String READONLY = "readonly.txt";
+
+    private static File testDir;
+
+    private static File writeableFile;
+
+    private static FileSelectInfo writeableFileInfo;
+
+    private static File readOnlyFile;
+
+    private static FileSelectInfo readOnlyFileInfo;
+
+    private static File notExistingFile;
+
+    private static FileSelectInfo notExistingFileInfo;
+
+    private static File zipFile;
+
+    private static FileObject zipFileObj;
+
+    @BeforeClass
+    public static void beforeClass() throws IOException {
+
+        testDir = getTestDir(CanReadFileFilterTest.class.getName());
+
+        writeableFile = new File(testDir, WRITEABLE);
+        writeableFileInfo = createFSI(writeableFile);
+        FileUtils.touch(writeableFile);
+
+        readOnlyFile = new File(testDir, READONLY);
+        readOnlyFileInfo = createFSI(readOnlyFile);
+        FileUtils.touch(readOnlyFile);
+        readOnlyFile.setReadable(true);
+        readOnlyFile.setWritable(false);
+
+        notExistingFile = new File(testDir, "not-existing-file.txt");
+        notExistingFileInfo = createFSI(notExistingFile);
+
+        zipFile = new File(getTempDir(), CanReadFileFilterTest.class.getName()
+                + ".zip");
+        zipDir(testDir, "", zipFile);
+        zipFileObj = getZipFileObject(zipFile);
+
+    }
+
+    @AfterClass
+    public static void afterClass() throws IOException {
+
+        writeableFileInfo = null;
+        writeableFile.delete();
+        writeableFile = null;
+
+        readOnlyFileInfo = null;
+        readOnlyFile.delete();
+        readOnlyFile = null;
+
+        notExistingFileInfo = null;
+        notExistingFile = null;
+
+        zipFileObj.close();
+        FileUtils.deleteQuietly(zipFile);
+        zipFile = null;
+
+        FileUtils.deleteDirectory(testDir);
+        testDir = null;
+
+    }
+
+    @Test
+    public void testAcceptCanRead() {
+
+        Assert.assertTrue(CanReadFileFilter.CAN_READ.accept(writeableFileInfo));
+        Assert.assertTrue(CanReadFileFilter.CAN_READ.accept(readOnlyFileInfo));
+        Assert.assertFalse(CanReadFileFilter.CAN_READ
+                .accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testAcceptCannotRead() {
+
+        Assert.assertFalse(CanReadFileFilter.CANNOT_READ
+                .accept(writeableFileInfo));
+        Assert.assertFalse(CanReadFileFilter.CANNOT_READ
+                .accept(readOnlyFileInfo));
+        Assert.assertTrue(CanReadFileFilter.CANNOT_READ
+                .accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testAcceptReadOnly() {
+
+        Assert.assertFalse(CanReadFileFilter.READ_ONLY
+                .accept(writeableFileInfo));
+        Assert.assertTrue(CanReadFileFilter.READ_ONLY.accept(readOnlyFileInfo));
+        Assert.assertFalse(CanReadFileFilter.READ_ONLY
+                .accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testAcceptZipFile() throws FileSystemException {
+
+        FileObject[] files;
+
+        // CAN_READ Filter
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                CanReadFileFilter.CAN_READ));
+        assertContains(files, READONLY, WRITEABLE);
+        Assert.assertEquals(2, files.length);
+
+        // CANNOT_READ Filter
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                CanReadFileFilter.CANNOT_READ));
+        Assert.assertTrue(files == null || files.length == 0);
+
+        // READ_ONLY Filter
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                CanReadFileFilter.READ_ONLY));
+        assertContains(files, READONLY, WRITEABLE);
+        Assert.assertEquals(2, files.length);
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/CanWriteFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/CanWriteFileFilterTest.java
new file mode 100644
index 0000000..5eb6462
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/CanWriteFileFilterTest.java
@@ -0,0 +1,151 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test for {@link CanWriteFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class CanWriteFileFilterTest extends BaseFilterTest {
+
+    private static final String WRITEABLE = "writeable.txt";
+
+    private static final String READONLY = "readonly.txt";
+
+    private static File testDir;
+
+    private static File writeableFile;
+
+    private static FileSelectInfo writeableFileInfo;
+
+    private static File readOnlyFile;
+
+    private static FileSelectInfo readOnlyFileInfo;
+
+    private static File notExistingFile;
+
+    private static FileSelectInfo notExistingFileInfo;
+
+    private static File zipFile;
+
+    private static FileObject zipFileObj;
+
+    @BeforeClass
+    public static void beforeClass() throws IOException {
+
+        testDir = getTestDir(CanWriteFileFilterTest.class.getName());
+
+        writeableFile = new File(testDir, WRITEABLE);
+        writeableFileInfo = createFSI(writeableFile);
+        FileUtils.touch(writeableFile);
+
+        readOnlyFile = new File(testDir, READONLY);
+        readOnlyFileInfo = createFSI(readOnlyFile);
+        FileUtils.touch(readOnlyFile);
+        readOnlyFile.setReadable(true);
+        readOnlyFile.setWritable(false);
+
+        notExistingFile = new File(testDir, "not-existing-file.txt");
+        notExistingFileInfo = createFSI(notExistingFile);
+
+        zipFile = new File(getTempDir(), CanWriteFileFilterTest.class.getName()
+                + ".zip");
+        zipDir(testDir, "", zipFile);
+        zipFileObj = getZipFileObject(zipFile);
+
+    }
+
+    @AfterClass
+    public static void afterClass() throws IOException {
+
+        writeableFileInfo = null;
+        writeableFile.delete();
+        writeableFile = null;
+
+        readOnlyFileInfo = null;
+        readOnlyFile.delete();
+        readOnlyFile = null;
+
+        notExistingFileInfo = null;
+        notExistingFile = null;
+
+        zipFileObj.close();
+        FileUtils.deleteQuietly(zipFile);
+        zipFile = null;
+
+        FileUtils.deleteDirectory(testDir);
+        testDir = null;
+
+    }
+
+    @Test
+    public void testAcceptCanWrite() {
+
+        Assert.assertTrue(CanWriteFileFilter.CAN_WRITE
+                .accept(writeableFileInfo));
+        Assert.assertFalse(CanWriteFileFilter.CAN_WRITE
+                .accept(readOnlyFileInfo));
+        Assert.assertTrue(CanWriteFileFilter.CAN_WRITE
+                .accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testAcceptCannotWrite() {
+
+        Assert.assertFalse(CanWriteFileFilter.CANNOT_WRITE
+                .accept(writeableFileInfo));
+        Assert.assertTrue(CanWriteFileFilter.CANNOT_WRITE
+                .accept(readOnlyFileInfo));
+        Assert.assertFalse(CanWriteFileFilter.CANNOT_WRITE
+                .accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testAcceptZipFile() throws FileSystemException {
+
+        FileObject[] files;
+
+        // CAN_WRITE Filter
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                CanWriteFileFilter.CAN_WRITE));
+        Assert.assertTrue(files == null || files.length == 0);
+
+        // CANNOT_WRITE Filter
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                CanWriteFileFilter.CANNOT_WRITE));
+        assertContains(files, READONLY, WRITEABLE);
+        Assert.assertEquals(2, files.length);
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/DirectoryAndFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/DirectoryAndFileFilterTest.java
new file mode 100644
index 0000000..797eb66
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/DirectoryAndFileFilterTest.java
@@ -0,0 +1,161 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSelector;
+import org.apache.commons.vfs2.FileSystemException;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test for {@link DirectoryFileFilter} and {@link FileFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class DirectoryAndFileFilterTest extends BaseFilterTest {
+
+    private static final String FILE = "myfile.txt";
+
+    private static final String DIR = "mydir";
+
+    private static File testDir;
+
+    private static File file;
+
+    private static FileSelectInfo fileInfo;
+
+    private static File dir;
+
+    private static FileSelectInfo dirInfo;
+
+    private static File notExistingFile;
+
+    private static FileSelectInfo notExistingFileInfo;
+
+    private static File zipFile;
+
+    private static FileObject zipFileObj;
+
+    @BeforeClass
+    public static void beforeClass() throws IOException {
+
+        testDir = getTestDir(DirectoryAndFileFilterTest.class.getName());
+        testDir.mkdir();
+
+        dir = new File(testDir, DIR);
+        dir.mkdir();
+        dirInfo = createFSI(dir);
+
+        file = new File(dir, FILE);
+        FileUtils.touch(file);
+        fileInfo = createFSI(file);
+
+        notExistingFile = new File(testDir, "not-existing-file.txt");
+        notExistingFileInfo = createFSI(notExistingFile);
+
+        zipFile = new File(getTempDir(),
+                DirectoryAndFileFilterTest.class.getName() + ".zip");
+        zipDir(testDir, "", zipFile);
+        zipFileObj = getZipFileObject(zipFile);
+
+    }
+
+    @AfterClass
+    public static void afterClass() throws IOException {
+
+        file = null;
+        fileInfo = null;
+
+        dir = null;
+        dirInfo = null;
+
+        notExistingFileInfo = null;
+        notExistingFile = null;
+
+        zipFileObj.close();
+        FileUtils.deleteQuietly(zipFile);
+        zipFile = null;
+
+        FileUtils.deleteDirectory(testDir);
+
+        testDir = null;
+
+    }
+
+    @Test
+    public void testDirectoryFileFilter() {
+
+        final FileFilter testee = DirectoryFileFilter.DIRECTORY;
+
+        Assert.assertTrue(testee.accept(dirInfo));
+        Assert.assertFalse(testee.accept(fileInfo));
+        Assert.assertFalse(testee.accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testFileFileFilter() {
+
+        final FileFilter testee = FileFileFilter.FILE;
+
+        Assert.assertTrue(testee.accept(fileInfo));
+        Assert.assertFalse(testee.accept(dirInfo));
+        Assert.assertFalse(testee.accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testAcceptZipFile() throws FileSystemException {
+
+        FileObject[] files;
+
+        // FILE Filter
+        files = zipFileObj.findFiles(new FileSelector() {
+            @Override
+            public boolean traverseDescendents(final FileSelectInfo fileInfo)
+                    throws Exception {
+                return true;
+            }
+
+            @Override
+            public boolean includeFile(final FileSelectInfo fileInfo)
+                    throws Exception {
+                return FileFileFilter.FILE.accept(fileInfo);
+            }
+        });
+        assertContains(files, FILE);
+        Assert.assertEquals(1, files.length);
+
+        // DIRECTORY Filter
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                DirectoryFileFilter.DIRECTORY));
+        assertContains(files, DIR);
+        Assert.assertEquals(1, files.length);
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/EmptyFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/EmptyFileFilterTest.java
new file mode 100644
index 0000000..7b5176b
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/EmptyFileFilterTest.java
@@ -0,0 +1,165 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test for {@link EmptyFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class EmptyFileFilterTest extends BaseFilterTest {
+
+    private static File testDir;
+
+    private static File notEmptyFile;
+
+    private static FileSelectInfo notEmptyFileInfo;
+
+    private static File emptyFile;
+
+    private static FileSelectInfo emptyFileInfo;
+
+    private static File notEmptyDir;
+
+    private static FileSelectInfo notEmptyDirInfo;
+
+    private static File emptyDir;
+
+    private static FileSelectInfo emptyDirInfo;
+
+    private static File notExistingFile;
+
+    private static FileSelectInfo notExistingFileInfo;
+
+    private static File zipFile;
+
+    private static FileObject zipFileObj;
+
+    @BeforeClass
+    public static void beforeClass() throws IOException {
+        testDir = getTestDir(EmptyFileFilterTest.class.getName());
+        testDir.mkdir();
+
+        notEmptyFile = new File(testDir, "full.txt");
+        FileUtils.write(notEmptyFile, "whatever");
+        notEmptyFileInfo = createFSI(notEmptyFile);
+
+        emptyFile = new File(testDir, "empty.txt");
+        FileUtils.touch(emptyFile);
+        emptyFileInfo = createFSI(emptyFile);
+
+        notEmptyDir = new File(testDir, "full-dir");
+        notEmptyDir.mkdir();
+        notEmptyDirInfo = createFSI(notEmptyDir);
+        FileUtils.touch(new File(notEmptyDir, "foobar.txt"));
+
+        emptyDir = new File(testDir, "empty-dir");
+        emptyDir.mkdir();
+        emptyDirInfo = createFSI(emptyDir);
+
+        notExistingFile = new File(testDir, "not-existing-file.txt");
+        notExistingFileInfo = createFSI(notExistingFile);
+
+        // Zip the test directory
+        zipFile = new File(getTempDir(), EmptyFileFilterTest.class.getName()
+                + ".zip");
+        zipDir(testDir, "", zipFile);
+        zipFileObj = getZipFileObject(zipFile);
+
+    }
+
+    @AfterClass
+    public static void afterClass() throws IOException {
+
+        notEmptyFile = null;
+        notEmptyFileInfo = null;
+        emptyFile = null;
+        emptyFileInfo = null;
+        notEmptyDir = null;
+        notEmptyDirInfo = null;
+        emptyDir = null;
+        emptyDirInfo = null;
+        notExistingFile = null;
+        notExistingFileInfo = null;
+
+        zipFileObj.close();
+        FileUtils.deleteQuietly(zipFile);
+        zipFile = null;
+
+        FileUtils.deleteDirectory(testDir);
+        testDir = null;
+    }
+
+    @Test
+    public void testAcceptEmpty() {
+
+        final FileFilter testee = EmptyFileFilter.EMPTY;
+
+        Assert.assertFalse(testee.accept(notEmptyFileInfo));
+        Assert.assertTrue(testee.accept(emptyFileInfo));
+        Assert.assertFalse(testee.accept(notEmptyDirInfo));
+        Assert.assertTrue(testee.accept(emptyDirInfo));
+        Assert.assertTrue(testee.accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testAcceptNotEmpty() {
+
+        final FileFilter testee = EmptyFileFilter.NOT_EMPTY;
+
+        Assert.assertTrue(testee.accept(notEmptyFileInfo));
+        Assert.assertFalse(testee.accept(emptyFileInfo));
+        Assert.assertTrue(testee.accept(notEmptyDirInfo));
+        Assert.assertFalse(testee.accept(emptyDirInfo));
+        Assert.assertFalse(testee.accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testZipFile() throws FileSystemException {
+
+        // Same test with ZIP file
+        FileObject[] files;
+
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                EmptyFileFilter.EMPTY));
+        assertContains(files, emptyFile.getName());
+        Assert.assertEquals(1, files.length);
+
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                EmptyFileFilter.NOT_EMPTY));
+        assertContains(files, notEmptyFile.getName(), notEmptyDir.getName());
+        Assert.assertEquals(2, files.length);
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/HiddenFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/HiddenFileFilterTest.java
new file mode 100644
index 0000000..eafbfba
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/HiddenFileFilterTest.java
@@ -0,0 +1,144 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test for {@link HiddenFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class HiddenFileFilterTest extends BaseFilterTest {
+
+    private static File testDir;
+
+    private static File visibleFile;
+
+    private static FileSelectInfo visibleFileInfo;
+
+    private static File hiddenFile;
+
+    private static FileSelectInfo hiddenFileInfo;
+
+    private static File notExistingFile;
+
+    private static FileSelectInfo notExistingFileInfo;
+
+    private static File zipFile;
+
+    private static FileObject zipFileObj;
+
+    @BeforeClass
+    public static void beforeClass() throws IOException {
+        testDir = getTestDir(HiddenFileFilterTest.class.getName());
+        testDir.mkdir();
+
+        visibleFile = new File(testDir, "visible.txt");
+        FileUtils.touch(visibleFile);
+        visibleFileInfo = createFSI(visibleFile);
+
+        hiddenFile = new File(testDir, "hidden.txt");
+        // TODO xxx In Java 6 there is no way to hide a file
+        // hiddenFile.setVisible(false);
+        hiddenFileInfo = createFSI(hiddenFile);
+
+        notExistingFile = new File(testDir, "not-existing-file.txt");
+        notExistingFileInfo = createFSI(notExistingFile);
+
+        // Zip the test directory
+        zipFile = new File(getTempDir(), HiddenFileFilterTest.class.getName()
+                + ".zip");
+        zipDir(testDir, "", zipFile);
+        zipFileObj = getZipFileObject(zipFile);
+
+    }
+
+    @AfterClass
+    public static void afterClass() throws IOException {
+
+        visibleFile = null;
+        visibleFileInfo = null;
+        hiddenFile = null;
+        hiddenFileInfo = null;
+        notExistingFile = null;
+        notExistingFileInfo = null;
+
+        zipFileObj.close();
+        FileUtils.deleteQuietly(zipFile);
+        zipFile = null;
+
+        FileUtils.deleteDirectory(testDir);
+        testDir = null;
+    }
+
+    @Test
+    public void testAcceptHidden() {
+
+        final FileFilter testee = HiddenFileFilter.HIDDEN;
+
+        Assert.assertFalse(testee.accept(visibleFileInfo));
+        // TODO xxx In Java 6 there is no way to hide a file
+        // assertThat(testee.accept(hiddenFileInfo));
+        Assert.assertFalse(testee.accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testAcceptVisible() {
+
+        final FileFilter testee = HiddenFileFilter.VISIBLE;
+
+        Assert.assertTrue(testee.accept(visibleFileInfo));
+        // TODO xxx In Java 6 there is no way to hide a file
+        // assertThat(testee.accept(hiddenFileInfo));
+        Assert.assertTrue(testee.accept(notExistingFileInfo));
+
+    }
+
+    @Test
+    public void testZipFile() throws FileSystemException {
+
+        // Same test with ZIP file
+        FileObject[] files;
+
+        // TODO xxx In Java 6 there is no way to hide a file
+        // files = zipFileObj.findFiles(new
+        // FileFilterSelector(HiddenFileFilter.HIDDEN));
+        // assertContains(files, hiddenFile.getName());
+        // assertThat(files).hasSize(1);
+
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                HiddenFileFilter.VISIBLE));
+        assertContains(files, visibleFile.getName());
+        Assert.assertEquals(1, files.length);
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/NameFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/NameFileFilterTest.java
new file mode 100644
index 0000000..9384037
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/NameFileFilterTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link NameFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class NameFileFilterTest extends BaseFilterTest {
+
+    @Test
+    public void testAcceptList() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add("test1.txt");
+        list.add("test2.txt");
+        final NameFileFilter filter = new NameFileFilter(list);
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptListIOCaseInsensitive() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add("test1.txt");
+        list.add("test2.txt");
+        final NameFileFilter filter = new NameFileFilter(IOCase.INSENSITIVE, list);
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("TEST1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptListIOCaseSensitive() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add("test1.txt");
+        list.add("test2.txt");
+        final NameFileFilter filter = new NameFileFilter(IOCase.SENSITIVE, list);
+
+        // TEST
+        Assert.assertFalse(filter.accept(createFSI(new File("TEST1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptString() {
+
+        // PREPARE
+        final NameFileFilter filter = new NameFileFilter("test1.txt");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptStringIOCaseInsensitive() {
+
+        // PREPARE
+        final NameFileFilter filter = new NameFileFilter(IOCase.INSENSITIVE,
+                "test2.txt");
+
+        // TEST
+        Assert.assertFalse(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptStringIOCaseSensitive() {
+
+        // PREPARE
+        final NameFileFilter filter = new NameFileFilter(IOCase.SENSITIVE,
+                "test2.txt");
+
+        // TEST
+        Assert.assertFalse(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/NotFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/NotFileFilterTest.java
new file mode 100644
index 0000000..cca5fe6
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/NotFileFilterTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link NotFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class NotFileFilterTest extends BaseFilterTest {
+
+    @Test
+    public void testAccept() {
+
+        final FileSelectInfo any = createFSI(new File("test1.txt"));
+
+        Assert.assertFalse(new NotFileFilter(TrueFileFilter.TRUE).accept(any));
+        Assert.assertTrue(new NotFileFilter(FalseFileFilter.FALSE).accept(any));
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/OrFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/OrFileFilterTest.java
new file mode 100644
index 0000000..cc708f6
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/OrFileFilterTest.java
@@ -0,0 +1,182 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.junit.Assert;
+import org.junit.Test;
+
+// CHECKSTYLE:OFF Test code
+public class OrFileFilterTest extends BaseFilterTest {
+
+    @Test
+    public void testOrFileFilterFileFilter() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+
+        // TEST
+        final OrFileFilter testee = new OrFileFilter(filter1, filter2, filter3);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter2, filter3);
+
+    }
+
+    @Test
+    public void testOrFileFilterList() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+        final List<FileFilter> list = new ArrayList<>();
+        list.add(filter1);
+        list.add(filter2);
+        list.add(filter3);
+
+        // TEST
+        final OrFileFilter testee = new OrFileFilter(list);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter2, filter3);
+
+    }
+
+    @Test
+    public void testAddFileFilter() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+
+        // TEST
+        final OrFileFilter testee = new OrFileFilter();
+        testee.addFileFilter(filter1);
+        testee.addFileFilter(filter2);
+        testee.addFileFilter(filter3);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter2, filter3);
+
+    }
+
+    @Test
+    public void testRemoveFileFilter() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+        final OrFileFilter testee = new OrFileFilter(filter1, filter2, filter3);
+
+        // TEST
+        testee.removeFileFilter(filter2);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter3);
+
+    }
+
+    @Test
+    public void testSetFileFilters() {
+
+        // PREPARE
+        final FileFilter filter1 = new DummyFilter();
+        final FileFilter filter2 = new DummyFilter();
+        final FileFilter filter3 = new DummyFilter();
+        final List<FileFilter> list = new ArrayList<>();
+        list.add(filter1);
+        list.add(filter2);
+        list.add(filter3);
+        final OrFileFilter testee = new OrFileFilter();
+
+        // TEST
+        testee.setFileFilters(list);
+
+        // VERIFY
+        assertContainsOnly(testee.getFileFilters(), filter1, filter2, filter3);
+
+    }
+
+    @Test
+    public void testAccept() {
+
+        final FileSelectInfo any = createFSI(new File("anyfile"));
+
+        // Empty
+        Assert.assertFalse(new OrFileFilter().accept(any));
+
+        // True
+        Assert.assertTrue(new OrFileFilter(new True()).accept(any));
+        Assert.assertTrue(new OrFileFilter(new True(), new True()).accept(any));
+        Assert.assertTrue(new OrFileFilter(new False(), new True()).accept(any));
+        Assert.assertTrue(new OrFileFilter(new True(), new False()).accept(any));
+
+        // False
+        Assert.assertFalse(new OrFileFilter(new False()).accept(any));
+        Assert.assertFalse(new OrFileFilter(new False(), new False())
+                .accept(any));
+
+    }
+
+    /**
+     * Just a filter class.
+     */
+    private static class DummyFilter implements FileFilter {
+
+        @Override
+        public boolean accept(final FileSelectInfo fileInfo) {
+            return false;
+        }
+
+    }
+
+    /**
+     * Always TRUE.
+     */
+    private static class True implements FileFilter {
+
+        @Override
+        public boolean accept(final FileSelectInfo fileInfo) {
+            return true;
+        }
+
+    }
+
+    /**
+     * Always FALSE.
+     */
+    private static class False implements FileFilter {
+
+        @Override
+        public boolean accept(final FileSelectInfo fileInfo) {
+            return false;
+        }
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/PrefixFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/PrefixFileFilterTest.java
new file mode 100644
index 0000000..d9f1451
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/PrefixFileFilterTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link PrefixFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class PrefixFileFilterTest extends BaseFilterTest {
+
+    @Test
+    public void testAcceptList() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add("test1");
+        list.add("test2");
+        final PrefixFileFilter filter = new PrefixFileFilter(list);
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptListIOCaseInsensitive() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add("test1");
+        list.add("test2");
+        final PrefixFileFilter filter = new PrefixFileFilter(IOCase.INSENSITIVE, list);
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("TEST1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptListIOCaseSensitive() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add("test1");
+        list.add("test2");
+        final PrefixFileFilter filter = new PrefixFileFilter(IOCase.SENSITIVE, list);
+
+        // TEST
+        Assert.assertFalse(filter.accept(createFSI(new File("TEST1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptString() {
+
+        // PREPARE
+        final PrefixFileFilter filter = new PrefixFileFilter("test");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptStringIOCaseInsensitive() {
+
+        // PREPARE
+        final PrefixFileFilter filter = new PrefixFileFilter(IOCase.INSENSITIVE,
+                "test");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptStringIOCaseSensitive() {
+
+        // PREPARE
+        final PrefixFileFilter filter = new PrefixFileFilter(IOCase.SENSITIVE, "test");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("Test2.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/RegexFileFilterTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/RegexFileFilterTestCase.java
new file mode 100644
index 0000000..5b52657
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/RegexFileFilterTestCase.java
@@ -0,0 +1,112 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.util.regex.Pattern;
+
+import org.apache.commons.vfs2.FileFilter;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link RegexFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class RegexFileFilterTestCase extends BaseFilterTest {
+
+    @Test
+    public void testRegex() throws Exception {
+
+        FileFilter filter;
+
+        filter = new RegexFileFilter("^.*[tT]est(-\\d+)?\\.java$");
+        Assert.assertTrue(filter.accept(createFSI(new File("Test.java"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test-10.java"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test-.java"))));
+
+        filter = new RegexFileFilter("^[Tt]est.java$");
+        Assert.assertTrue(filter.accept(createFSI(new File("Test.java"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.java"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("tEST.java"))));
+
+        filter = new RegexFileFilter(Pattern.compile("^test.java$",
+                Pattern.CASE_INSENSITIVE));
+        Assert.assertTrue(filter.accept(createFSI(new File("Test.java"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.java"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("tEST.java"))));
+
+        filter = new RegexFileFilter("^test.java$", Pattern.CASE_INSENSITIVE);
+        Assert.assertTrue(filter.accept(createFSI(new File("Test.java"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.java"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("tEST.java"))));
+
+        filter = new RegexFileFilter("^test.java$", IOCase.INSENSITIVE);
+        Assert.assertTrue(filter.accept(createFSI(new File("Test.java"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.java"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("tEST.java"))));
+
+    }
+
+    @Test
+    public void testStringNullArgConstruction() {
+        try {
+            new RegexFileFilter((String) null);
+            fail();
+        } catch (final IllegalArgumentException ex) {
+            Assert.assertEquals(RegexFileFilter.PATTERN_IS_MISSING,
+                    ex.getMessage());
+        }
+    }
+
+    @Test
+    public void testPatternNullArgConstruction() {
+        try {
+            new RegexFileFilter((Pattern) null);
+            fail();
+        } catch (final IllegalArgumentException ex) {
+            Assert.assertEquals(RegexFileFilter.PATTERN_IS_MISSING,
+                    ex.getMessage());
+        }
+    }
+
+    @Test
+    public void testStringPatternNullArgConstruction() {
+        try {
+            new RegexFileFilter((String) null, Pattern.CASE_INSENSITIVE);
+            fail();
+        } catch (final IllegalArgumentException ex) {
+            Assert.assertEquals(RegexFileFilter.PATTERN_IS_MISSING,
+                    ex.getMessage());
+        }
+    }
+
+    @Test
+    public void testStringIOCaseNullArgConstruction() {
+        try {
+            new RegexFileFilter((String) null, IOCase.INSENSITIVE);
+            fail();
+        } catch (final IllegalArgumentException ex) {
+            Assert.assertEquals(RegexFileFilter.PATTERN_IS_MISSING,
+                    ex.getMessage());
+        }
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/SizeFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/SizeFileFilterTest.java
new file mode 100644
index 0000000..7bf58f3
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/SizeFileFilterTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.vfs2.FileFilterSelector;
+import org.apache.commons.vfs2.FileObject;
+import org.apache.commons.vfs2.FileSelectInfo;
+import org.apache.commons.vfs2.FileSystemException;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+/**
+ * Test for {@link SizeFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class SizeFileFilterTest extends BaseFilterTest {
+
+    private static File testDir;
+
+    private static File minFile;
+
+    private static FileSelectInfo minFileInfo;
+
+    private static File optFile;
+
+    private static FileSelectInfo optFileInfo;
+
+    private static File maxFile;
+
+    private static FileSelectInfo maxFileInfo;
+
+    private static File zipFile;
+
+    private static FileObject zipFileObj;
+
+    @BeforeClass
+    public static void beforeClass() throws IOException {
+        testDir = getTestDir(SizeFileFilterTest.class.getName());
+
+        // 2 characters
+        minFile = new File(testDir, "min.txt");
+        FileUtils.write(minFile, "12");
+        minFileInfo = createFSI(minFile);
+
+        // 4 characters
+        optFile = new File(testDir, "opt.txt");
+        FileUtils.write(optFile, "1234");
+        optFileInfo = createFSI(optFile);
+
+        // 6 characters
+        maxFile = new File(testDir, "max.txt");
+        FileUtils.write(maxFile, "123456");
+        maxFileInfo = createFSI(maxFile);
+
+        // Zip the test directory
+        zipFile = new File(getTempDir(), SizeFileFilterTest.class.getName()
+                + ".zip");
+        zipDir(testDir, "", zipFile);
+        zipFileObj = getZipFileObject(zipFile);
+
+    }
+
+    @AfterClass
+    public static void afterClass() throws IOException {
+
+        minFileInfo = null;
+        minFile = null;
+
+        optFileInfo = null;
+        optFile = null;
+
+        maxFileInfo = null;
+        maxFile = null;
+
+        zipFileObj.close();
+        FileUtils.deleteQuietly(zipFile);
+        zipFile = null;
+
+        FileUtils.deleteDirectory(testDir);
+        testDir = null;
+    }
+
+    @Test
+    public void testSizeFileFilterLong() {
+
+        final SizeFileFilter testee = new SizeFileFilter(4);
+        Assert.assertFalse(testee.accept(minFileInfo));
+        Assert.assertTrue(testee.accept(optFileInfo));
+        Assert.assertTrue(testee.accept(maxFileInfo));
+
+    }
+
+    @Test
+    public void testSizeFileFilterLongBoolean() {
+
+        SizeFileFilter testee;
+
+        testee = new SizeFileFilter(4, true);
+        Assert.assertFalse(testee.accept(minFileInfo));
+        Assert.assertTrue(testee.accept(optFileInfo));
+        Assert.assertTrue(testee.accept(maxFileInfo));
+
+        testee = new SizeFileFilter(4, false);
+        Assert.assertTrue(testee.accept(minFileInfo));
+        Assert.assertFalse(testee.accept(optFileInfo));
+        Assert.assertFalse(testee.accept(maxFileInfo));
+
+    }
+
+    @Test
+    public void testSizeRangeFileFilter() {
+
+        SizeRangeFileFilter testee;
+
+        testee = new SizeRangeFileFilter(2, 6);
+        Assert.assertTrue(testee.accept(minFileInfo));
+        Assert.assertTrue(testee.accept(optFileInfo));
+        Assert.assertTrue(testee.accept(maxFileInfo));
+
+        testee = new SizeRangeFileFilter(3, 6);
+        Assert.assertFalse(testee.accept(minFileInfo));
+        Assert.assertTrue(testee.accept(optFileInfo));
+        Assert.assertTrue(testee.accept(maxFileInfo));
+
+        testee = new SizeRangeFileFilter(2, 5);
+        Assert.assertTrue(testee.accept(minFileInfo));
+        Assert.assertTrue(testee.accept(optFileInfo));
+        Assert.assertFalse(testee.accept(maxFileInfo));
+
+        testee = new SizeRangeFileFilter(3, 5);
+        Assert.assertFalse(testee.accept(minFileInfo));
+        Assert.assertTrue(testee.accept(optFileInfo));
+        Assert.assertFalse(testee.accept(maxFileInfo));
+
+        testee = new SizeRangeFileFilter(4, 4);
+        Assert.assertFalse(testee.accept(minFileInfo));
+        Assert.assertTrue(testee.accept(optFileInfo));
+        Assert.assertFalse(testee.accept(maxFileInfo));
+
+    }
+
+    @Test
+    public void testSizeFileFilterZipDir() throws FileSystemException {
+
+        // Same test with ZIP file
+        FileObject[] files;
+
+        files = zipFileObj.findFiles(new FileFilterSelector(new SizeFileFilter(
+                4, true)));
+        assertContains(files, optFile.getName(), maxFile.getName());
+        Assert.assertEquals(2, files.length);
+
+        files = zipFileObj.findFiles(new FileFilterSelector(new SizeFileFilter(
+                4, false)));
+        assertContains(files, minFile.getName());
+        Assert.assertEquals(1, files.length);
+
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                new SizeRangeFileFilter(2, 6)));
+        assertContains(files, minFile.getName(), optFile.getName(),
+                maxFile.getName());
+        Assert.assertEquals(3, files.length);
+
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                new SizeRangeFileFilter(3, 6)));
+        assertContains(files, optFile.getName(), maxFile.getName());
+        Assert.assertEquals(2, files.length);
+
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                new SizeRangeFileFilter(2, 5)));
+        assertContains(files, minFile.getName(), optFile.getName());
+        Assert.assertEquals(2, files.length);
+
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                new SizeRangeFileFilter(3, 5)));
+        assertContains(files, optFile.getName());
+        Assert.assertEquals(1, files.length);
+
+        files = zipFileObj.findFiles(new FileFilterSelector(
+                new SizeRangeFileFilter(4, 4)));
+        assertContains(files, optFile.getName());
+        Assert.assertEquals(1, files.length);
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/SuffixFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/SuffixFileFilterTest.java
new file mode 100644
index 0000000..f202727
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/SuffixFileFilterTest.java
@@ -0,0 +1,128 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link SuffixFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class SuffixFileFilterTest extends BaseFilterTest {
+
+    @Test
+    public void testAcceptList() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add(".txt");
+        list.add(".bin");
+        final SuffixFileFilter filter = new SuffixFileFilter(list);
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.bin"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test2.BIN"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptListIOCaseInsensitive() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add(".txt");
+        list.add(".bin");
+        final SuffixFileFilter filter = new SuffixFileFilter(IOCase.INSENSITIVE, list);
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("TEST1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.bin"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.TXT"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptListIOCaseSensitive() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add(".txt");
+        list.add(".bin");
+        final SuffixFileFilter filter = new SuffixFileFilter(IOCase.SENSITIVE, list);
+
+        // TEST
+        Assert.assertFalse(filter.accept(createFSI(new File("test1.Txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test2.BIN"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptString() {
+
+        // PREPARE
+        final SuffixFileFilter filter = new SuffixFileFilter(".txt", ".xxx");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test2.TXT"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptStringIOCaseInsensitive() {
+
+        // PREPARE
+        final SuffixFileFilter filter = new SuffixFileFilter(IOCase.INSENSITIVE,
+                ".txt", ".xxx");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.TXT"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptStringIOCaseSensitive() {
+
+        // PREPARE
+        final SuffixFileFilter filter = new SuffixFileFilter(IOCase.SENSITIVE,
+                ".txt", ".xxx");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test2.TXT"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/WildcardFileFilterTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/WildcardFileFilterTest.java
new file mode 100644
index 0000000..90cf27e
--- /dev/null
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/filter/WildcardFileFilterTest.java
@@ -0,0 +1,172 @@
+/*
+ * 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.commons.vfs2.filter;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link WildcardFileFilter}.
+ */
+// CHECKSTYLE:OFF Test code
+public class WildcardFileFilterTest extends BaseFilterTest {
+
+    @Test
+    public void testAcceptList() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add("*.txt");
+        list.add("*.a??");
+        final WildcardFileFilter filter = new WildcardFileFilter(list);
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.a"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ab"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.abc"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ABC"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aaa"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.Aaa"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aAA"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.abcd"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptListIOCaseInsensitive() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add("*.txt");
+        list.add("*.a??");
+        final WildcardFileFilter filter = new WildcardFileFilter(IOCase.INSENSITIVE,
+                list);
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.a"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ab"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.abc"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.ABC"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aaa"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.Aaa"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aAA"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.abcd"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptListIOCaseSensitive() {
+
+        // PREPARE
+        final List<String> list = new ArrayList<>();
+        list.add("*.txt");
+        list.add("*.a??");
+        final WildcardFileFilter filter = new WildcardFileFilter(IOCase.SENSITIVE,
+                list);
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.a"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ab"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.abc"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ABC"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aaa"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.Aaa"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aAA"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.abcd"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptString() {
+
+        // PREPARE
+        final WildcardFileFilter filter = new WildcardFileFilter("*.txt", "*.a??");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.a"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ab"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.abc"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ABC"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aaa"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.Aaa"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aAA"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.abcd"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptStringIOCaseInsensitive() {
+
+        // PREPARE
+        final WildcardFileFilter filter = new WildcardFileFilter(IOCase.INSENSITIVE,
+                "*.txt", "*.a??");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.a"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ab"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.abc"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.ABC"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aaa"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.Aaa"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aAA"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.abcd"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+    @Test
+    public void testAcceptStringIOCaseSensitive() {
+
+        // PREPARE
+        final WildcardFileFilter filter = new WildcardFileFilter(IOCase.SENSITIVE,
+                "*.txt", "*.a??");
+
+        // TEST
+        Assert.assertTrue(filter.accept(createFSI(new File("test1.txt"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test2.txt"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.a"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ab"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.abc"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.ABC"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aaa"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.Aaa"))));
+        Assert.assertTrue(filter.accept(createFSI(new File("test.aAA"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.abcd"))));
+        Assert.assertFalse(filter.accept(createFSI(new File("test.xxx"))));
+
+    }
+
+}
+// CHECKSTYLE:ON
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/UriParserTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/UriParserTestCase.java
index 4e50678..4b481fd 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/UriParserTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/UriParserTestCase.java
@@ -61,14 +61,14 @@ public class UriParserTestCase {
 
 	@Test
 	public void testNormalSchemeWithBuffer() {
-		StringBuilder buffer = new StringBuilder();
+		final StringBuilder buffer = new StringBuilder();
 		UriParser.extractScheme(schemes, "ftp://user:pass@host/some/path/some:file", buffer);
 		Assert.assertEquals("//user:pass@host/some/path/some:file", buffer.toString());
 	}
 
 	@Test
 	public void testOneSlashSchemeWithBuffer() {
-		StringBuilder buffer = new StringBuilder();
+		final StringBuilder buffer = new StringBuilder();
 		UriParser.extractScheme(schemes, "file:/user:pass@host/some/path/some:file", buffer);
 		Assert.assertEquals("/user:pass@host/some/path/some:file", buffer.toString());
 	}
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ram/test/CustomRamProviderTest.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ram/test/CustomRamProviderTest.java
index bd16042..9277950 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ram/test/CustomRamProviderTest.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/ram/test/CustomRamProviderTest.java
@@ -254,9 +254,9 @@ public class CustomRamProviderTest {
      */
     @Test
     public void testMoveFile() throws FileSystemException {
-        FileObject fileSource = manager.resolveFile("ram://virtual/source");
+        final FileObject fileSource = manager.resolveFile("ram://virtual/source");
         fileSource.createFile();
-        FileObject fileDest = manager.resolveFile("ram://virtual/dest");
+        final FileObject fileDest = manager.resolveFile("ram://virtual/dest");
         Assert.assertTrue(fileSource.canRenameTo(fileDest));
         fileSource.moveTo(fileDest);
     }
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/zip/ZipProviderWithCharsetNullTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/zip/ZipProviderWithCharsetNullTestCase.java
index 464b0c8..a247894 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/zip/ZipProviderWithCharsetNullTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/zip/ZipProviderWithCharsetNullTestCase.java
@@ -63,10 +63,10 @@ public class ZipProviderWithCharsetNullTestCase extends AbstractProviderTestConf
 
         final File zipFile = AbstractVfsTestCase.getTestResource("test.zip");
         final String uri = "zip:file:" + zipFile.getAbsolutePath() + "!/";
-        FileObject resolvedFile = manager.resolveFile(uri, opts);
-        FileSystem fileSystem = resolvedFile.getFileSystem();
+        final FileObject resolvedFile = manager.resolveFile(uri, opts);
+        final FileSystem fileSystem = resolvedFile.getFileSystem();
         Assert.assertTrue(fileSystem instanceof ZipFileSystem);
-        ZipFileSystem zipFileSystem = (ZipFileSystem) fileSystem;
+        final ZipFileSystem zipFileSystem = (ZipFileSystem) fileSystem;
         Assert.assertEquals(null, zipFileSystem.getCharset());
         return resolvedFile;
     }
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/zip/ZipProviderWithCharsetTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/zip/ZipProviderWithCharsetTestCase.java
index 6f5d3db..b551841 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/zip/ZipProviderWithCharsetTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/zip/ZipProviderWithCharsetTestCase.java
@@ -67,10 +67,10 @@ public class ZipProviderWithCharsetTestCase extends AbstractProviderTestConfig {
 
         final File zipFile = AbstractVfsTestCase.getTestResource("test.zip");
         final String uri = "zip:file:" + zipFile.getAbsolutePath() + "!/";
-        FileObject resolvedFile = manager.resolveFile(uri, opts);
-        FileSystem fileSystem = resolvedFile.getFileSystem();
+        final FileObject resolvedFile = manager.resolveFile(uri, opts);
+        final FileSystem fileSystem = resolvedFile.getFileSystem();
         Assert.assertTrue(fileSystem instanceof ZipFileSystem);
-        ZipFileSystem zipFileSystem = (ZipFileSystem) fileSystem;
+        final ZipFileSystem zipFileSystem = (ZipFileSystem) fileSystem;
         Assert.assertEquals(StandardCharsets.UTF_8, zipFileSystem.getCharset());
         return resolvedFile;
     }
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/test/AbstractProviderTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/test/AbstractProviderTestCase.java
index 589e871..9fb630f 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/test/AbstractProviderTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/test/AbstractProviderTestCase.java
@@ -114,7 +114,7 @@ public abstract class AbstractProviderTestCase extends AbstractVfsTestCase {
     }
 
     protected FileSystem getFileSystem() {
-        FileObject rFolder = getReadFolder();
+        final FileObject rFolder = getReadFolder();
         Assert.assertNotNull("This test's read folder should not be null", rFolder);
         return rFolder.getFileSystem();
     }
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/test/AbstractTestSuite.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/test/AbstractTestSuite.java
index e98d58d..7c153a8 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/test/AbstractTestSuite.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/test/AbstractTestSuite.java
@@ -296,14 +296,14 @@ public abstract class AbstractTestSuite extends TestSetup {
     private Thread[] diffThreadSnapshot(final Thread[] startThreadSnapshot, final Thread[] endThreadSnapshot) {
         final List<Thread> diff = new ArrayList<>(10);
 
-        nextEnd: for (int iterEnd = 0; iterEnd < endThreadSnapshot.length; iterEnd++) {
-            for (int iterStart = 0; iterStart < startThreadSnapshot.length; iterStart++) {
-                if (startThreadSnapshot[iterStart] == endThreadSnapshot[iterEnd]) {
+        nextEnd: for (final Thread element : endThreadSnapshot) {
+            for (final Thread element2 : startThreadSnapshot) {
+                if (element2 == element) {
                     continue nextEnd;
                 }
             }
 
-            diff.add(endThreadSnapshot[iterEnd]);
+            diff.add(element);
         }
 
         final Thread ret[] = new Thread[diff.size()];
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 627071a..152d9e1 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -65,6 +65,9 @@ The <action> type attribute can be add,update,fix,remove.
       <action issue="VFS-696" dev="ggregory" type="fix" due-to="rayzzed">
         SFTP HTTP and SOCKS proxy authentication. GitHub PR #49.
       </action>
+      <action issue="VFS-497" dev="ggregory" type="add" due-to="Michael Schnell">
+        Ported filters from Commons IO #9.
+      </action>
     </release>
     <release version="2.3" date="2019-02-01" description="New features and bug fix release.">
       <action issue="VFS-645" dev="ggregory" type="fix">