Reduce thread leaks in tests from 76 to 29.
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/VFS.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/VFS.java
index c8614f0..43250aa 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/VFS.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/VFS.java
@@ -53,17 +53,18 @@
     private static FileSystemManager createFileSystemManager(final String managerClassName) throws FileSystemException {
         try {
             // Create instance
-            final Class<?> mgrClass = Class.forName(managerClassName);
-            final FileSystemManager mgr = (FileSystemManager) mgrClass.newInstance();
+            final Class<FileSystemManager> clazz = (Class<FileSystemManager>) Class.forName(managerClassName);
+            final FileSystemManager manager = clazz.newInstance();
 
             try {
                 // Initialize
-                mgrClass.getMethod("init", (Class[]) null).invoke(mgr, (Object[]) null);
-            } catch (final NoSuchMethodException ignored) {
+                clazz.getMethod("init", (Class[]) null).invoke(manager, (Object[]) null);
+            } catch (final NoSuchMethodException e) {
                 /* Ignore; don't initialize. */
+                e.printStackTrace();
             }
 
-            return mgr;
+            return manager;
         } catch (final InvocationTargetException e) {
             throw new FileSystemException("vfs/create-manager.error", managerClassName, e.getTargetException());
         } catch (final Exception e) {
@@ -101,7 +102,7 @@
      * @throws FileSystemException if an error occurs creating the manager.
      * @since 2.5.0
      */
-    public static FileSystemManager reset() throws FileSystemException {
+    public static synchronized FileSystemManager reset() throws FileSystemException {
         close();
         return instance = createFileSystemManager("org.apache.commons.vfs2.impl.StandardFileSystemManager");
     }
@@ -124,5 +125,6 @@
     }
 
     private VFS() {
+        // no public instantiation.
     }
 }
diff --git a/commons-vfs2/src/main/java/org/apache/commons/vfs2/cache/SoftRefFilesCache.java b/commons-vfs2/src/main/java/org/apache/commons/vfs2/cache/SoftRefFilesCache.java
index 4e2da10..1b283ba 100644
--- a/commons-vfs2/src/main/java/org/apache/commons/vfs2/cache/SoftRefFilesCache.java
+++ b/commons-vfs2/src/main/java/org/apache/commons/vfs2/cache/SoftRefFilesCache.java
@@ -30,28 +30,20 @@
 import org.apache.commons.vfs2.FileSystem;
 
 /**
- * This implementation caches every file as long as it is strongly reachable by the java vm. As soon as the vm needs
+ * This implementation caches every file as long as it is strongly reachable by the JVM. As soon as the JVM needs
  * memory - every softly reachable file will be discarded.
  *
  * @see SoftReference
  */
 public class SoftRefFilesCache extends AbstractFilesCache {
 
-    private static final Log log = LogFactory.getLog(SoftRefFilesCache.class);
-
-    private final Map<FileSystem, Map<FileName, Reference<FileObject>>> fileSystemCache = new HashMap<>();
-    private final Map<Reference<FileObject>, FileSystemAndNameKey> refReverseMap = new HashMap<>(100);
-    private final ReferenceQueue<FileObject> refQueue = new ReferenceQueue<>();
-
-    private SoftRefReleaseThread softRefReleaseThread;
-
     /**
-     * This thread will listen on the ReferenceQueue and remove the entry in the filescache as soon as the vm removes
-     * the reference
+     * This thread will listen on the ReferenceQueue and remove the entry in the file cache as soon as the JVM removes
+     * the reference.
      */
-    private final class SoftRefReleaseThread extends Thread {
-        private SoftRefReleaseThread() {
-            setName(SoftRefReleaseThread.class.getName());
+    private final class ReleaseThread extends Thread {
+        private ReleaseThread() {
+            setName(ReleaseThread.class.getName());
             setDaemon(true);
         }
 
@@ -59,37 +51,114 @@
         public void run() {
             try {
                 while (true) {
-                    final Reference<?> ref = refQueue.remove(0);
-                    if (ref == null) {
-                        continue;
-                    }
-
-                    removeFile(ref);
+                    removeFile(refQueue.remove(0));
                 }
             } catch (final InterruptedException e) {
+                // end thread run.
+                // System.out.println("Thread caught InterruptedException, ending " + getId());
+                // System.out.flush();
             }
         }
     }
 
+    private static final Log log = LogFactory.getLog(SoftRefFilesCache.class);
+    private final Map<FileSystem, Map<FileName, Reference<FileObject>>> fileSystemCache = new HashMap<>();
+    private final Map<Reference<FileObject>, FileSystemAndNameKey> refReverseMap = new HashMap<>(100);
+    private final ReferenceQueue<FileObject> refQueue = new ReferenceQueue<>();
+    private ReleaseThread releaseThread;
+
+    /**
+     * Constructs a new instance.
+     */
     public SoftRefFilesCache() {
+        // empty
     }
 
-    private synchronized void startThread() {
-        if (softRefReleaseThread == null) {
-            softRefReleaseThread = new SoftRefReleaseThread();
-            softRefReleaseThread.start();
+    @Override
+    public synchronized void clear(final FileSystem fileSystem) {
+        final Map<FileName, Reference<FileObject>> files = getOrCreateFilesystemCache(fileSystem);
+        final Iterator<FileSystemAndNameKey> iterKeys = refReverseMap.values().iterator();
+
+        while (iterKeys.hasNext()) {
+            final FileSystemAndNameKey key = iterKeys.next();
+            if (key.getFileSystem() == fileSystem) {
+                iterKeys.remove();
+                files.remove(key.getFileName());
+            }
         }
+
+        if (files.isEmpty()) {
+            close(fileSystem);
+        }
+    }
+
+    @Override
+    public synchronized void close() {
+        super.close();
+        endThread();
+        fileSystemCache.clear();
+        refReverseMap.clear();
+    }
+
+    /**
+     * @param fileSystem The file system to close.
+     */
+    private synchronized void close(final FileSystem fileSystem) {
+        if (log.isDebugEnabled()) {
+            log.debug("Close FileSystem: " + fileSystem.getRootName());
+        }
+
+        fileSystemCache.remove(fileSystem);
+        if (fileSystemCache.isEmpty()) {
+            endThread();
+        }
+    }
+
+    protected Reference<FileObject> createReference(final FileObject file, final ReferenceQueue<FileObject> refqueue) {
+        return new SoftReference<>(file, refqueue);
     }
 
     private synchronized void endThread() {
-        final SoftRefReleaseThread thread = softRefReleaseThread;
-        softRefReleaseThread = null;
+        final ReleaseThread thread = releaseThread;
+        releaseThread = null;
         if (thread != null) {
             thread.interrupt();
         }
     }
 
     @Override
+    public synchronized FileObject getFile(final FileSystem fileSystem, final FileName fileName) {
+        final Map<FileName, Reference<FileObject>> files = getOrCreateFilesystemCache(fileSystem);
+
+        final Reference<FileObject> ref = files.get(fileName);
+        if (ref == null) {
+            return null;
+        }
+
+        final FileObject fo = ref.get();
+        if (fo == null) {
+            removeFile(fileSystem, fileName);
+        }
+        return fo;
+    }
+
+    protected synchronized Map<FileName, Reference<FileObject>> getOrCreateFilesystemCache(final FileSystem fileSystem) {
+        if (fileSystemCache.isEmpty()) {
+            startThread();
+        }
+
+        return fileSystemCache.computeIfAbsent(fileSystem, k -> new HashMap<>());
+    }
+
+    private String getSafeName(final FileName fileName) {
+        return fileName.getFriendlyURI();
+    }
+
+    private String getSafeName(final FileObject fileObject) {
+        return this.getSafeName(fileObject.getName());
+    }
+
+    @Override
     public void putFile(final FileObject fileObject) {
         if (log.isDebugEnabled()) {
             log.debug("putFile: " + this.getSafeName(fileObject));
@@ -109,14 +178,6 @@
         }
     }
 
-    private String getSafeName(final FileName fileName) {
-        return fileName.getFriendlyURI();
-    }
-
-    private String getSafeName(final FileObject fileObject) {
-        return this.getSafeName(fileObject.getName());
-    }
-
     @Override
     public boolean putFileIfAbsent(final FileObject fileObject) {
         if (log.isDebugEnabled()) {
@@ -141,67 +202,6 @@
         }
     }
 
-    protected Reference<FileObject> createReference(final FileObject file, final ReferenceQueue<FileObject> refqueue) {
-        return new SoftReference<>(file, refqueue);
-    }
-
-    @Override
-    public synchronized FileObject getFile(final FileSystem fileSystem, final FileName fileName) {
-        final Map<FileName, Reference<FileObject>> files = getOrCreateFilesystemCache(fileSystem);
-
-        final Reference<FileObject> ref = files.get(fileName);
-        if (ref == null) {
-            return null;
-        }
-
-        final FileObject fo = ref.get();
-        if (fo == null) {
-            removeFile(fileSystem, fileName);
-        }
-        return fo;
-    }
-
-    @Override
-    public synchronized void clear(final FileSystem fileSystem) {
-        final Map<FileName, Reference<FileObject>> files = getOrCreateFilesystemCache(fileSystem);
-
-        final Iterator<FileSystemAndNameKey> iterKeys = refReverseMap.values().iterator();
-        while (iterKeys.hasNext()) {
-            final FileSystemAndNameKey key = iterKeys.next();
-            if (key.getFileSystem() == fileSystem) {
-                iterKeys.remove();
-                files.remove(key.getFileName());
-            }
-        }
-
-        if (files.isEmpty()) {
-            close(fileSystem);
-        }
-    }
-
-    /**
-     * @param fileSystem The file system to close.
-     */
-    private synchronized void close(final FileSystem fileSystem) {
-        if (log.isDebugEnabled()) {
-            log.debug("close fs: " + fileSystem.getRootName());
-        }
-
-        fileSystemCache.remove(fileSystem);
-        if (fileSystemCache.isEmpty()) {
-            endThread();
-        }
-    }
-
-    @Override
-    public synchronized void close() {
-        endThread();
-
-        fileSystemCache.clear();
-
-        refReverseMap.clear();
-    }
-
     @Override
     public synchronized void removeFile(final FileSystem fileSystem, final FileName fileName) {
         if (removeFile(new FileSystemAndNameKey(fileSystem, fileName))) {
@@ -226,17 +226,25 @@
 
     private synchronized void removeFile(final Reference<?> ref) {
         final FileSystemAndNameKey key = refReverseMap.get(ref);
-
         if (key != null && removeFile(key)) {
             close(key.getFileSystem());
         }
     }
 
-    protected synchronized Map<FileName, Reference<FileObject>> getOrCreateFilesystemCache(final FileSystem fileSystem) {
-        if (fileSystemCache.isEmpty()) {
-            startThread();
+    private synchronized void startThread() {
+        if (releaseThread == null) {
+            releaseThread = new ReleaseThread();
+            releaseThread.start();
+            // System.out.println("Started thread ID " + releaseThread.getId());
+            // System.out.flush();
+            // Thread.dumpStack();
         }
+    }
 
-        return fileSystemCache.computeIfAbsent(fileSystem, k -> new HashMap<>());
+    @Override
+    public String toString() {
+        return super.toString() + " [releaseThread=" + releaseThread
+            + (releaseThread == null ? "" : "(ID " + releaseThread.getId() + " is " + releaseThread.getState() + ")")
+            + "]";
     }
 }
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 0e5ca5d..b47c256 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
@@ -290,7 +290,6 @@
         if (init) {
             throw new FileSystemException("vfs.impl/already-inited.error");
         }
-
         this.filesCache = filesCache;
     }
 
@@ -459,8 +458,7 @@
     private void closeComponent(final Object component) {
         if (component != null && components.contains(component)) {
             if (component instanceof VfsComponent) {
-                final VfsComponent vfsComponent = (VfsComponent) component;
-                vfsComponent.close();
+                ((VfsComponent) component).close();
             }
             components.remove(component);
         }
@@ -504,7 +502,6 @@
         }
 
         if (filesCache == null) {
-            // filesCache = new DefaultFilesCache();
             filesCache = new SoftRefFilesCache();
         }
         if (fileCacheStrategy == null) {
@@ -543,16 +540,14 @@
         closeComponent(vfsProvider);
         closeComponent(fileReplicator);
         closeComponent(tempFileStore);
-        closeComponent(filesCache);
         closeComponent(defaultProvider);
 
-
         // unregister all providers here, so if any components have local file references
         // they can still resolve against the supported schemes
         providers.clear();
 
         // FileOperations are components, too
-        operationProviders.values().forEach(opproviders -> opproviders.forEach(this::closeComponent));
+        operationProviders.values().forEach(opProviders -> opProviders.forEach(this::closeComponent));
 
         // unregister all
         operationProviders.clear();
@@ -572,6 +567,11 @@
         // virtual schemas
         virtualFileSystemSchemes.clear();
 
+        // Close cache last.
+        if (filesCache != null) {
+            filesCache.close();
+        }
+
         // setters and derived state
         defaultProvider = null;
         baseFile = null;
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/AbstractProviderTestConfig.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/AbstractProviderTestConfig.java
index 0973ec7..2e4e193 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/AbstractProviderTestConfig.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/AbstractProviderTestConfig.java
@@ -24,7 +24,16 @@
  */
 public abstract class AbstractProviderTestConfig extends AbstractProviderTestCase implements ProviderTestConfig {
 
-    private FilesCache cache;
+    private FilesCache filesCache;
+
+    /**
+     * Subclasses can override.
+     *
+     * @return A new cache.
+     */
+    protected FilesCache createFilesCache() {
+        return new SoftRefFilesCache();
+    }
 
     /**
      * Returns a DefaultFileSystemManager instance (or subclass instance).
@@ -35,13 +44,11 @@
     }
 
     @Override
-    public FilesCache getFilesCache() {
-        if (cache == null) {
-            // cache = new DefaultFilesCache();
-            cache = new SoftRefFilesCache();
+    public final FilesCache getFilesCache() {
+        if (filesCache == null) {
+            filesCache = createFilesCache();
         }
-
-        return cache;
+        return filesCache;
     }
 
     @Override
@@ -57,4 +64,12 @@
         // default is do nothing.
     }
 
+    @Override
+    public void tearDown() throws Exception {
+        if (filesCache != null) {
+            filesCache.close();
+            // Give a chance for any threads to end.
+            Thread.sleep(20);
+        }
+    }
 }
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/AbstractTestSuite.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/AbstractTestSuite.java
index 0ccaae8..c0ee2bd 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/AbstractTestSuite.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/AbstractTestSuite.java
@@ -211,6 +211,8 @@
 
         manager.freeUnusedResources();
         manager.close();
+        // Give a chance for any threads to end.
+        Thread.sleep(20);
 
         // Make sure temp directory is empty or gone
         checkTempDir("Temp dir not empty after test");
@@ -226,7 +228,7 @@
              * if (providerConfig.checkCleanThreadState()) { // close the manager to do a "not thread safe" release of
              * all resources // and allow the vm to shutdown manager.close(); fail(message); } else {
              */
-            System.out.println(message);
+            System.out.print(message);
             // }
         }
         // System.in.read();
@@ -238,7 +240,7 @@
     private void checkTempDir(final String assertMsg) {
         if (tempDir.exists()) {
             Assert.assertTrue(assertMsg + " (" + tempDir.getAbsolutePath() + ")",
-                    tempDir.isDirectory() && tempDir.list().length == 0);
+                tempDir.isDirectory() && ArrayUtils.isEmpty(tempDir.list()));
         }
     }
 
@@ -247,7 +249,7 @@
             return StringUtils.EMPTY;
         }
         final StringBuffer sb = new StringBuffer(256);
-        sb.append("Created threads still running:");
+        sb.append("Threads still running (" + threadSnapshot.length + "): ");
         sb.append(System.lineSeparator());
 
         Field threadTargetField = null;
@@ -261,53 +263,49 @@
         int liveCount = 0;
         for (int index = 0; index < threadSnapshot.length; index++) {
             final Thread thread = threadSnapshot[index];
-            if (thread == null || !thread.isAlive()) {
-                continue;
-            }
-            liveCount++;
-            sb.append("Thread[");
-            sb.append(index);
-            sb.append("]: ");
-            sb.append(" ID ");
-            sb.append(thread.getId());
-            sb.append(", ");
-            // prints [name,priority,group]
-            sb.append(thread);
-            sb.append(", ");
-            sb.append(thread.getState());
-            sb.append(", ");
-            if (!thread.isDaemon()) {
-                sb.append("non_");
-            } 
-            sb.append("daemon");
-
-            if (threadTargetField != null) {
+            if (thread != null && thread.isAlive()) {
+                liveCount++;
+                sb.append("\tThread[");
+                sb.append(index);
+                sb.append("] ");
+                sb.append(" ID ");
+                sb.append(thread.getId());
                 sb.append(", ");
-                try {
-                    final Object threadTarget = threadTargetField.get(thread);
-                    if (threadTarget != null) {
-                        sb.append(threadTarget.getClass());
-                    } else {
-                        sb.append("null");
-                    }
-                } catch (final IllegalAccessException e) {
-                    sb.append("unknown (");
-                    sb.append(e);
-                    sb.append(")");
+                // prints [name,priority,group]
+                sb.append(thread);
+                sb.append(",\t");
+                sb.append(thread.getState());
+                sb.append(", ");
+                if (!thread.isDaemon()) {
+                    sb.append("non_");
                 }
-            }
+                sb.append("daemon");
 
-            sb.append(System.lineSeparator());
-//            Stream.of(thread.getStackTrace()).forEach(e -> {
-//                sb.append('\t');
-//                sb.append(e);
-//                sb.append(System.lineSeparator());
-//            });
+                if (threadTargetField != null) {
+                    sb.append("\t, ");
+                    try {
+                        final Object threadTarget = threadTargetField.get(thread);
+                        if (threadTarget != null) {
+                            sb.append(threadTarget.getClass());
+                        } else {
+                            sb.append("null");
+                        }
+                    } catch (final IllegalAccessException e) {
+                        sb.append("unknown (");
+                        sb.append(e);
+                        sb.append(")");
+                    }
+                }
+
+                sb.append(System.lineSeparator());
+//              Stream.of(thread.getStackTrace()).forEach(e -> {
+//                  sb.append('\t');
+//                  sb.append(e);
+//                  sb.append(System.lineSeparator());
+//              });
+            }
         }
-        if (liveCount == 0) {
-            return StringUtils.EMPTY;
-        }
-        return sb.toString();
+        return liveCount == 0 ? StringUtils.EMPTY : sb.toString();
     }
 
     private Thread[] diffThreadSnapshot(final Thread[] startThreadSnapshot, final Thread[] endThreadSnapshot) {
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/ProviderTestSuite.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/ProviderTestSuite.java
index 837d923..a142197 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/ProviderTestSuite.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/ProviderTestSuite.java
@@ -63,4 +63,5 @@
         addTests(UrlStructureTests.class);
         addTests(VfsClassLoaderTests.class);
     }
+    
 }
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/DefaultFilesCacheTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/DefaultFilesCacheTestCase.java
index b963a72..2462541 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/DefaultFilesCacheTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/DefaultFilesCacheTestCase.java
@@ -38,7 +38,7 @@
     }
 
     @Override
-    public FilesCache getFilesCache() {
+    public FilesCache createFilesCache() {
         return new DefaultFilesCache();
     }
 
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/LRUFilesCacheTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/LRUFilesCacheTestCase.java
index 5a37f06..2156ed7 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/LRUFilesCacheTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/LRUFilesCacheTestCase.java
@@ -38,7 +38,7 @@
     }
 
     @Override
-    public FilesCache getFilesCache() {
+    public FilesCache createFilesCache() {
         return new LRUFilesCache(5);
     }
 
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/NullFilesCacheTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/NullFilesCacheTestCase.java
index a1b60c0..34912e0 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/NullFilesCacheTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/NullFilesCacheTestCase.java
@@ -38,7 +38,7 @@
     }
 
     @Override
-    public FilesCache getFilesCache() {
+    public FilesCache createFilesCache() {
         return new NullFilesCache();
     }
 
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/SoftRefFilesCacheTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/SoftRefFilesCacheTestCase.java
index 804c7ad..50c06d0 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/SoftRefFilesCacheTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/SoftRefFilesCacheTestCase.java
@@ -36,7 +36,7 @@
     }
 
     @Override
-    public FilesCache getFilesCache() {
+    public FilesCache createFilesCache() {
         return new SoftRefFilesCache();
     }
 
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/SoftRefFilesCacheTests.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/SoftRefFilesCacheTests.java
index cb48e44..817dea5 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/SoftRefFilesCacheTests.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/SoftRefFilesCacheTests.java
@@ -36,7 +36,7 @@
     }
 
     @Test
-    public void testClass() {
+    public void testFilesCacheClass() {
         assertTrue(getManager().getFilesCache() instanceof SoftRefFilesCache);
     }
 
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/WeakRefFilesCacheTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/WeakRefFilesCacheTestCase.java
index 45aed54..7a2bad1 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/WeakRefFilesCacheTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/cache/WeakRefFilesCacheTestCase.java
@@ -38,7 +38,7 @@
     }
 
     @Override
-    public FilesCache getFilesCache() {
+    public FilesCache createFilesCache() {
         return new WeakRefFilesCache();
     }
 
diff --git a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/url/UrlProviderHttpTestCase.java b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/url/UrlProviderHttpTestCase.java
index 03a08d5..842c333 100644
--- a/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/url/UrlProviderHttpTestCase.java
+++ b/commons-vfs2/src/test/java/org/apache/commons/vfs2/provider/url/UrlProviderHttpTestCase.java
@@ -20,10 +20,12 @@
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
+import org.apache.commons.AbstractVfsTestCase;
 import org.apache.commons.vfs2.AbstractProviderTestConfig;
 import org.apache.commons.vfs2.FileObject;
 import org.apache.commons.vfs2.FileSystemManager;
 import org.apache.commons.vfs2.ProviderTestSuite;
+import org.apache.commons.vfs2.VFS;
 import org.apache.commons.vfs2.impl.DefaultFileSystemManager;
 import org.apache.commons.vfs2.util.NHttpFileServer;
 
@@ -80,10 +82,8 @@
 
     /**
      * Stops the embedded Apache HTTP Server ().
-     *
-     * @throws IOException
      */
-    private static void tearDownClass() throws IOException {
+    public static void tearDownClass() {
         if (Server != null) {
             Server.shutdown(5000, TimeUnit.SECONDS);
         }