[jboss-cvs] JBossAS SVN: r91988 - in projects/vfs/branches/dml-zip-rework/src: main/java/org/jboss/vfs and 6 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Aug 4 18:31:26 EDT 2009


Author: david.lloyd at jboss.com
Date: 2009-08-04 18:31:25 -0400 (Tue, 04 Aug 2009)
New Revision: 91988

Added:
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempDir.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempFileProvider.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFS.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSInputSource.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSUtils.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFile.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilter.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilterWithAttributes.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileVisitor.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VisitorAttributes.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/
Removed:
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempDir.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempFileProvider.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFS.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSInputSource.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSUtils.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFile.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilter.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilterWithAttributes.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileVisitor.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VisitorAttributes.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/plugins/
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/
Modified:
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/VirtualFileURLConnection.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/VirtualFileURLStreamHandler.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/file/Handler.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/EnumerationIterable.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/EnumerationIterator.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/FileSystem.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/JZipFileSystem.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/JavaZipFileSystem.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/RealFileSystem.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/AbstractVirtualFileFilterWithAttributes.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/AbstractVirtualFileVisitor.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/ExtensibleFilter.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/FilterVirtualFileVisitor.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/MatchAllVirtualFileFilter.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/PathTokenizer.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/SuffixMatchFilter.java
   projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/SuffixesExcludeFilter.java
   projects/vfs/branches/dml-zip-rework/src/test/java/org/jboss/test/vfs/FileVFSUnitTestCase.java
   projects/vfs/branches/dml-zip-rework/src/test/java/org/jboss/test/vfs/support/ClassPathIterator.java
Log:
org.jboss.virtual -> org.jboss.vfs

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs (from rev 91986, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual)

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempDir.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/TempDir.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempDir.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,124 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.virtual;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.File;
-import java.io.InputStream;
-import java.io.FileOutputStream;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * A temporary directory which exists until it is closed, at which time its contents will be removed.
- */
-public final class TempDir implements Closeable
-{
-   private final TempFileProvider provider;
-   private final File root;
-   private final AtomicBoolean open = new AtomicBoolean(true);
-
-   TempDir(TempFileProvider provider, File root)
-   {
-      this.provider = provider;
-      this.root = root;
-   }
-
-   /**
-    * Get the {@code File} that represents the root of this temporary directory.  The returned file is only valid
-    * as long as the tempdir exists.
-    *
-    * @return the root file
-    * @throws IOException if the directory was closed at the time of this invocation
-    */
-   public File getRoot() throws IOException
-   {
-      if (! open.get()) {
-         throw new IOException("Temp directory closed");
-      }
-      return root;
-   }
-
-   /**
-    * Get the {@code File} for a relative path.  The returned file is only valid
-    * as long as the tempdir exists.
-    *
-    * @param relativePath the relative path
-    * @return the corresponding file
-    * @throws IOException if the directory was closed at the time of this invocation
-    */
-   public File getFile(String relativePath) throws IOException {
-      if (! open.get()) {
-         throw new IOException("Temp directory closed");
-      }
-      return new File(root, relativePath);
-   }
-
-   /**
-    * Create a file within this temporary directory, prepopulating the file from the given
-    * input stream.
-    *
-    * @param relativePath the relative path name
-    * @param sourceData the source input stream to use
-    * @return the file
-    * @throws IOException if the directory was closed at the time of this invocation or an error occurs
-    */
-   public File createFile(String relativePath, InputStream sourceData) throws IOException {
-      final File tempFile = getFile(relativePath);
-      boolean ok = false;
-      try {
-         final FileOutputStream fos = new FileOutputStream(tempFile);
-         try {
-            VFSUtils.copyStream(sourceData, fos);
-            fos.close();
-            sourceData.close();
-            ok = true;
-            return tempFile;
-         } finally {
-            VFSUtils.safeClose(fos);
-         }
-      } finally {
-         VFSUtils.safeClose(sourceData);
-         if (! ok) {
-            tempFile.delete();
-         }
-      }
-   }
-
-   /**
-    * Close this directory.  The contents of the directory will be removed.
-    *
-    * @throws IOException if an I/O error occurs
-    */
-   public void close() throws IOException
-   {
-      if (open.getAndSet(false)) {
-         provider.new DeleteTask(root).run();
-      }
-   }
-
-   protected void finalize() throws Throwable
-   {
-      VFSUtils.safeClose(this);
-   }
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempDir.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/TempDir.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempDir.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempDir.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,124 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.vfs;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
+import java.io.FileOutputStream;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * A temporary directory which exists until it is closed, at which time its contents will be removed.
+ */
+public final class TempDir implements Closeable
+{
+   private final TempFileProvider provider;
+   private final File root;
+   private final AtomicBoolean open = new AtomicBoolean(true);
+
+   TempDir(TempFileProvider provider, File root)
+   {
+      this.provider = provider;
+      this.root = root;
+   }
+
+   /**
+    * Get the {@code File} that represents the root of this temporary directory.  The returned file is only valid
+    * as long as the tempdir exists.
+    *
+    * @return the root file
+    * @throws IOException if the directory was closed at the time of this invocation
+    */
+   public File getRoot() throws IOException
+   {
+      if (! open.get()) {
+         throw new IOException("Temp directory closed");
+      }
+      return root;
+   }
+
+   /**
+    * Get the {@code File} for a relative path.  The returned file is only valid
+    * as long as the tempdir exists.
+    *
+    * @param relativePath the relative path
+    * @return the corresponding file
+    * @throws IOException if the directory was closed at the time of this invocation
+    */
+   public File getFile(String relativePath) throws IOException {
+      if (! open.get()) {
+         throw new IOException("Temp directory closed");
+      }
+      return new File(root, relativePath);
+   }
+
+   /**
+    * Create a file within this temporary directory, prepopulating the file from the given
+    * input stream.
+    *
+    * @param relativePath the relative path name
+    * @param sourceData the source input stream to use
+    * @return the file
+    * @throws IOException if the directory was closed at the time of this invocation or an error occurs
+    */
+   public File createFile(String relativePath, InputStream sourceData) throws IOException {
+      final File tempFile = getFile(relativePath);
+      boolean ok = false;
+      try {
+         final FileOutputStream fos = new FileOutputStream(tempFile);
+         try {
+            VFSUtils.copyStream(sourceData, fos);
+            fos.close();
+            sourceData.close();
+            ok = true;
+            return tempFile;
+         } finally {
+            VFSUtils.safeClose(fos);
+         }
+      } finally {
+         VFSUtils.safeClose(sourceData);
+         if (! ok) {
+            tempFile.delete();
+         }
+      }
+   }
+
+   /**
+    * Close this directory.  The contents of the directory will be removed.
+    *
+    * @throws IOException if an I/O error occurs
+    */
+   public void close() throws IOException
+   {
+      if (open.getAndSet(false)) {
+         provider.new DeleteTask(root).run();
+      }
+   }
+
+   protected void finalize() throws Throwable
+   {
+      VFSUtils.safeClose(this);
+   }
+}

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempFileProvider.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/TempFileProvider.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempFileProvider.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,151 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-
-package org.jboss.virtual;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.Closeable;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.Random;
-import java.security.SecureRandom;
-
-/**
- * A provider for temporary physical files and directories.
- */
-public final class TempFileProvider implements Closeable
-{
-   private static final String JBOSS_TMP_DIR_PROPERTY = "jboss.server.temp.dir";
-   private static final String JVM_TMP_DIR_PROPERTY = "java.io.tmpdir";
-   private static final File TMP_ROOT;
-   private static final int RETRIES = 10;
-   private final AtomicBoolean open = new AtomicBoolean(true);
-
-   static {
-      String configTmpDir = System.getProperty(JBOSS_TMP_DIR_PROPERTY);
-      if (configTmpDir == null)
-         configTmpDir = System.getProperty(JVM_TMP_DIR_PROPERTY);
-
-      try
-      {
-         TMP_ROOT = new File(configTmpDir, "vfs");
-         TMP_ROOT.mkdirs();
-      }
-      catch (Exception e)
-      {
-         throw new RuntimeException("Can't set up temp file provider", e);
-      }
-   }
-
-   /**
-    * Create a temporary file provider for a given type.
-    *
-    * @param providerType the provider type string (used as a prefix in the temp file dir name)
-    * @return the new provider
-    * @throws IOException if an I/O error occurs
-    */
-   public static TempFileProvider create(String providerType, ScheduledExecutorService executor) throws IOException
-   {
-      return new TempFileProvider(createTempDir(providerType, "", TMP_ROOT), executor);
-   }
-
-   private final File providerRoot;
-   private final ScheduledExecutorService executor;
-
-   private TempFileProvider(File providerRoot, ScheduledExecutorService executor)
-   {
-      this.providerRoot = providerRoot;
-      this.executor = executor;
-   }
-
-   /**
-    * Create a temp directory, into which temporary files may be placed.
-    *
-    * @param originalName the original file name
-    * @return the temp directory
-    * @throws IOException
-    */
-   public TempDir createTempDir(String originalName) throws IOException {
-      if (! open.get()) {
-         throw new IOException("Temp file provider closed");
-      }
-      final String name = createTempName(originalName + "-", "");
-      final File f = new File(providerRoot, name);
-      for (int i = 0; i < RETRIES; i ++) {
-         if (f.mkdir())
-            return new TempDir(this, f);
-      }
-      final IOException eo = new IOException("Could not create directory after " + RETRIES + " attempts");
-      throw eo;
-   }
-
-   private static final Random rng = new SecureRandom();
-
-   private static File createTempDir(String prefix, String suffix, File root) throws IOException
-   {
-      for (int i = 0; i < RETRIES; i ++) {
-         final File f = new File(root, createTempName(prefix, suffix));
-         if (f.mkdir())
-            return f;
-      }
-      final IOException eo = new IOException("Could not create directory after " + RETRIES + " attempts");
-      throw eo;
-   }
-
-   static String createTempName(String prefix, String suffix) {
-      return prefix + Long.toHexString(rng.nextLong()) + suffix;
-   }
-
-   /**
-    * Close this provider and delete any temp files associated with it.
-    */
-   public void close() throws IOException
-   {
-      if (open.getAndSet(false)) {
-         new DeleteTask(providerRoot).run();
-      }
-   }
-
-   protected void finalize()
-   {
-      VFSUtils.safeClose(this);
-   }
-
-   class DeleteTask implements Runnable
-   {
-      private final File root;
-
-      public DeleteTask(File root)
-      {
-         this.root = root;
-      }
-
-      public void run()
-      {
-         if (! VFSUtils.recursiveDelete(root)) {
-            executor.schedule(this, 30L, TimeUnit.SECONDS);
-         }
-      }
-   }
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempFileProvider.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/TempFileProvider.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempFileProvider.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/TempFileProvider.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,151 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+
+package org.jboss.vfs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.Closeable;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.Random;
+import java.security.SecureRandom;
+
+/**
+ * A provider for temporary physical files and directories.
+ */
+public final class TempFileProvider implements Closeable
+{
+   private static final String JBOSS_TMP_DIR_PROPERTY = "jboss.server.temp.dir";
+   private static final String JVM_TMP_DIR_PROPERTY = "java.io.tmpdir";
+   private static final File TMP_ROOT;
+   private static final int RETRIES = 10;
+   private final AtomicBoolean open = new AtomicBoolean(true);
+
+   static {
+      String configTmpDir = System.getProperty(JBOSS_TMP_DIR_PROPERTY);
+      if (configTmpDir == null)
+         configTmpDir = System.getProperty(JVM_TMP_DIR_PROPERTY);
+
+      try
+      {
+         TMP_ROOT = new File(configTmpDir, "vfs");
+         TMP_ROOT.mkdirs();
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException("Can't set up temp file provider", e);
+      }
+   }
+
+   /**
+    * Create a temporary file provider for a given type.
+    *
+    * @param providerType the provider type string (used as a prefix in the temp file dir name)
+    * @return the new provider
+    * @throws IOException if an I/O error occurs
+    */
+   public static TempFileProvider create(String providerType, ScheduledExecutorService executor) throws IOException
+   {
+      return new TempFileProvider(createTempDir(providerType, "", TMP_ROOT), executor);
+   }
+
+   private final File providerRoot;
+   private final ScheduledExecutorService executor;
+
+   private TempFileProvider(File providerRoot, ScheduledExecutorService executor)
+   {
+      this.providerRoot = providerRoot;
+      this.executor = executor;
+   }
+
+   /**
+    * Create a temp directory, into which temporary files may be placed.
+    *
+    * @param originalName the original file name
+    * @return the temp directory
+    * @throws IOException
+    */
+   public TempDir createTempDir(String originalName) throws IOException {
+      if (! open.get()) {
+         throw new IOException("Temp file provider closed");
+      }
+      final String name = createTempName(originalName + "-", "");
+      final File f = new File(providerRoot, name);
+      for (int i = 0; i < RETRIES; i ++) {
+         if (f.mkdir())
+            return new TempDir(this, f);
+      }
+      final IOException eo = new IOException("Could not create directory after " + RETRIES + " attempts");
+      throw eo;
+   }
+
+   private static final Random rng = new SecureRandom();
+
+   private static File createTempDir(String prefix, String suffix, File root) throws IOException
+   {
+      for (int i = 0; i < RETRIES; i ++) {
+         final File f = new File(root, createTempName(prefix, suffix));
+         if (f.mkdir())
+            return f;
+      }
+      final IOException eo = new IOException("Could not create directory after " + RETRIES + " attempts");
+      throw eo;
+   }
+
+   static String createTempName(String prefix, String suffix) {
+      return prefix + Long.toHexString(rng.nextLong()) + suffix;
+   }
+
+   /**
+    * Close this provider and delete any temp files associated with it.
+    */
+   public void close() throws IOException
+   {
+      if (open.getAndSet(false)) {
+         new DeleteTask(providerRoot).run();
+      }
+   }
+
+   protected void finalize()
+   {
+      VFSUtils.safeClose(this);
+   }
+
+   class DeleteTask implements Runnable
+   {
+      private final File root;
+
+      public DeleteTask(File root)
+      {
+         this.root = root;
+      }
+
+      public void run()
+      {
+         if (! VFSUtils.recursiveDelete(root)) {
+            executor.schedule(this, 30L, TimeUnit.SECONDS);
+         }
+      }
+   }
+}

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFS.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFS.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,805 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.virtual;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.File;
-import java.io.InputStream;
-import java.io.FileOutputStream;
-import java.net.URI;
-import java.net.URL;
-import java.net.URISyntaxException;
-import java.util.AbstractSet;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Enumeration;
-import java.util.zip.ZipFile;
-import java.util.zip.ZipEntry;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import org.jboss.virtual.spi.FileSystem;
-import org.jboss.virtual.spi.RealFileSystem;
-import org.jboss.virtual.spi.JavaZipFileSystem;
-import org.jboss.virtual.plugins.vfs.helpers.PathTokenizer;
-import org.jboss.logging.Logger;
-
-/**
- * Virtual File System
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author Scott.Stark at jboss.org
- * @author <a href="ales.justin at jboss.com">Ales Justin</a>
- * @version $Revision: 1.1 $
- */
-public class VFS
-{
-   private static final Logger log = Logger.getLogger(VFS.class);
-
-   public static final boolean LEAK_DEBUGGING;
-
-   private final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = new ConcurrentHashMap<VirtualFile, Map<String, Mount>>();
-   private final VirtualFile rootVirtualFile;
-   private final Mount rootMount;
-
-   static VFS instance = new VFS();
-
-   // todo - LRU VirtualFiles?
-   // todo - LRU String intern?
-
-   static
-   {
-      init();
-      LEAK_DEBUGGING = AccessController.doPrivileged(new PrivilegedAction<Boolean>()
-      {
-         public Boolean run()
-         {
-            return Boolean.valueOf(System.getProperty("jboss.vfs.leakDebugging", "true"));
-         }
-      }).booleanValue();
-   }
-
-   /**
-    * Get the "global" instance.
-    *
-    * @return the VFS instance
-    */
-   public static VFS getInstance()
-   {
-      return instance;
-   }
-
-   /**
-    * Create a new instance.
-    */
-   public VFS()
-   {
-      // By default, there's a root mount which points to the "real" FS
-      //noinspection ThisEscapedInObjectConstruction
-      rootVirtualFile = new VirtualFile("", null);
-      rootMount = new Mount(RealFileSystem.ROOT_INSTANCE, rootVirtualFile);
-   }
-
-   /**
-    * Get file.
-    * Backcompatibility method.
-    *
-    * @param url the url
-    * @return the file matching url
-    * @throws IOException if there is a problem accessing the VFS
-    * @deprecated use {@link #getChild(URL)} instead
-    */
-   @Deprecated
-   @SuppressWarnings("deprecation")
-   public static VirtualFile getRoot(URL url) throws IOException
-   {
-      try
-      {
-         return getRoot(url.toURI());
-      }
-      catch (URISyntaxException e)
-      {
-         IOException ioe = new IOException();
-         ioe.initCause(e);
-         throw ioe;
-      }
-   }
-
-   /**
-    * Get file.
-    * Backcompatibility method.
-    *
-    * @param uri the uri
-    * @return the file matching uri
-    * @throws IOException if there is a problem accessing the VFS
-    * @deprecated use {@link #getChild(URI)} instead
-    */
-   @Deprecated
-   public static VirtualFile getRoot(URI uri) throws IOException
-   {
-      return getInstance().getChild(uri.getPath());
-   }
-
-   /**
-    * Initialize VFS protocol handlers package property.
-    */
-   @SuppressWarnings({"deprecation", "unchecked"})
-   public static void init()
-   {
-      // A small hack that allows us to replace file for now
-      URL.setURLStreamHandlerFactory(null);
-
-      String pkgs = System.getProperty("java.protocol.handler.pkgs");
-      if (pkgs == null || pkgs.trim().length() == 0)
-      {
-         pkgs = "org.jboss.virtual.protocol";
-         System.setProperty("java.protocol.handler.pkgs", pkgs);
-      }
-      else if (pkgs.contains("org.jboss.virtual.protocol") == false)
-      {
-         pkgs = "org.jboss.virtual.protocol|" + pkgs;
-         System.setProperty("java.protocol.handler.pkgs", pkgs);
-      }
-   }
-
-   /**
-    * Mount a filesystem on a mount point in the VFS.  The mount point is any valid file name, existant or non-existant.
-    * If a relative path is given, it will be treated as relative to the VFS root.
-    *
-    * @param mountPoint the mount point
-    * @param fileSystem the file system to mount
-    * @return a handle which can be used to unmount the filesystem
-    * @throws IOException if an I/O error occurs, such as a filesystem already being mounted at the given mount point
-    */
-   public Closeable mount(VirtualFile mountPoint, FileSystem fileSystem) throws IOException {
-      if (mountPoint.getVFS() != this) {
-         throw new IOException("VirtualFile does not match VFS instance");
-      }
-      final VirtualFile parent = mountPoint.getParent();
-      if (parent == null) {
-         throw new IOException("Root filsystem already mounted");
-      }
-      final String name = mountPoint.getName();
-      final Mount mount = new Mount(fileSystem, mountPoint);
-      for (;;) {
-         Map<String, Mount> childMountMap = mounts.get(parent);
-         Map<String, Mount> newMap;
-         if (childMountMap == null) {
-            childMountMap = mounts.putIfAbsent(parent, Collections.singletonMap(name, mount));
-            if (childMountMap == null) {
-               return mount;
-            }
-         }
-         newMap = new HashMap<String, Mount>(childMountMap);
-         if (newMap.put(name, mount) != null) {
-            throw new IOException("Filsystem already mounted at mount point \"" + mountPoint + "\"");
-         }
-         if (mounts.replace(parent, childMountMap, newMap)) {
-            return mount;
-         }
-      }
-   }
-
-   /**
-    * Find a virtual file.
-    *
-    * @param url the URL whose path component is the child path
-    * @return the child
-    * @throws IllegalArgumentException if the path is null
-    */
-   public VirtualFile getChild(URL url) throws URISyntaxException
-   {
-      return getChild(url.toURI());
-   }
-
-   /**
-    * Find a virtual file.
-    *
-    * @param uri the URI whose path component is the child path
-    * @return the child
-    * @throws IllegalArgumentException if the path is null
-    */
-   public VirtualFile getChild(URI uri)
-   {
-      return getChild(uri.getPath());
-   }
-
-   /**
-    * Find a virtual file.
-    *
-    * @param path the child path
-    * @return the child
-    * @throws IllegalArgumentException if the path is null
-    */
-   public VirtualFile getChild(String path)
-   {
-      if (path == null)
-         throw new IllegalArgumentException("Null path");
-
-      return rootVirtualFile.getChild(path);
-   }
-
-   /**
-    * Get the root virtual file for this VFS instance.
-    *
-    * @return the root virtual file
-    */
-   public VirtualFile getRootVirtualFile()
-   {
-      return rootVirtualFile;
-   }
-
-   /**
-    * Get the children
-    *
-    * @return the children
-    * @throws IOException for any problem accessing the virtual file system
-    */
-   public List<VirtualFile> getChildren() throws IOException
-   {
-      return getRootVirtualFile().getChildren(null);
-   }
-
-   /**
-    * Get the children
-    *
-    * @param filter to filter the children
-    * @return the children
-    * @throws IOException for any problem accessing the virtual file system
-    */
-   public List<VirtualFile> getChildren(VirtualFileFilter filter) throws IOException
-   {
-      return getRootVirtualFile().getChildren(filter);
-   }
-
-   /**
-    * Get all the children recursively<p>
-    *
-    * This always uses {@link VisitorAttributes#RECURSE}
-    *
-    * @return the children
-    * @throws IOException for any problem accessing the virtual file system
-    */
-   public List<VirtualFile> getChildrenRecursively() throws IOException
-   {
-      return getRootVirtualFile().getChildrenRecursively(null);
-   }
-
-   /**
-    * Get all the children recursively<p>
-    *
-    * This always uses {@link VisitorAttributes#RECURSE}
-    *
-    * @param filter to filter the children
-    * @return the children
-    * @throws IOException for any problem accessing the virtual file system
-    */
-   public List<VirtualFile> getChildrenRecursively(VirtualFileFilter filter) throws IOException
-   {
-      return getRootVirtualFile().getChildrenRecursively(filter);
-   }
-
-   /**
-    * Visit the virtual file system from the root
-    *
-    * @param visitor the visitor
-    * @throws IOException for any problem accessing the VFS
-    * @throws IllegalArgumentException if the visitor is null
-    */
-   public void visit(VirtualFileVisitor visitor) throws IOException
-   {
-      visitor.visit(rootVirtualFile);
-   }
-
-   /**
-    * Visit the virtual file system
-    *
-    * @param file the file
-    * @param visitor the visitor
-    * @throws IOException for any problem accessing the VFS
-    * @throws IllegalArgumentException if the file or visitor is null
-    */
-   protected void visit(VirtualFile file, VirtualFileVisitor visitor) throws IOException
-   {
-      if (file == null)
-         throw new IllegalArgumentException("Null file");
-
-      if (file.getVFS() != this)
-         throw new IllegalArgumentException("Virtual file from foreign VFS");
-
-      visitor.visit(file);
-   }
-
-   Mount getMount(VirtualFile virtualFile) {
-      final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = this.mounts;
-      for (;;) {
-         final VirtualFile parent = virtualFile.getParent();
-         if (parent == null) {
-            return rootMount;
-         }
-         final Map<String, Mount> parentMounts = mounts.get(parent);
-         if (parentMounts == null) {
-            virtualFile = parent;
-         } else {
-            final Mount mount = parentMounts.get(virtualFile.getName());
-            if (mount == null) {
-               virtualFile = parent;
-            } else {
-               return mount;
-            }
-         }
-      }
-   }
-
-   /**
-    * Get all immediate submounts for a path.
-    *
-    * @param virtualFile the path
-    * @return the collection of present mount (simple) names
-    */
-   Set<String> getSubmounts(VirtualFile virtualFile)
-   {
-      final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = this.mounts;
-      final Map<String, Mount> mountMap = mounts.get(virtualFile);
-      if (mountMap == null) {
-         return emptyRemovableSet();
-      }
-      return new HashSet<String>(mountMap.keySet());
-   }
-
-   private static Closeable doMount(final FileSystem fileSystem, final VirtualFile mountPoint) throws IOException
-   {
-      boolean ok = false;
-      try {
-         final Closeable mountHandle = getInstance().mount(mountPoint, fileSystem);
-         final Closeable closeable = new Closeable()
-         {
-            public void close() throws IOException
-            {
-               VFSUtils.safeClose(mountHandle);
-               VFSUtils.safeClose(fileSystem);
-            }
-         };
-         ok = true;
-         return closeable;
-      } finally {
-         if (! ok) {
-            VFSUtils.safeClose(fileSystem);
-         }
-      }
-   }
-
-   /**
-    * Create and mount a zip file into the filesystem, returning a single handle which will unmount and close the file
-    * system when closed.
-    *
-    * @param zipFile the zip file to mount
-    * @param mountPoint the point at which the filesystem should be mounted
-    * @param tempFileProvider the temporary file provider
-    * @return a handle
-    * @throws IOException if an error occurs
-    */
-   public static Closeable mountZip(File zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
-   {
-      boolean ok = false;
-      final TempDir tempDir = tempFileProvider.createTempDir(zipFile.getName());
-      try {
-         final Closeable closeable = doMount(new JavaZipFileSystem(zipFile, tempDir), mountPoint);
-         ok = true;
-         return closeable;
-      } finally {
-         if (! ok) {
-            VFSUtils.safeClose(tempDir);
-         }
-      }
-   }
-
-   /**
-    * Create and mount a zip file into the filesystem, returning a single handle which will unmount and close the file
-    * system when closed.
-    *
-    * @param zipData an input stream containing the zip data
-    * @param zipName the name of the archive
-    * @param mountPoint the point at which the filesystem should be mounted
-    * @param tempFileProvider the temporary file provider
-    * @return a handle
-    * @throws IOException if an error occurs
-    */
-   public static Closeable mountZip(InputStream zipData, String zipName, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
-   {
-      boolean ok = false;
-      try {
-         final TempDir tempDir = tempFileProvider.createTempDir(zipName);
-         try {
-            final Closeable closeable = doMount(new JavaZipFileSystem(zipName, zipData, tempDir), mountPoint);
-            ok = true;
-            return closeable;
-         } finally {
-            if (! ok) {
-               VFSUtils.safeClose(tempDir);
-            }
-         }
-      } finally {
-         VFSUtils.safeClose(zipData);
-      }
-   }
-
-   /**
-    * Create and mount a zip file into the filesystem, returning a single handle which will unmount and close the file
-    * system when closed.
-    *
-    * @param zipFile a zip file in the VFS
-    * @param mountPoint the point at which the filesystem should be mounted
-    * @param tempFileProvider the temporary file provider
-    * @return a handle
-    * @throws IOException if an error occurs
-    */
-   public static Closeable mountZip(VirtualFile zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
-   {
-      return mountZip(zipFile.openStream(), zipFile.getName(), mountPoint, tempFileProvider);
-   }
-
-   /**
-    * Create and mount a real file system, returning a single handle which will unmount and close the filesystem when
-    * closed.
-    *
-    * @param realRoot the real filesystem root
-    * @param mountPoint the point at which the filesystem should be mounted
-    * @return a handle
-    * @throws IOException if an error occurs
-    */
-   public static Closeable mountReal(File realRoot, VirtualFile mountPoint) throws IOException
-   {
-      return doMount(new RealFileSystem(realRoot), mountPoint);
-   }
-
-   /**
-    * Create and mount a temporary file system, returning a single handle which will unmount and close the filesystem
-    * when closed.
-    *
-    * @param mountPoint the point at which the filesystem should be mounted
-    * @param tempFileProvider the temporary file provider
-    * @return a handle
-    * @throws IOException if an error occurs
-    */
-   public static Closeable mountTemp(VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
-   {
-      boolean ok = false;
-      final TempDir tempDir = tempFileProvider.createTempDir("tmpfs");
-      try {
-         final Closeable closeable = doMount(new RealFileSystem(tempDir.getRoot()), mountPoint);
-         ok = true;
-         return new Closeable()
-         {
-            public void close() throws IOException
-            {
-               VFSUtils.safeClose(closeable);
-               VFSUtils.safeClose(tempDir);
-            }
-         };
-      } finally {
-         if (! ok) {
-            VFSUtils.safeClose(tempDir);
-         }
-      }
-   }
-
-   /**
-    * Create and mount an expanded zip file in a temporary file system, returning a single handle which will unmount and
-    * close the filesystem when closed.
-    *
-    * @param zipFile the zip file to mount
-    * @param mountPoint the point at which the filesystem should be mounted
-    * @param tempFileProvider the temporary file provider
-    * @return a handle
-    * @throws IOException if an error occurs
-    */
-   public static Closeable mountZipExpanded(File zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
-   {
-      boolean ok = false;
-      final TempDir tempDir = tempFileProvider.createTempDir(zipFile.getName());
-      try {
-         final File rootFile = tempDir.getRoot();
-         unzip(zipFile, rootFile);
-         final Closeable closeable = doMount(new RealFileSystem(rootFile), mountPoint);
-         ok = true;
-         return new Closeable()
-         {
-            public void close() throws IOException
-            {
-               VFSUtils.safeClose(closeable);
-               VFSUtils.safeClose(tempDir);
-            }
-         };
-      } finally {
-         if (! ok) {
-            VFSUtils.safeClose(tempDir);
-         }
-      }
-   }
-
-   /**
-    * Create and mount an expanded zip file in a temporary file system, returning a single handle which will unmount and
-    * close the filesystem when closed.  The given zip data stream is closed.
-    *
-    * @param zipData an input stream containing the zip data
-    * @param zipName the name of the archive
-    * @param mountPoint the point at which the filesystem should be mounted
-    * @param tempFileProvider the temporary file provider
-    * @return a handle
-    * @throws IOException if an error occurs
-    */
-   public static Closeable mountZipExpanded(InputStream zipData, String zipName, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
-   {
-      try {
-         boolean ok = false;
-         final TempDir tempDir = tempFileProvider.createTempDir(zipName);
-         try {
-            final File zipFile = File.createTempFile(zipName + "-", ".tmp", tempDir.getRoot());
-            try {
-               final FileOutputStream os = new FileOutputStream(zipFile);
-               try {
-                  // allow an error on close to terminate the unzip
-                  VFSUtils.copyStream(zipData, os);
-                  zipData.close();
-                  os.close();
-               } finally {
-                  VFSUtils.safeClose(zipData);
-                  VFSUtils.safeClose(os);
-               }
-               final File rootFile = tempDir.getRoot();
-               unzip(zipFile, rootFile);
-               final Closeable closeable = doMount(new RealFileSystem(rootFile), mountPoint);
-               ok = true;
-               return new Closeable()
-               {
-                  public void close() throws IOException
-                  {
-                     VFSUtils.safeClose(closeable);
-                     VFSUtils.safeClose(tempDir);
-                  }
-               };
-            } finally {
-               zipFile.delete();
-            }
-         } finally {
-            if (! ok) {
-               VFSUtils.safeClose(tempDir);
-            }
-         }
-      } finally {
-         VFSUtils.safeClose(zipData);
-      }
-   }
-
-   /**
-    * Create and mount an expanded zip file in a temporary file system, returning a single handle which will unmount and
-    * close the filesystem when closed.  The given zip data stream is closed.
-    *
-    * @param zipFile a zip file in the VFS
-    * @param mountPoint the point at which the filesystem should be mounted
-    * @param tempFileProvider the temporary file provider
-    * @return a handle
-    * @throws IOException if an error occurs
-    */
-   public static Closeable mountZipExpanded(VirtualFile zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
-   {
-      return mountZipExpanded(zipFile.openStream(), zipFile.getName(), mountPoint, tempFileProvider);
-   }
-
-   /**
-    * Expand a zip file to a destination directory.  The directory must exist.  If an error occurs, the destination
-    * directory may contain a partially-extracted archive, so cleanup is up to the caller.
-    *
-    * @param zipFile the zip file
-    * @param destDir the destination directory
-    * @throws IOException if an error occurs
-    */
-   public static void unzip(File zipFile, File destDir) throws IOException
-   {
-      final ZipFile zip = new ZipFile(zipFile);
-      try {
-         final Set<File> createdDirs = new HashSet<File>();
-         final Enumeration<? extends ZipEntry> entries = zip.entries();
-         FILES_LOOP: while (entries.hasMoreElements()) {
-            final ZipEntry zipEntry = entries.nextElement();
-            final String name = zipEntry.getName();
-            final List<String> tokens = PathTokenizer.getTokens(name);
-            final Iterator<String> it = tokens.iterator();
-            File current = destDir;
-            while (it.hasNext())
-            {
-               String token = it.next();
-               if (PathTokenizer.isCurrentToken(token) || PathTokenizer.isReverseToken(token))
-               {
-                  // invalid file; skip it!
-                  continue FILES_LOOP;
-               }
-               current = new File(current, token);
-               if ((it.hasNext() || zipEntry.isDirectory()) && createdDirs.add(current))
-               {
-                  current.mkdir();
-               }
-            }
-            if (! zipEntry.isDirectory()) {
-               final InputStream is = zip.getInputStream(zipEntry);
-               try {
-                  final FileOutputStream os = new FileOutputStream(current);
-                  try {
-                     VFSUtils.copyStream(is, os);
-                     // allow an error on close to terminate the unzip
-                     is.close();
-                     os.close();
-                  } finally {
-                     VFSUtils.safeClose(os);
-                  }
-               } finally {
-                  VFSUtils.safeClose(is);
-               }
-            }
-         }
-      } finally {
-         VFSUtils.safeClose(zip);
-      }
-   }
-
-   @SuppressWarnings({ "unchecked" })
-   private static <E> Set<E> emptyRemovableSet() {
-      return EMPTY_REMOVABLE_SET;
-   }
-
-   private static final Set EMPTY_REMOVABLE_SET = new EmptyRemovableSet();
-
-   private static final class EmptyRemovableSet<E> extends AbstractSet<E> {
-
-      public boolean remove(Object o)
-      {
-         return false;
-      }
-
-      public boolean retainAll(Collection<?> c)
-      {
-         return false;
-      }
-
-      public void clear()
-      {
-      }
-
-      public Iterator<E> iterator()
-      {
-         return Collections.<E>emptySet().iterator();
-      }
-
-      public int size()
-      {
-         return 0;
-      }
-   }
-
-   /**
-    * The mount representation.  This instance represents a binding between a position in the virtual filesystem and
-    * the backing filesystem implementation; the same {@code FileSystem} may be mounted in more than one place, however
-    * only one {@code FileSystem} may be bound to a specific path at a time.
-    */
-   final class Mount implements Closeable {
-      private final FileSystem fileSystem;
-      private final VirtualFile mountPoint;
-      private final StackTraceElement[] allocationPoint;
-      private final AtomicBoolean closed = new AtomicBoolean(false);
-
-      Mount(FileSystem fileSystem, VirtualFile mountPoint)
-      {
-         this.fileSystem = fileSystem;
-         this.mountPoint = mountPoint;
-         allocationPoint = Thread.currentThread().getStackTrace();
-      }
-
-      public void close() throws IOException
-      {
-         if (closed.getAndSet(true)) {
-            return;
-         }
-         final String name = mountPoint.getName();
-         final VirtualFile parent = mountPoint.getParent();
-         final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = VFS.this.mounts;
-         for (;;) {
-            final Map<String, Mount> parentMounts = mounts.get(parent);
-            if (parentMounts == null) {
-               return;
-            }
-            final VFS.Mount mount = parentMounts.get(name);
-            if (mount != this) {
-               return;
-            }
-            final Map<String, Mount> newParentMounts;
-            if (parentMounts.size() == 2) {
-               final Iterator<Map.Entry<String, Mount>> ei = parentMounts.entrySet().iterator();
-               final Map.Entry<String, Mount> e1 = ei.next();
-               if (e1.getKey().equals(name)) {
-                  final Map.Entry<String, Mount> e2 = ei.next();
-                  newParentMounts = Collections.singletonMap(e2.getKey(), e2.getValue());
-               } else {
-                  newParentMounts = Collections.singletonMap(e1.getKey(), e1.getValue());
-               }
-               if (mounts.replace(parent, parentMounts, newParentMounts)) {
-                  return;
-               }
-            } else if (parentMounts.size() == 1) {
-               if (mounts.remove(parent, parentMounts)) {
-                  return;
-               }
-            } else {
-               newParentMounts = new HashMap<String, Mount>(parentMounts);
-               newParentMounts.remove(name);
-               if (mounts.replace(parent, parentMounts, newParentMounts)) {
-                  return;
-               }
-            }
-         }
-      }
-
-      FileSystem getFileSystem()
-      {
-         return fileSystem;
-      }
-
-      VirtualFile getMountPoint()
-      {
-         return mountPoint;
-      }
-
-      protected void finalize() throws IOException
-      {
-         if (! closed.get()) {
-            final StackTraceElement[] allocationPoint = this.allocationPoint;
-            if (allocationPoint != null) {
-               final LeakDescriptor t = new LeakDescriptor();
-               t.setStackTrace(allocationPoint);
-               log.warnf(t, "A VFS mount (%s) was leaked!", mountPoint);
-            } else {
-               log.warnf("A VFS mount (%s) was leaked!", mountPoint);
-            }
-            close();
-         }
-      }
-   }
-
-   private static final class LeakDescriptor extends Throwable {
-      private static final long serialVersionUID = 6034058126740270584L;
-
-      public String toString()
-      {
-         return "Allocation stack trace:";
-      }
-   }
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFS.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFS.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFS.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFS.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,805 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.vfs;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.File;
+import java.io.InputStream;
+import java.io.FileOutputStream;
+import java.net.URI;
+import java.net.URL;
+import java.net.URISyntaxException;
+import java.util.AbstractSet;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Enumeration;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipEntry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.jboss.vfs.spi.FileSystem;
+import org.jboss.vfs.spi.RealFileSystem;
+import org.jboss.vfs.spi.JavaZipFileSystem;
+import org.jboss.vfs.util.PathTokenizer;
+import org.jboss.logging.Logger;
+
+/**
+ * Virtual File System
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author Scott.Stark at jboss.org
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @version $Revision: 1.1 $
+ */
+public class VFS
+{
+   private static final Logger log = Logger.getLogger(VFS.class);
+
+   public static final boolean LEAK_DEBUGGING;
+
+   private final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = new ConcurrentHashMap<VirtualFile, Map<String, Mount>>();
+   private final VirtualFile rootVirtualFile;
+   private final Mount rootMount;
+
+   static VFS instance = new VFS();
+
+   // todo - LRU VirtualFiles?
+   // todo - LRU String intern?
+
+   static
+   {
+      init();
+      LEAK_DEBUGGING = AccessController.doPrivileged(new PrivilegedAction<Boolean>()
+      {
+         public Boolean run()
+         {
+            return Boolean.valueOf(System.getProperty("jboss.vfs.leakDebugging", "true"));
+         }
+      }).booleanValue();
+   }
+
+   /**
+    * Get the "global" instance.
+    *
+    * @return the VFS instance
+    */
+   public static VFS getInstance()
+   {
+      return instance;
+   }
+
+   /**
+    * Create a new instance.
+    */
+   public VFS()
+   {
+      // By default, there's a root mount which points to the "real" FS
+      //noinspection ThisEscapedInObjectConstruction
+      rootVirtualFile = new VirtualFile("", null);
+      rootMount = new Mount(RealFileSystem.ROOT_INSTANCE, rootVirtualFile);
+   }
+
+   /**
+    * Get file.
+    * Backcompatibility method.
+    *
+    * @param url the url
+    * @return the file matching url
+    * @throws IOException if there is a problem accessing the VFS
+    * @deprecated use {@link #getChild(URL)} instead
+    */
+   @Deprecated
+   @SuppressWarnings("deprecation")
+   public static VirtualFile getRoot(URL url) throws IOException
+   {
+      try
+      {
+         return getRoot(url.toURI());
+      }
+      catch (URISyntaxException e)
+      {
+         IOException ioe = new IOException();
+         ioe.initCause(e);
+         throw ioe;
+      }
+   }
+
+   /**
+    * Get file.
+    * Backcompatibility method.
+    *
+    * @param uri the uri
+    * @return the file matching uri
+    * @throws IOException if there is a problem accessing the VFS
+    * @deprecated use {@link #getChild(URI)} instead
+    */
+   @Deprecated
+   public static VirtualFile getRoot(URI uri) throws IOException
+   {
+      return getInstance().getChild(uri.getPath());
+   }
+
+   /**
+    * Initialize VFS protocol handlers package property.
+    */
+   @SuppressWarnings({"deprecation", "unchecked"})
+   public static void init()
+   {
+      // A small hack that allows us to replace file for now
+      URL.setURLStreamHandlerFactory(null);
+
+      String pkgs = System.getProperty("java.protocol.handler.pkgs");
+      if (pkgs == null || pkgs.trim().length() == 0)
+      {
+         pkgs = "org.jboss.virtual.protocol";
+         System.setProperty("java.protocol.handler.pkgs", pkgs);
+      }
+      else if (pkgs.contains("org.jboss.virtual.protocol") == false)
+      {
+         pkgs = "org.jboss.virtual.protocol|" + pkgs;
+         System.setProperty("java.protocol.handler.pkgs", pkgs);
+      }
+   }
+
+   /**
+    * Mount a filesystem on a mount point in the VFS.  The mount point is any valid file name, existant or non-existant.
+    * If a relative path is given, it will be treated as relative to the VFS root.
+    *
+    * @param mountPoint the mount point
+    * @param fileSystem the file system to mount
+    * @return a handle which can be used to unmount the filesystem
+    * @throws IOException if an I/O error occurs, such as a filesystem already being mounted at the given mount point
+    */
+   public Closeable mount(VirtualFile mountPoint, FileSystem fileSystem) throws IOException {
+      if (mountPoint.getVFS() != this) {
+         throw new IOException("VirtualFile does not match VFS instance");
+      }
+      final VirtualFile parent = mountPoint.getParent();
+      if (parent == null) {
+         throw new IOException("Root filsystem already mounted");
+      }
+      final String name = mountPoint.getName();
+      final Mount mount = new Mount(fileSystem, mountPoint);
+      for (;;) {
+         Map<String, Mount> childMountMap = mounts.get(parent);
+         Map<String, Mount> newMap;
+         if (childMountMap == null) {
+            childMountMap = mounts.putIfAbsent(parent, Collections.singletonMap(name, mount));
+            if (childMountMap == null) {
+               return mount;
+            }
+         }
+         newMap = new HashMap<String, Mount>(childMountMap);
+         if (newMap.put(name, mount) != null) {
+            throw new IOException("Filsystem already mounted at mount point \"" + mountPoint + "\"");
+         }
+         if (mounts.replace(parent, childMountMap, newMap)) {
+            return mount;
+         }
+      }
+   }
+
+   /**
+    * Find a virtual file.
+    *
+    * @param url the URL whose path component is the child path
+    * @return the child
+    * @throws IllegalArgumentException if the path is null
+    */
+   public VirtualFile getChild(URL url) throws URISyntaxException
+   {
+      return getChild(url.toURI());
+   }
+
+   /**
+    * Find a virtual file.
+    *
+    * @param uri the URI whose path component is the child path
+    * @return the child
+    * @throws IllegalArgumentException if the path is null
+    */
+   public VirtualFile getChild(URI uri)
+   {
+      return getChild(uri.getPath());
+   }
+
+   /**
+    * Find a virtual file.
+    *
+    * @param path the child path
+    * @return the child
+    * @throws IllegalArgumentException if the path is null
+    */
+   public VirtualFile getChild(String path)
+   {
+      if (path == null)
+         throw new IllegalArgumentException("Null path");
+
+      return rootVirtualFile.getChild(path);
+   }
+
+   /**
+    * Get the root virtual file for this VFS instance.
+    *
+    * @return the root virtual file
+    */
+   public VirtualFile getRootVirtualFile()
+   {
+      return rootVirtualFile;
+   }
+
+   /**
+    * Get the children
+    *
+    * @return the children
+    * @throws IOException for any problem accessing the virtual file system
+    */
+   public List<VirtualFile> getChildren() throws IOException
+   {
+      return getRootVirtualFile().getChildren(null);
+   }
+
+   /**
+    * Get the children
+    *
+    * @param filter to filter the children
+    * @return the children
+    * @throws IOException for any problem accessing the virtual file system
+    */
+   public List<VirtualFile> getChildren(VirtualFileFilter filter) throws IOException
+   {
+      return getRootVirtualFile().getChildren(filter);
+   }
+
+   /**
+    * Get all the children recursively<p>
+    *
+    * This always uses {@link VisitorAttributes#RECURSE}
+    *
+    * @return the children
+    * @throws IOException for any problem accessing the virtual file system
+    */
+   public List<VirtualFile> getChildrenRecursively() throws IOException
+   {
+      return getRootVirtualFile().getChildrenRecursively(null);
+   }
+
+   /**
+    * Get all the children recursively<p>
+    *
+    * This always uses {@link VisitorAttributes#RECURSE}
+    *
+    * @param filter to filter the children
+    * @return the children
+    * @throws IOException for any problem accessing the virtual file system
+    */
+   public List<VirtualFile> getChildrenRecursively(VirtualFileFilter filter) throws IOException
+   {
+      return getRootVirtualFile().getChildrenRecursively(filter);
+   }
+
+   /**
+    * Visit the virtual file system from the root
+    *
+    * @param visitor the visitor
+    * @throws IOException for any problem accessing the VFS
+    * @throws IllegalArgumentException if the visitor is null
+    */
+   public void visit(VirtualFileVisitor visitor) throws IOException
+   {
+      visitor.visit(rootVirtualFile);
+   }
+
+   /**
+    * Visit the virtual file system
+    *
+    * @param file the file
+    * @param visitor the visitor
+    * @throws IOException for any problem accessing the VFS
+    * @throws IllegalArgumentException if the file or visitor is null
+    */
+   protected void visit(VirtualFile file, VirtualFileVisitor visitor) throws IOException
+   {
+      if (file == null)
+         throw new IllegalArgumentException("Null file");
+
+      if (file.getVFS() != this)
+         throw new IllegalArgumentException("Virtual file from foreign VFS");
+
+      visitor.visit(file);
+   }
+
+   Mount getMount(VirtualFile virtualFile) {
+      final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = this.mounts;
+      for (;;) {
+         final VirtualFile parent = virtualFile.getParent();
+         if (parent == null) {
+            return rootMount;
+         }
+         final Map<String, Mount> parentMounts = mounts.get(parent);
+         if (parentMounts == null) {
+            virtualFile = parent;
+         } else {
+            final Mount mount = parentMounts.get(virtualFile.getName());
+            if (mount == null) {
+               virtualFile = parent;
+            } else {
+               return mount;
+            }
+         }
+      }
+   }
+
+   /**
+    * Get all immediate submounts for a path.
+    *
+    * @param virtualFile the path
+    * @return the collection of present mount (simple) names
+    */
+   Set<String> getSubmounts(VirtualFile virtualFile)
+   {
+      final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = this.mounts;
+      final Map<String, Mount> mountMap = mounts.get(virtualFile);
+      if (mountMap == null) {
+         return emptyRemovableSet();
+      }
+      return new HashSet<String>(mountMap.keySet());
+   }
+
+   private static Closeable doMount(final FileSystem fileSystem, final VirtualFile mountPoint) throws IOException
+   {
+      boolean ok = false;
+      try {
+         final Closeable mountHandle = getInstance().mount(mountPoint, fileSystem);
+         final Closeable closeable = new Closeable()
+         {
+            public void close() throws IOException
+            {
+               VFSUtils.safeClose(mountHandle);
+               VFSUtils.safeClose(fileSystem);
+            }
+         };
+         ok = true;
+         return closeable;
+      } finally {
+         if (! ok) {
+            VFSUtils.safeClose(fileSystem);
+         }
+      }
+   }
+
+   /**
+    * Create and mount a zip file into the filesystem, returning a single handle which will unmount and close the file
+    * system when closed.
+    *
+    * @param zipFile the zip file to mount
+    * @param mountPoint the point at which the filesystem should be mounted
+    * @param tempFileProvider the temporary file provider
+    * @return a handle
+    * @throws IOException if an error occurs
+    */
+   public static Closeable mountZip(File zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+   {
+      boolean ok = false;
+      final TempDir tempDir = tempFileProvider.createTempDir(zipFile.getName());
+      try {
+         final Closeable closeable = doMount(new JavaZipFileSystem(zipFile, tempDir), mountPoint);
+         ok = true;
+         return closeable;
+      } finally {
+         if (! ok) {
+            VFSUtils.safeClose(tempDir);
+         }
+      }
+   }
+
+   /**
+    * Create and mount a zip file into the filesystem, returning a single handle which will unmount and close the file
+    * system when closed.
+    *
+    * @param zipData an input stream containing the zip data
+    * @param zipName the name of the archive
+    * @param mountPoint the point at which the filesystem should be mounted
+    * @param tempFileProvider the temporary file provider
+    * @return a handle
+    * @throws IOException if an error occurs
+    */
+   public static Closeable mountZip(InputStream zipData, String zipName, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+   {
+      boolean ok = false;
+      try {
+         final TempDir tempDir = tempFileProvider.createTempDir(zipName);
+         try {
+            final Closeable closeable = doMount(new JavaZipFileSystem(zipName, zipData, tempDir), mountPoint);
+            ok = true;
+            return closeable;
+         } finally {
+            if (! ok) {
+               VFSUtils.safeClose(tempDir);
+            }
+         }
+      } finally {
+         VFSUtils.safeClose(zipData);
+      }
+   }
+
+   /**
+    * Create and mount a zip file into the filesystem, returning a single handle which will unmount and close the file
+    * system when closed.
+    *
+    * @param zipFile a zip file in the VFS
+    * @param mountPoint the point at which the filesystem should be mounted
+    * @param tempFileProvider the temporary file provider
+    * @return a handle
+    * @throws IOException if an error occurs
+    */
+   public static Closeable mountZip(VirtualFile zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+   {
+      return mountZip(zipFile.openStream(), zipFile.getName(), mountPoint, tempFileProvider);
+   }
+
+   /**
+    * Create and mount a real file system, returning a single handle which will unmount and close the filesystem when
+    * closed.
+    *
+    * @param realRoot the real filesystem root
+    * @param mountPoint the point at which the filesystem should be mounted
+    * @return a handle
+    * @throws IOException if an error occurs
+    */
+   public static Closeable mountReal(File realRoot, VirtualFile mountPoint) throws IOException
+   {
+      return doMount(new RealFileSystem(realRoot), mountPoint);
+   }
+
+   /**
+    * Create and mount a temporary file system, returning a single handle which will unmount and close the filesystem
+    * when closed.
+    *
+    * @param mountPoint the point at which the filesystem should be mounted
+    * @param tempFileProvider the temporary file provider
+    * @return a handle
+    * @throws IOException if an error occurs
+    */
+   public static Closeable mountTemp(VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+   {
+      boolean ok = false;
+      final TempDir tempDir = tempFileProvider.createTempDir("tmpfs");
+      try {
+         final Closeable closeable = doMount(new RealFileSystem(tempDir.getRoot()), mountPoint);
+         ok = true;
+         return new Closeable()
+         {
+            public void close() throws IOException
+            {
+               VFSUtils.safeClose(closeable);
+               VFSUtils.safeClose(tempDir);
+            }
+         };
+      } finally {
+         if (! ok) {
+            VFSUtils.safeClose(tempDir);
+         }
+      }
+   }
+
+   /**
+    * Create and mount an expanded zip file in a temporary file system, returning a single handle which will unmount and
+    * close the filesystem when closed.
+    *
+    * @param zipFile the zip file to mount
+    * @param mountPoint the point at which the filesystem should be mounted
+    * @param tempFileProvider the temporary file provider
+    * @return a handle
+    * @throws IOException if an error occurs
+    */
+   public static Closeable mountZipExpanded(File zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+   {
+      boolean ok = false;
+      final TempDir tempDir = tempFileProvider.createTempDir(zipFile.getName());
+      try {
+         final File rootFile = tempDir.getRoot();
+         unzip(zipFile, rootFile);
+         final Closeable closeable = doMount(new RealFileSystem(rootFile), mountPoint);
+         ok = true;
+         return new Closeable()
+         {
+            public void close() throws IOException
+            {
+               VFSUtils.safeClose(closeable);
+               VFSUtils.safeClose(tempDir);
+            }
+         };
+      } finally {
+         if (! ok) {
+            VFSUtils.safeClose(tempDir);
+         }
+      }
+   }
+
+   /**
+    * Create and mount an expanded zip file in a temporary file system, returning a single handle which will unmount and
+    * close the filesystem when closed.  The given zip data stream is closed.
+    *
+    * @param zipData an input stream containing the zip data
+    * @param zipName the name of the archive
+    * @param mountPoint the point at which the filesystem should be mounted
+    * @param tempFileProvider the temporary file provider
+    * @return a handle
+    * @throws IOException if an error occurs
+    */
+   public static Closeable mountZipExpanded(InputStream zipData, String zipName, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+   {
+      try {
+         boolean ok = false;
+         final TempDir tempDir = tempFileProvider.createTempDir(zipName);
+         try {
+            final File zipFile = File.createTempFile(zipName + "-", ".tmp", tempDir.getRoot());
+            try {
+               final FileOutputStream os = new FileOutputStream(zipFile);
+               try {
+                  // allow an error on close to terminate the unzip
+                  VFSUtils.copyStream(zipData, os);
+                  zipData.close();
+                  os.close();
+               } finally {
+                  VFSUtils.safeClose(zipData);
+                  VFSUtils.safeClose(os);
+               }
+               final File rootFile = tempDir.getRoot();
+               unzip(zipFile, rootFile);
+               final Closeable closeable = doMount(new RealFileSystem(rootFile), mountPoint);
+               ok = true;
+               return new Closeable()
+               {
+                  public void close() throws IOException
+                  {
+                     VFSUtils.safeClose(closeable);
+                     VFSUtils.safeClose(tempDir);
+                  }
+               };
+            } finally {
+               zipFile.delete();
+            }
+         } finally {
+            if (! ok) {
+               VFSUtils.safeClose(tempDir);
+            }
+         }
+      } finally {
+         VFSUtils.safeClose(zipData);
+      }
+   }
+
+   /**
+    * Create and mount an expanded zip file in a temporary file system, returning a single handle which will unmount and
+    * close the filesystem when closed.  The given zip data stream is closed.
+    *
+    * @param zipFile a zip file in the VFS
+    * @param mountPoint the point at which the filesystem should be mounted
+    * @param tempFileProvider the temporary file provider
+    * @return a handle
+    * @throws IOException if an error occurs
+    */
+   public static Closeable mountZipExpanded(VirtualFile zipFile, VirtualFile mountPoint, TempFileProvider tempFileProvider) throws IOException
+   {
+      return mountZipExpanded(zipFile.openStream(), zipFile.getName(), mountPoint, tempFileProvider);
+   }
+
+   /**
+    * Expand a zip file to a destination directory.  The directory must exist.  If an error occurs, the destination
+    * directory may contain a partially-extracted archive, so cleanup is up to the caller.
+    *
+    * @param zipFile the zip file
+    * @param destDir the destination directory
+    * @throws IOException if an error occurs
+    */
+   public static void unzip(File zipFile, File destDir) throws IOException
+   {
+      final ZipFile zip = new ZipFile(zipFile);
+      try {
+         final Set<File> createdDirs = new HashSet<File>();
+         final Enumeration<? extends ZipEntry> entries = zip.entries();
+         FILES_LOOP: while (entries.hasMoreElements()) {
+            final ZipEntry zipEntry = entries.nextElement();
+            final String name = zipEntry.getName();
+            final List<String> tokens = PathTokenizer.getTokens(name);
+            final Iterator<String> it = tokens.iterator();
+            File current = destDir;
+            while (it.hasNext())
+            {
+               String token = it.next();
+               if (PathTokenizer.isCurrentToken(token) || PathTokenizer.isReverseToken(token))
+               {
+                  // invalid file; skip it!
+                  continue FILES_LOOP;
+               }
+               current = new File(current, token);
+               if ((it.hasNext() || zipEntry.isDirectory()) && createdDirs.add(current))
+               {
+                  current.mkdir();
+               }
+            }
+            if (! zipEntry.isDirectory()) {
+               final InputStream is = zip.getInputStream(zipEntry);
+               try {
+                  final FileOutputStream os = new FileOutputStream(current);
+                  try {
+                     VFSUtils.copyStream(is, os);
+                     // allow an error on close to terminate the unzip
+                     is.close();
+                     os.close();
+                  } finally {
+                     VFSUtils.safeClose(os);
+                  }
+               } finally {
+                  VFSUtils.safeClose(is);
+               }
+            }
+         }
+      } finally {
+         VFSUtils.safeClose(zip);
+      }
+   }
+
+   @SuppressWarnings({ "unchecked" })
+   private static <E> Set<E> emptyRemovableSet() {
+      return EMPTY_REMOVABLE_SET;
+   }
+
+   private static final Set EMPTY_REMOVABLE_SET = new EmptyRemovableSet();
+
+   private static final class EmptyRemovableSet<E> extends AbstractSet<E> {
+
+      public boolean remove(Object o)
+      {
+         return false;
+      }
+
+      public boolean retainAll(Collection<?> c)
+      {
+         return false;
+      }
+
+      public void clear()
+      {
+      }
+
+      public Iterator<E> iterator()
+      {
+         return Collections.<E>emptySet().iterator();
+      }
+
+      public int size()
+      {
+         return 0;
+      }
+   }
+
+   /**
+    * The mount representation.  This instance represents a binding between a position in the virtual filesystem and
+    * the backing filesystem implementation; the same {@code FileSystem} may be mounted in more than one place, however
+    * only one {@code FileSystem} may be bound to a specific path at a time.
+    */
+   final class Mount implements Closeable {
+      private final FileSystem fileSystem;
+      private final VirtualFile mountPoint;
+      private final StackTraceElement[] allocationPoint;
+      private final AtomicBoolean closed = new AtomicBoolean(false);
+
+      Mount(FileSystem fileSystem, VirtualFile mountPoint)
+      {
+         this.fileSystem = fileSystem;
+         this.mountPoint = mountPoint;
+         allocationPoint = Thread.currentThread().getStackTrace();
+      }
+
+      public void close() throws IOException
+      {
+         if (closed.getAndSet(true)) {
+            return;
+         }
+         final String name = mountPoint.getName();
+         final VirtualFile parent = mountPoint.getParent();
+         final ConcurrentMap<VirtualFile, Map<String, Mount>> mounts = VFS.this.mounts;
+         for (;;) {
+            final Map<String, Mount> parentMounts = mounts.get(parent);
+            if (parentMounts == null) {
+               return;
+            }
+            final VFS.Mount mount = parentMounts.get(name);
+            if (mount != this) {
+               return;
+            }
+            final Map<String, Mount> newParentMounts;
+            if (parentMounts.size() == 2) {
+               final Iterator<Map.Entry<String, Mount>> ei = parentMounts.entrySet().iterator();
+               final Map.Entry<String, Mount> e1 = ei.next();
+               if (e1.getKey().equals(name)) {
+                  final Map.Entry<String, Mount> e2 = ei.next();
+                  newParentMounts = Collections.singletonMap(e2.getKey(), e2.getValue());
+               } else {
+                  newParentMounts = Collections.singletonMap(e1.getKey(), e1.getValue());
+               }
+               if (mounts.replace(parent, parentMounts, newParentMounts)) {
+                  return;
+               }
+            } else if (parentMounts.size() == 1) {
+               if (mounts.remove(parent, parentMounts)) {
+                  return;
+               }
+            } else {
+               newParentMounts = new HashMap<String, Mount>(parentMounts);
+               newParentMounts.remove(name);
+               if (mounts.replace(parent, parentMounts, newParentMounts)) {
+                  return;
+               }
+            }
+         }
+      }
+
+      FileSystem getFileSystem()
+      {
+         return fileSystem;
+      }
+
+      VirtualFile getMountPoint()
+      {
+         return mountPoint;
+      }
+
+      protected void finalize() throws IOException
+      {
+         if (! closed.get()) {
+            final StackTraceElement[] allocationPoint = this.allocationPoint;
+            if (allocationPoint != null) {
+               final LeakDescriptor t = new LeakDescriptor();
+               t.setStackTrace(allocationPoint);
+               log.warnf(t, "A VFS mount (%s) was leaked!", mountPoint);
+            } else {
+               log.warnf("A VFS mount (%s) was leaked!", mountPoint);
+            }
+            close();
+         }
+      }
+   }
+
+   private static final class LeakDescriptor extends Throwable {
+      private static final long serialVersionUID = 6034058126740270584L;
+
+      public String toString()
+      {
+         return "Allocation stack trace:";
+      }
+   }
+}

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSInputSource.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFSInputSource.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSInputSource.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,85 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.virtual;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.InputStreamReader;
-
-import org.xml.sax.InputSource;
-
-/**
- * VFS based impl of InputSource.
- *
- * @author <a href="mailto:ales.justin at jboss.org">Ales Justin</a>
- */
-public class VFSInputSource extends InputSource
-{
-   private VirtualFile file;
-
-   public VFSInputSource(VirtualFile file)
-   {
-      if (file == null)
-         throw new IllegalArgumentException("Null file");
-
-      this.file = file;
-   }
-
-   @Override
-   public String getSystemId()
-   {
-      try
-      {
-         return VFSUtils.getVirtualURI(file).toString();
-      }
-      catch (Exception e)
-      {
-         throw new RuntimeException(e);
-      }
-   }
-
-   @Override
-   public InputStream getByteStream()
-   {
-      try
-      {
-         return file.openStream();
-      }
-      catch (IOException e)
-      {
-         throw new RuntimeException(e);
-      }
-   }
-
-   @Override
-   public Reader getCharacterStream()
-   {
-      return new InputStreamReader(getByteStream());
-   }
-
-   @Override
-   public String toString()
-   {
-      return file.getPathName();
-   }
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSInputSource.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFSInputSource.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSInputSource.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSInputSource.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,85 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.vfs;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.InputStreamReader;
+
+import org.xml.sax.InputSource;
+
+/**
+ * VFS based impl of InputSource.
+ *
+ * @author <a href="mailto:ales.justin at jboss.org">Ales Justin</a>
+ */
+public class VFSInputSource extends InputSource
+{
+   private VirtualFile file;
+
+   public VFSInputSource(VirtualFile file)
+   {
+      if (file == null)
+         throw new IllegalArgumentException("Null file");
+
+      this.file = file;
+   }
+
+   @Override
+   public String getSystemId()
+   {
+      try
+      {
+         return VFSUtils.getVirtualURI(file).toString();
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   @Override
+   public InputStream getByteStream()
+   {
+      try
+      {
+         return file.openStream();
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   @Override
+   public Reader getCharacterStream()
+   {
+      return new InputStreamReader(getByteStream());
+   }
+
+   @Override
+   public String toString()
+   {
+      return file.getPathName();
+   }
+}

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSUtils.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFSUtils.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSUtils.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,597 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.virtual;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.zip.ZipFile;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-
-import org.jboss.logging.Logger;
-import org.jboss.util.collection.CollectionsFactory;
-
-/**
- * VFS Utilities
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author <a href="ales.justin at jboss.com">Ales Justin</a>
- * @version $Revision: 1.1 $
- */
-public class VFSUtils
-{
-   /** The log */
-   private static final Logger log = Logger.getLogger(VFSUtils.class);
-
-   /** The default encoding */
-   private static final String DEFAULT_ENCODING = "UTF-8";
-
-   /**
-    * Constant representing the URL file protocol
-    */
-   public static final String FILE_PROTOCOL = "file";
-
-   /** Standard separator for JAR URL */
-   public static final String JAR_URL_SEPARATOR = "!/";
-
-   /** The default buffer size to use for copies */
-   public static final int DEFAULT_BUFFER_SIZE = 65536;
-
-   private VFSUtils()
-   {
-   }
-
-   /**
-    * Get the paths string for a collection of virtual files
-    *
-    * @param paths the paths
-    * @return the string
-    * @throws IllegalArgumentException for null paths
-    */
-   public static String getPathsString(Collection<VirtualFile> paths)
-   {
-      if (paths == null)
-         throw new IllegalArgumentException("Null paths");
-
-      StringBuilder buffer = new StringBuilder();
-      boolean first = true;
-      for (VirtualFile path : paths)
-      {
-         if (path == null)
-            throw new IllegalArgumentException("Null path in " + paths);
-         if (first == false)
-            buffer.append(':');
-         else
-            first = false;
-         buffer.append(path.getPathName());
-      }
-
-      if (first == true)
-         buffer.append("<empty>");
-
-      return buffer.toString();
-   }
-
-   /**
-    * Add manifest paths
-    *
-    * @param file the file
-    * @param paths the paths to add to
-    * @throws IOException if there is an error reading the manifest or the
-    *         virtual file is closed
-    * @throws IllegalStateException if the file has no parent
-    * @throws IllegalArgumentException for a null file or paths
-    */
-   public static void addManifestLocations(VirtualFile file, List<VirtualFile> paths) throws IOException
-   {
-      if (file == null)
-         throw new IllegalArgumentException("Null file");
-      if (paths == null)
-         throw new IllegalArgumentException("Null paths");
-
-      boolean trace = log.isTraceEnabled();
-
-      Manifest manifest = getManifest(file);
-      if (manifest == null)
-         return;
-
-      Attributes mainAttributes = manifest.getMainAttributes();
-      String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
-
-      if (classPath == null)
-      {
-         if (trace)
-            log.trace("Manifest has no Class-Path for " + file.getPathName());
-         return;
-      }
-
-      VirtualFile parent = file.getParent();
-      if (parent == null)
-      {
-         log.debug(file + " has no parent.");
-         return;
-      }
-
-      if (trace)
-         log.trace("Parsing Class-Path: " + classPath + " for " + file.getName() + " parent=" + parent.getName());
-
-      StringTokenizer tokenizer = new StringTokenizer(classPath);
-      while (tokenizer.hasMoreTokens())
-      {
-         String path = tokenizer.nextToken();
-         try
-         {
-            VirtualFile vf = parent.getChild(path);
-            if(vf != null)
-            {
-               if(paths.contains(vf) == false)
-               {
-                  paths.add(vf);
-                  // Recursively process the jar
-                  addManifestLocations(vf, paths);
-               }
-               else if (trace)
-                  log.trace(vf.getName() + " from manifiest is already in the classpath " + paths);
-            }
-            else if (trace)
-               log.trace("Unable to find " + path + " from " + parent.getName());
-         }
-         catch (IOException e)
-         {
-            log.debug("Manifest Class-Path entry " + path + " ignored for " + file.getPathName() + " reason=" + e);
-         }
-      }
-   }
-
-   /**
-    * Get a manifest from a virtual file,
-    * assuming the virtual file is the root of an archive
-    *
-    * @param archive the root the archive
-    * @return the manifest or null if not found
-    * @throws IOException if there is an error reading the manifest or the
-    *         virtual file is closed
-    * @throws IllegalArgumentException for a null archive
-    */
-   public static Manifest getManifest(VirtualFile archive) throws IOException
-   {
-      if (archive == null)
-         throw new IllegalArgumentException("Null archive");
-
-      VirtualFile manifest = archive.getChild(JarFile.MANIFEST_NAME);
-      if (manifest == null)
-      {
-         if (log.isTraceEnabled())
-            log.trace("Can't find manifest for " + archive.getPathName());
-         return null;
-      }
-      return readManifest(manifest);
-   }
-
-   /**
-    * Read the manifest from given manifest VirtualFile.
-    *
-    * @param manifest the VF to read from
-    * @return JAR's manifest
-    * @throws IOException if problems while opening VF stream occur
-    */
-   public static Manifest readManifest(VirtualFile manifest) throws IOException
-   {
-      if (manifest == null)
-         throw new IllegalArgumentException("Null manifest file");
-
-      InputStream stream = manifest.openStream();
-      try
-      {
-         return new Manifest(stream);
-      }
-      finally
-      {
-         safeClose(stream);
-      }
-   }
-
-   /**
-    * Fix a name (removes any trailing slash)
-    *
-    * @param name the name to fix
-    * @return the fixed name
-    * @throws IllegalArgumentException for a null name
-    */
-   public static String fixName(String name)
-   {
-      if (name == null)
-         throw new IllegalArgumentException("Null name");
-
-      int length = name.length();
-      if (length <= 1)
-         return name;
-      if (name.charAt(length-1) == '/')
-         return name.substring(0, length-1);
-
-      return name;
-   }
-
-   /**
-    * Decode the path with UTF-8 encoding..
-    *
-    * @param path the path to decode
-    * @return decoded path
-    */
-   public static String decode(String path)
-   {
-      return decode(path, DEFAULT_ENCODING);
-   }
-
-   /**
-    * Decode the path.
-    *
-    * @param path the path to decode
-    * @param encoding the encodeing
-    * @return decoded path
-    */
-   public static String decode(String path, String encoding)
-   {
-      try
-      {
-         return URLDecoder.decode(path, encoding);
-      }
-      catch (UnsupportedEncodingException e)
-      {
-         throw new IllegalArgumentException("Cannot decode: " + path + " [" + encoding + "]", e);
-      }
-   }
-
-   /**
-    * Get the name.
-    *
-    * @param uri the uri
-    * @return name from uri's path
-    */
-   public static String getName(URI uri)
-   {
-      if (uri == null)
-         throw new IllegalArgumentException("Null uri");
-
-      String name = uri.getPath();
-      if( name != null )
-      {
-         // TODO: Not correct for certain uris like jar:...!/
-         int lastSlash = name.lastIndexOf('/');
-         if( lastSlash > 0 )
-            name = name.substring(lastSlash+1);
-      }
-      return name;
-   }
-
-   /**
-    * Take a URL.getQuery string and parse it into name=value pairs
-    *
-    * @param query Possibly empty/null url query string
-    * @return String[] for the name/value pairs in the query. May be empty but never null.
-    */
-   public static Map<String, String> parseURLQuery(String query)
-   {
-	   Map<String, String> pairsMap = CollectionsFactory.createLazyMap();
-      if(query != null)
-      {
-   	   StringTokenizer tokenizer = new StringTokenizer(query, "=&");
-   	   while(tokenizer.hasMoreTokens())
-   	   {
-   		   String name = tokenizer.nextToken();
-   		   String value = tokenizer.nextToken();
-   		   pairsMap.put(name, value);
-   	   }
-      }
-	   return pairsMap;
-   }
-
-   /**
-    * Deal with urls that may include spaces.
-    *
-    * @param url the url
-    * @return uri the uri
-    * @throws URISyntaxException for any error
-    */
-   public static URI toURI(URL url) throws URISyntaxException
-   {
-      if (url == null)
-         throw new IllegalArgumentException("Null url");
-
-      try
-      {
-         return url.toURI();
-      }
-      catch (URISyntaxException e)
-      {
-         String urispec = url.toExternalForm();
-         // Escape percent sign and spaces
-         urispec = urispec.replaceAll("%", "%25");
-         urispec = urispec.replaceAll(" ", "%20");
-         return new URI(urispec);
-      }
-   }
-
-   /**
-    * Ensure the url is convertible to URI by encoding spaces and percent characters if necessary
-    *
-    * @param url to be sanitized
-    * @return sanitized URL
-    * @throws URISyntaxException if URI conversion can't be fixed
-    * @throws MalformedURLException if an error occurs
-    */
-   public static URL sanitizeURL(URL url) throws URISyntaxException, MalformedURLException
-   {
-      return toURI(url).toURL();
-   }
-
-   /**
-    * Copy input stream to output stream and close them both
-    *
-    * @param is input stream
-    * @param os output stream
-    * @throws IOException for any error
-    */
-   public static void copyStreamAndClose(InputStream is, OutputStream os) throws IOException
-   {
-      copyStreamAndClose(is, os, DEFAULT_BUFFER_SIZE);
-   }
-
-   /**
-    * Copy input stream to output stream and close them both
-    *
-    * @param is input stream
-    * @param os output stream
-    * @param bufferSize the buffer size to use
-    * @throws IOException for any error
-    */
-   public static void copyStreamAndClose(InputStream is, OutputStream os, int bufferSize)
-         throws IOException
-   {
-      try
-      {
-         copyStream(is, os, bufferSize);
-         // throw an exception if the close fails since some data might be lost
-         is.close();
-         os.close();
-      }
-      finally
-      {
-         // ...but still guarantee that they're both closed
-         safeClose(is);
-         safeClose(os);
-      }
-   }
-
-   /**
-    * Copy input stream to output stream without closing streams.
-    * Flushes output stream when done.
-    *
-    * @param is input stream
-    * @param os output stream
-    * @throws IOException for any error
-    */
-   public static void copyStream(InputStream is, OutputStream os) throws IOException
-   {
-      copyStream(is, os, DEFAULT_BUFFER_SIZE);
-   }
-
-   /**
-    * Copy input stream to output stream without closing streams.
-    * Flushes output stream when done.
-    *
-    * @param is input stream
-    * @param os output stream
-    * @param bufferSize the buffer size to use
-    * @throws IOException for any error
-    */
-   public static void copyStream(InputStream is, OutputStream os, int bufferSize)
-         throws IOException
-   {
-      if (is == null)
-         throw new IllegalArgumentException("input stream is null");
-      if (os == null)
-         throw new IllegalArgumentException("output stream is null");
-      byte [] buff = new byte[bufferSize];
-      int rc;
-      while ((rc = is.read(buff)) != -1) os.write(buff, 0, rc);
-      os.flush();
-   }
-
-   /**
-    * Write the given bytes to the given virtual file, replacing its current contents (if any) or creating a new
-    * file if one does not exist.
-    *
-    * @param virtualFile the virtual file to write
-    * @param bytes the bytes
-    * @throws IOException if an error occurs
-    */
-   public static void writeFile(VirtualFile virtualFile, byte[] bytes) throws IOException
-   {
-      final File file = virtualFile.getPhysicalFile();
-      file.getParentFile().mkdirs();
-      final FileOutputStream fos = new FileOutputStream(file);
-      try {
-         fos.write(bytes);
-         fos.close();
-      } finally {
-         safeClose(fos);
-      }
-   }
-
-   /**
-    * Get the virtual URL for a virtual file.  This URL can be used to access the virtual file; however, taking the
-    * file part of the URL and attempting to use it with the {@link java.io.File} class may fail if the file is not
-    * present on the physical filesystem, and in general should not be attempted.
-    *
-    * @param file the virtual file
-    * @return the URL
-    * @throws MalformedURLException if the file cannot be coerced into a URL for some reason
-    */
-   public static URL getVirtualURL(VirtualFile file) throws MalformedURLException
-   {
-      // todo: specify the URL handler directly as a minor optimization
-      return new URL("file", "", -1, file.getPathName(true));
-   }
-
-   /**
-    * Get the virtual URI for a virtual file.
-    *
-    * @param file the virtual file
-    * @return the URI
-    * @throws URISyntaxException if the file cannot be coerced into a URI for some reason
-    */
-   public static URI getVirtualURI(VirtualFile file) throws URISyntaxException
-   {
-      return new URI("file", "", file.getPathName(true), null);
-   }
-
-   /**
-    * Get a physical URL for a virtual file.  See the warnings on the {@link VirtualFile#getPhysicalFile()} method
-    * before using this method.
-    *
-    * @param file the virtual file
-    * @return the physical file URL
-    * @throws IOException if an I/O error occurs getting the physical file
-    */
-   public static URL getPhysicalURL(VirtualFile file) throws IOException
-   {
-      return getPhysicalURI(file).toURL();
-   }
-
-   /**
-    * Get a physical URI for a virtual file.  See the warnings on the {@link VirtualFile#getPhysicalFile()} method
-    * before using this method.
-    *
-    * @param file the virtual file
-    * @return the physical file URL
-    * @throws IOException if an I/O error occurs getting the physical file
-    */
-   public static URI getPhysicalURI(VirtualFile file) throws IOException
-   {
-      return file.getPhysicalFile().toURI();
-   }
-
-   /**
-    * Safely close some resource without throwing an exception.  Any exception will be logged at TRACE level.
-    *
-    * @param c the resource
-    */
-   public static void safeClose(final Closeable c)
-   {
-      if (c != null) try {
-         c.close();
-      }
-      catch (Exception e)
-      {
-         log.trace("Failed to close resource", e);
-      }
-   }
-
-   /**
-    * Safely close some resources without throwing an exception.  Any exception will be logged at TRACE level.
-    *
-    * @param ci the resources
-    */
-   public static void safeClose(final Iterable<? extends Closeable> ci)
-   {
-      if (ci != null) for (Closeable closeable : ci)
-      {
-         safeClose(closeable);
-      }
-   }
-
-   /**
-    * Safely close some resource without throwing an exception.  Any exception will be logged at TRACE level.
-    *
-    * @param zipFile the resource
-    */
-   public static void safeClose(final ZipFile zipFile)
-   {
-      if (zipFile != null) try {
-         zipFile.close();
-      }
-      catch (Exception e)
-      {
-         log.trace("Failed to close resource", e);
-      }
-   }
-
-   /**
-    * Attempt to recursively delete a real file.
-    *
-    * @param root the real file to delete
-    * @return {@code true} if the file was deleted
-    */
-   public static boolean recursiveDelete(File root)
-   {
-      boolean ok = true;
-      if (root.isDirectory()) {
-         final File[] files = root.listFiles();
-         for (File file : files)
-         {
-            ok &= recursiveDelete(file);
-         }
-         return ok && (root.delete() || ! root.exists());
-      } else {
-         ok &= root.delete() || ! root.exists();
-      }
-      return ok;
-   }
-
-   /**
-    * Attempt to recursively delete a virtual file.
-    *
-    * @param root the virtual file to delete
-    * @return {@code true} if the file was deleted
-    */
-   public static boolean recursiveDelete(VirtualFile root) throws IOException
-   {
-      boolean ok = true;
-      if (root.isDirectory()) {
-         final List<VirtualFile> files = root.getChildren();
-         for (VirtualFile file : files)
-         {
-            ok &= recursiveDelete(file);
-         }
-         return ok && (root.delete() || ! root.exists());
-      } else {
-         ok &= root.delete() || ! root.exists();
-      }
-      return ok;
-   }
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSUtils.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VFSUtils.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSUtils.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VFSUtils.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,597 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.vfs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.zip.ZipFile;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.jboss.logging.Logger;
+import org.jboss.util.collection.CollectionsFactory;
+
+/**
+ * VFS Utilities
+ *
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @version $Revision: 1.1 $
+ */
+public class VFSUtils
+{
+   /** The log */
+   private static final Logger log = Logger.getLogger(VFSUtils.class);
+
+   /** The default encoding */
+   private static final String DEFAULT_ENCODING = "UTF-8";
+
+   /**
+    * Constant representing the URL file protocol
+    */
+   public static final String FILE_PROTOCOL = "file";
+
+   /** Standard separator for JAR URL */
+   public static final String JAR_URL_SEPARATOR = "!/";
+
+   /** The default buffer size to use for copies */
+   public static final int DEFAULT_BUFFER_SIZE = 65536;
+
+   private VFSUtils()
+   {
+   }
+
+   /**
+    * Get the paths string for a collection of virtual files
+    *
+    * @param paths the paths
+    * @return the string
+    * @throws IllegalArgumentException for null paths
+    */
+   public static String getPathsString(Collection<VirtualFile> paths)
+   {
+      if (paths == null)
+         throw new IllegalArgumentException("Null paths");
+
+      StringBuilder buffer = new StringBuilder();
+      boolean first = true;
+      for (VirtualFile path : paths)
+      {
+         if (path == null)
+            throw new IllegalArgumentException("Null path in " + paths);
+         if (first == false)
+            buffer.append(':');
+         else
+            first = false;
+         buffer.append(path.getPathName());
+      }
+
+      if (first == true)
+         buffer.append("<empty>");
+
+      return buffer.toString();
+   }
+
+   /**
+    * Add manifest paths
+    *
+    * @param file the file
+    * @param paths the paths to add to
+    * @throws IOException if there is an error reading the manifest or the
+    *         virtual file is closed
+    * @throws IllegalStateException if the file has no parent
+    * @throws IllegalArgumentException for a null file or paths
+    */
+   public static void addManifestLocations(VirtualFile file, List<VirtualFile> paths) throws IOException
+   {
+      if (file == null)
+         throw new IllegalArgumentException("Null file");
+      if (paths == null)
+         throw new IllegalArgumentException("Null paths");
+
+      boolean trace = log.isTraceEnabled();
+
+      Manifest manifest = getManifest(file);
+      if (manifest == null)
+         return;
+
+      Attributes mainAttributes = manifest.getMainAttributes();
+      String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
+
+      if (classPath == null)
+      {
+         if (trace)
+            log.trace("Manifest has no Class-Path for " + file.getPathName());
+         return;
+      }
+
+      VirtualFile parent = file.getParent();
+      if (parent == null)
+      {
+         log.debug(file + " has no parent.");
+         return;
+      }
+
+      if (trace)
+         log.trace("Parsing Class-Path: " + classPath + " for " + file.getName() + " parent=" + parent.getName());
+
+      StringTokenizer tokenizer = new StringTokenizer(classPath);
+      while (tokenizer.hasMoreTokens())
+      {
+         String path = tokenizer.nextToken();
+         try
+         {
+            VirtualFile vf = parent.getChild(path);
+            if(vf != null)
+            {
+               if(paths.contains(vf) == false)
+               {
+                  paths.add(vf);
+                  // Recursively process the jar
+                  addManifestLocations(vf, paths);
+               }
+               else if (trace)
+                  log.trace(vf.getName() + " from manifiest is already in the classpath " + paths);
+            }
+            else if (trace)
+               log.trace("Unable to find " + path + " from " + parent.getName());
+         }
+         catch (IOException e)
+         {
+            log.debug("Manifest Class-Path entry " + path + " ignored for " + file.getPathName() + " reason=" + e);
+         }
+      }
+   }
+
+   /**
+    * Get a manifest from a virtual file,
+    * assuming the virtual file is the root of an archive
+    *
+    * @param archive the root the archive
+    * @return the manifest or null if not found
+    * @throws IOException if there is an error reading the manifest or the
+    *         virtual file is closed
+    * @throws IllegalArgumentException for a null archive
+    */
+   public static Manifest getManifest(VirtualFile archive) throws IOException
+   {
+      if (archive == null)
+         throw new IllegalArgumentException("Null archive");
+
+      VirtualFile manifest = archive.getChild(JarFile.MANIFEST_NAME);
+      if (manifest == null)
+      {
+         if (log.isTraceEnabled())
+            log.trace("Can't find manifest for " + archive.getPathName());
+         return null;
+      }
+      return readManifest(manifest);
+   }
+
+   /**
+    * Read the manifest from given manifest VirtualFile.
+    *
+    * @param manifest the VF to read from
+    * @return JAR's manifest
+    * @throws IOException if problems while opening VF stream occur
+    */
+   public static Manifest readManifest(VirtualFile manifest) throws IOException
+   {
+      if (manifest == null)
+         throw new IllegalArgumentException("Null manifest file");
+
+      InputStream stream = manifest.openStream();
+      try
+      {
+         return new Manifest(stream);
+      }
+      finally
+      {
+         safeClose(stream);
+      }
+   }
+
+   /**
+    * Fix a name (removes any trailing slash)
+    *
+    * @param name the name to fix
+    * @return the fixed name
+    * @throws IllegalArgumentException for a null name
+    */
+   public static String fixName(String name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+
+      int length = name.length();
+      if (length <= 1)
+         return name;
+      if (name.charAt(length-1) == '/')
+         return name.substring(0, length-1);
+
+      return name;
+   }
+
+   /**
+    * Decode the path with UTF-8 encoding..
+    *
+    * @param path the path to decode
+    * @return decoded path
+    */
+   public static String decode(String path)
+   {
+      return decode(path, DEFAULT_ENCODING);
+   }
+
+   /**
+    * Decode the path.
+    *
+    * @param path the path to decode
+    * @param encoding the encodeing
+    * @return decoded path
+    */
+   public static String decode(String path, String encoding)
+   {
+      try
+      {
+         return URLDecoder.decode(path, encoding);
+      }
+      catch (UnsupportedEncodingException e)
+      {
+         throw new IllegalArgumentException("Cannot decode: " + path + " [" + encoding + "]", e);
+      }
+   }
+
+   /**
+    * Get the name.
+    *
+    * @param uri the uri
+    * @return name from uri's path
+    */
+   public static String getName(URI uri)
+   {
+      if (uri == null)
+         throw new IllegalArgumentException("Null uri");
+
+      String name = uri.getPath();
+      if( name != null )
+      {
+         // TODO: Not correct for certain uris like jar:...!/
+         int lastSlash = name.lastIndexOf('/');
+         if( lastSlash > 0 )
+            name = name.substring(lastSlash+1);
+      }
+      return name;
+   }
+
+   /**
+    * Take a URL.getQuery string and parse it into name=value pairs
+    *
+    * @param query Possibly empty/null url query string
+    * @return String[] for the name/value pairs in the query. May be empty but never null.
+    */
+   public static Map<String, String> parseURLQuery(String query)
+   {
+	   Map<String, String> pairsMap = CollectionsFactory.createLazyMap();
+      if(query != null)
+      {
+   	   StringTokenizer tokenizer = new StringTokenizer(query, "=&");
+   	   while(tokenizer.hasMoreTokens())
+   	   {
+   		   String name = tokenizer.nextToken();
+   		   String value = tokenizer.nextToken();
+   		   pairsMap.put(name, value);
+   	   }
+      }
+	   return pairsMap;
+   }
+
+   /**
+    * Deal with urls that may include spaces.
+    *
+    * @param url the url
+    * @return uri the uri
+    * @throws URISyntaxException for any error
+    */
+   public static URI toURI(URL url) throws URISyntaxException
+   {
+      if (url == null)
+         throw new IllegalArgumentException("Null url");
+
+      try
+      {
+         return url.toURI();
+      }
+      catch (URISyntaxException e)
+      {
+         String urispec = url.toExternalForm();
+         // Escape percent sign and spaces
+         urispec = urispec.replaceAll("%", "%25");
+         urispec = urispec.replaceAll(" ", "%20");
+         return new URI(urispec);
+      }
+   }
+
+   /**
+    * Ensure the url is convertible to URI by encoding spaces and percent characters if necessary
+    *
+    * @param url to be sanitized
+    * @return sanitized URL
+    * @throws URISyntaxException if URI conversion can't be fixed
+    * @throws MalformedURLException if an error occurs
+    */
+   public static URL sanitizeURL(URL url) throws URISyntaxException, MalformedURLException
+   {
+      return toURI(url).toURL();
+   }
+
+   /**
+    * Copy input stream to output stream and close them both
+    *
+    * @param is input stream
+    * @param os output stream
+    * @throws IOException for any error
+    */
+   public static void copyStreamAndClose(InputStream is, OutputStream os) throws IOException
+   {
+      copyStreamAndClose(is, os, DEFAULT_BUFFER_SIZE);
+   }
+
+   /**
+    * Copy input stream to output stream and close them both
+    *
+    * @param is input stream
+    * @param os output stream
+    * @param bufferSize the buffer size to use
+    * @throws IOException for any error
+    */
+   public static void copyStreamAndClose(InputStream is, OutputStream os, int bufferSize)
+         throws IOException
+   {
+      try
+      {
+         copyStream(is, os, bufferSize);
+         // throw an exception if the close fails since some data might be lost
+         is.close();
+         os.close();
+      }
+      finally
+      {
+         // ...but still guarantee that they're both closed
+         safeClose(is);
+         safeClose(os);
+      }
+   }
+
+   /**
+    * Copy input stream to output stream without closing streams.
+    * Flushes output stream when done.
+    *
+    * @param is input stream
+    * @param os output stream
+    * @throws IOException for any error
+    */
+   public static void copyStream(InputStream is, OutputStream os) throws IOException
+   {
+      copyStream(is, os, DEFAULT_BUFFER_SIZE);
+   }
+
+   /**
+    * Copy input stream to output stream without closing streams.
+    * Flushes output stream when done.
+    *
+    * @param is input stream
+    * @param os output stream
+    * @param bufferSize the buffer size to use
+    * @throws IOException for any error
+    */
+   public static void copyStream(InputStream is, OutputStream os, int bufferSize)
+         throws IOException
+   {
+      if (is == null)
+         throw new IllegalArgumentException("input stream is null");
+      if (os == null)
+         throw new IllegalArgumentException("output stream is null");
+      byte [] buff = new byte[bufferSize];
+      int rc;
+      while ((rc = is.read(buff)) != -1) os.write(buff, 0, rc);
+      os.flush();
+   }
+
+   /**
+    * Write the given bytes to the given virtual file, replacing its current contents (if any) or creating a new
+    * file if one does not exist.
+    *
+    * @param virtualFile the virtual file to write
+    * @param bytes the bytes
+    * @throws IOException if an error occurs
+    */
+   public static void writeFile(VirtualFile virtualFile, byte[] bytes) throws IOException
+   {
+      final File file = virtualFile.getPhysicalFile();
+      file.getParentFile().mkdirs();
+      final FileOutputStream fos = new FileOutputStream(file);
+      try {
+         fos.write(bytes);
+         fos.close();
+      } finally {
+         safeClose(fos);
+      }
+   }
+
+   /**
+    * Get the virtual URL for a virtual file.  This URL can be used to access the virtual file; however, taking the
+    * file part of the URL and attempting to use it with the {@link java.io.File} class may fail if the file is not
+    * present on the physical filesystem, and in general should not be attempted.
+    *
+    * @param file the virtual file
+    * @return the URL
+    * @throws MalformedURLException if the file cannot be coerced into a URL for some reason
+    */
+   public static URL getVirtualURL(VirtualFile file) throws MalformedURLException
+   {
+      // todo: specify the URL handler directly as a minor optimization
+      return new URL("file", "", -1, file.getPathName(true));
+   }
+
+   /**
+    * Get the virtual URI for a virtual file.
+    *
+    * @param file the virtual file
+    * @return the URI
+    * @throws URISyntaxException if the file cannot be coerced into a URI for some reason
+    */
+   public static URI getVirtualURI(VirtualFile file) throws URISyntaxException
+   {
+      return new URI("file", "", file.getPathName(true), null);
+   }
+
+   /**
+    * Get a physical URL for a virtual file.  See the warnings on the {@link VirtualFile#getPhysicalFile()} method
+    * before using this method.
+    *
+    * @param file the virtual file
+    * @return the physical file URL
+    * @throws IOException if an I/O error occurs getting the physical file
+    */
+   public static URL getPhysicalURL(VirtualFile file) throws IOException
+   {
+      return getPhysicalURI(file).toURL();
+   }
+
+   /**
+    * Get a physical URI for a virtual file.  See the warnings on the {@link VirtualFile#getPhysicalFile()} method
+    * before using this method.
+    *
+    * @param file the virtual file
+    * @return the physical file URL
+    * @throws IOException if an I/O error occurs getting the physical file
+    */
+   public static URI getPhysicalURI(VirtualFile file) throws IOException
+   {
+      return file.getPhysicalFile().toURI();
+   }
+
+   /**
+    * Safely close some resource without throwing an exception.  Any exception will be logged at TRACE level.
+    *
+    * @param c the resource
+    */
+   public static void safeClose(final Closeable c)
+   {
+      if (c != null) try {
+         c.close();
+      }
+      catch (Exception e)
+      {
+         log.trace("Failed to close resource", e);
+      }
+   }
+
+   /**
+    * Safely close some resources without throwing an exception.  Any exception will be logged at TRACE level.
+    *
+    * @param ci the resources
+    */
+   public static void safeClose(final Iterable<? extends Closeable> ci)
+   {
+      if (ci != null) for (Closeable closeable : ci)
+      {
+         safeClose(closeable);
+      }
+   }
+
+   /**
+    * Safely close some resource without throwing an exception.  Any exception will be logged at TRACE level.
+    *
+    * @param zipFile the resource
+    */
+   public static void safeClose(final ZipFile zipFile)
+   {
+      if (zipFile != null) try {
+         zipFile.close();
+      }
+      catch (Exception e)
+      {
+         log.trace("Failed to close resource", e);
+      }
+   }
+
+   /**
+    * Attempt to recursively delete a real file.
+    *
+    * @param root the real file to delete
+    * @return {@code true} if the file was deleted
+    */
+   public static boolean recursiveDelete(File root)
+   {
+      boolean ok = true;
+      if (root.isDirectory()) {
+         final File[] files = root.listFiles();
+         for (File file : files)
+         {
+            ok &= recursiveDelete(file);
+         }
+         return ok && (root.delete() || ! root.exists());
+      } else {
+         ok &= root.delete() || ! root.exists();
+      }
+      return ok;
+   }
+
+   /**
+    * Attempt to recursively delete a virtual file.
+    *
+    * @param root the virtual file to delete
+    * @return {@code true} if the file was deleted
+    */
+   public static boolean recursiveDelete(VirtualFile root) throws IOException
+   {
+      boolean ok = true;
+      if (root.isDirectory()) {
+         final List<VirtualFile> files = root.getChildren();
+         for (VirtualFile file : files)
+         {
+            ok &= recursiveDelete(file);
+         }
+         return ok && (root.delete() || ! root.exists());
+      } else {
+         ok &= root.delete() || ! root.exists();
+      }
+      return ok;
+   }
+}

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFile.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VirtualFile.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFile.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,499 +0,0 @@
-/*
-  * JBoss, Home of Professional Open Source
-  * Copyright 2005, JBoss Inc., and individual contributors as indicated
-  * by the @authors tag. See the copyright.txt in the distribution for a
-  * full listing of individual contributors.
-  *
-  * This is free software; you can redistribute it and/or modify it
-  * under the terms of the GNU Lesser General Public License as
-  * published by the Free Software Foundation; either version 2.1 of
-  * the License, or (at your option) any later version.
-  *
-  * This software is distributed in the hope that it will be useful,
-  * but WITHOUT ANY WARRANTY; without even the implied warranty of
-  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  * Lesser General Public License for more details.
-  *
-  * You should have received a copy of the GNU Lesser General Public
-  * License along with this software; if not, write to the Free
-  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-  */
-package org.jboss.virtual;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.net.URI;
-import java.net.URL;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.Arrays;
-
-import org.jboss.virtual.plugins.vfs.helpers.FilterVirtualFileVisitor;
-import org.jboss.virtual.plugins.vfs.helpers.MatchAllVirtualFileFilter;
-import org.jboss.virtual.plugins.vfs.helpers.PathTokenizer;
-
-/**
- * A virtual file.  This is a symbolic reference to a location in the virtual file system hierarchy.  Holding a
- * {@code VirtualFile} instance gives no guarantees as to the presence or immutability of the referenced file or
- * any of its parent path elements.
- *
- * @author Scott.Stark at jboss.org
- * @author adrian at jboss.org
- * @author Ales.Justin at jboss.org
- * @version $Revision: 44334 $
- */
-public class VirtualFile implements Serializable
-{
-   private static final long serialVersionUID = 1L;
-   private final String name;
-   private final String lcname;
-   private final VirtualFile parent;
-   private final int hashCode;
-
-   VirtualFile(String name, VirtualFile parent)
-   {
-      this.name = name;
-      lcname = name.toLowerCase();
-      this.parent = parent;
-      int result = parent == null ? 1 : parent.hashCode();
-      result = 31 * result + name.hashCode();
-      hashCode = result;
-   }
-
-   /**
-    * Get the simple VF name (X.java)
-    *
-    * @return the simple file name
-    */
-   public String getName()
-   {
-      return name;
-   }
-
-   /**
-    * Get the simple VF name mapped to lowercase (x.java) (used by case-insensitive filesystems like ZIP).
-    *
-    * @return the lowercase simple file name
-    */
-   public String getLowerCaseName()
-   {
-      return lcname;
-   }
-
-   /**
-    * Get the absolute VFS full path name (/xxx/yyy/foo.ear/baz.jar/org/jboss/X.java)
-    *
-    * @return the VFS full path name
-    */
-   public String getPathName()
-   {
-      return getPathName(false);
-   }
-
-   /**
-    * Get the absolute VFS full path name. If this is a URL then directory entries will
-    * have a trailing slash.
-    *
-    * @param url whether or not this path is being used for a URL
-    * @return the VFS full path name
-    */
-   String getPathName(boolean url)
-   {
-      final StringBuilder builder = new StringBuilder(160);
-      final VirtualFile parent = this.parent;
-      if (parent == null) {
-         return "/";
-      } else {
-         builder.append(parent.getPathName());
-         if (parent.parent != null) {
-            builder.append('/');
-         }
-         builder.append(name);
-      }
-      // Perhaps this should be cached to avoid the fs stat call?
-      if (url && isDirectory())
-         builder.append("/");
-      return builder.toString();
-   }
-
-   /**
-    * When the file was last modified
-    *
-    * @return the last modified time
-    * @throws IOException for any problem accessing the virtual file system
-    */
-   public long getLastModified() throws IOException
-   {
-      final VFS.Mount mount = VFS.instance.getMount(this);
-      return mount.getFileSystem().getLastModified(mount.getMountPoint(), this);
-   }
-
-   /**
-    * Get the size
-    *
-    * @return the size
-    * @throws IOException for any problem accessing the virtual file system
-    */
-   public long getSize() throws IOException
-   {
-      final VFS.Mount mount = VFS.instance.getMount(this);
-      return mount.getFileSystem().getSize(mount.getMountPoint(), this);
-   }
-
-   /**
-    * Tests whether the underlying implementation file still exists.
-    * @return true if the file exists, false otherwise.
-    * @throws IOException - thrown on failure to detect existence.
-    */
-   public boolean exists() throws IOException
-   {
-      final VFS.Mount mount = VFS.instance.getMount(this);
-      return mount.getFileSystem().exists(mount.getMountPoint(), this);
-   }
-
-   /**
-    * Whether it is a simple leaf of the VFS,
-    * i.e. whether it can contain other files
-    *
-    * @return true if a simple file.
-    * @throws IOException for any problem accessing the virtual file system
-    * @deprecated use {@link #isDirectory()} instead
-    */
-   @Deprecated
-   public boolean isLeaf() throws IOException
-   {
-      return ! isDirectory();
-   }
-
-   /**
-    * Determine whether the named virtual file is a directory.
-    *
-    * @return {@code true} if it is a directory, {@code false} otherwise
-    * @throws IOException if an I/O error occurs
-    */
-   public boolean isDirectory()
-   {
-      final VFS.Mount mount = VFS.instance.getMount(this);
-      return mount.getFileSystem().isDirectory(mount.getMountPoint(), this);
-   }
-
-   /**
-    * Access the file contents.
-    *
-    * @return an InputStream for the file contents.
-    * @throws IOException for any error accessing the file system
-    */
-   public InputStream openStream() throws IOException
-   {
-      final VFS.Mount mount = VFS.instance.getMount(this);
-      return mount.getFileSystem().openInputStream(mount.getMountPoint(), this);
-   }
-
-   /**
-    * Delete this virtual file
-    *
-    * @return true if file was deleted
-    * @throws IOException if an error occurs
-    */
-   public boolean delete() throws IOException
-   {
-      final VFS.Mount mount = VFS.instance.getMount(this);
-      return mount.getFileSystem().delete(mount.getMountPoint(), this);
-   }
-
-   /**
-    * Get a physical file for this virtual file.  Depending on the underlying file system type, this may simply return
-    * an already-existing file; it may create a copy of a file; or it may reuse a preexisting copy of the file.  Furthermore,
-    * the retured file may or may not have any relationship to other files from the same or any other virtual
-    * directory.
-    *
-    * @return the physical file
-    * @throws IOException if an I/O error occurs while producing the physical file
-    */
-   public File getPhysicalFile() throws IOException
-   {
-      final VFS.Mount mount = VFS.instance.getMount(this);
-      return mount.getFileSystem().getFile(mount.getMountPoint(), this);
-   }
-
-   /**
-    * Get the VFS instance for this virtual file
-    *
-    * @return the VFS
-    */
-   public VFS getVFS()
-   {
-      return VFS.instance;
-   }
-
-   /**
-    * Get a {@code VirtualFile} which represents the parent of this instance.
-    *
-    * @return the parent or {@code null} if there is no parent
-    */
-   public VirtualFile getParent()
-   {
-      return parent;
-   }
-
-   /**
-    * Get the all the parent files of this virtual file from this file to the root.  The leafmost file will be at
-    * the start of the array, and the rootmost will be at the end.
-    *
-    * @return the array of parent files
-    */
-   public VirtualFile[] getParentFiles() {
-      return getParentFiles(0);
-   }
-
-   /**
-    * Get the all the parent files of this virtual file from this file to the root as a list.  The leafmost file will be at
-    * the start of the list, and the rootmost will be at the end.
-    *
-    * @return the list of parent files
-    */
-   public List<VirtualFile> getParentFileList() {
-      return Arrays.asList(getParentFiles());
-   }
-
-   private VirtualFile[] getParentFiles(int idx) {
-      final VirtualFile[] array;
-      if (parent == null) {
-         array = new VirtualFile[idx + 1];
-      } else {
-         array = parent.getParentFiles(idx + 1);
-      }
-      array[idx] = this;
-      return array;
-   }
-
-   /**
-    * Get the children.  This is the combined list of real children within this directory, as well as virtual
-    * children created by submounts.
-    *
-    * @return the children
-    * @throws IOException for any problem accessing the virtual file system
-    */
-   public List<VirtualFile> getChildren() throws IOException
-   {
-      if (! isDirectory())
-         return Collections.emptyList();
-
-      VFS vfs = VFS.instance;
-      final VFS.Mount mount = vfs.getMount(this);
-      final Set<String> submounts = vfs.getSubmounts(this);
-      final List<String> names = mount.getFileSystem().getDirectoryEntries(mount.getMountPoint(), this);
-      final List<VirtualFile> virtualFiles = new ArrayList<VirtualFile>(names.size() + submounts.size());
-      for (String name : names)
-      {
-         final VirtualFile child = new VirtualFile(name, this);
-         virtualFiles.add(child);
-         submounts.remove(name);
-      }
-      return virtualFiles;
-   }
-
-   /**
-    * Get the children
-    *
-    * @param filter to filter the children
-    * @return the children
-    * @throws IOException for any problem accessing the virtual file system
-    * @throws IllegalStateException if the file is closed or it is a leaf node
-    */
-   public List<VirtualFile> getChildren(VirtualFileFilter filter) throws IOException
-   {
-      if (! isDirectory())
-         return Collections.emptyList();
-
-      if (filter == null)
-         filter = MatchAllVirtualFileFilter.INSTANCE;
-      FilterVirtualFileVisitor visitor = new FilterVirtualFileVisitor(filter, null);
-      visit(visitor);
-      return visitor.getMatched();
-   }
-
-   /**
-    * Get all the children recursively<p>
-    *
-    * This always uses {@link VisitorAttributes#RECURSE}
-    *
-    * @return the children
-    * @throws IOException for any problem accessing the virtual file system
-    * @throws IllegalStateException if the file is closed
-    */
-   public List<VirtualFile> getChildrenRecursively() throws IOException
-   {
-      return getChildrenRecursively(null);
-   }
-
-   /**
-    * Get all the children recursively<p>
-    *
-    * This always uses {@link VisitorAttributes#RECURSE}
-    *
-    * @param filter to filter the children
-    * @return the children
-    * @throws IOException for any problem accessing the virtual file system
-    * @throws IllegalStateException if the file is closed or it is a leaf node
-    */
-   public List<VirtualFile> getChildrenRecursively(VirtualFileFilter filter) throws IOException
-   {
-      if (! isDirectory())
-         return Collections.emptyList();
-
-      if (filter == null)
-         filter = MatchAllVirtualFileFilter.INSTANCE;
-      FilterVirtualFileVisitor visitor = new FilterVirtualFileVisitor(filter, VisitorAttributes.RECURSE);
-      visit(visitor);
-      return visitor.getMatched();
-   }
-
-   /**
-    * Visit the virtual file system
-    *
-    * @param visitor the visitor
-    * @throws IOException for any problem accessing the virtual file system
-    * @throws IllegalArgumentException if the visitor is null
-    * @throws IllegalStateException if the file is closed
-    */
-   public void visit(VirtualFileVisitor visitor) throws IOException
-   {
-      visit(visitor, true);
-   }
-
-   private void visit(VirtualFileVisitor visitor, boolean root) throws IOException
-   {
-      final VisitorAttributes visitorAttributes = visitor.getAttributes();
-
-      if (root && visitorAttributes.isIncludeRoot())
-         visitor.visit(this);
-
-      if (! isDirectory())
-         return;
-
-      for (VirtualFile child : getChildren())
-      {
-         // Always visit a leaf, and visit directories when leaves only is false
-         if (!child.isDirectory() || !visitorAttributes.isLeavesOnly())
-            visitor.visit(child);
-
-         if (child.isDirectory() && visitorAttributes.isRecurse(child))
-            child.visit(visitor, false);
-      }
-   }
-
-   /**
-    * Get a child virtual file.
-    *
-    * @param path the path
-    * @return the child or {@code null} if not found
-    * @throws IllegalArgumentException if the path is null
-    */
-   public VirtualFile getChild(String path)
-   {
-      if (path == null)
-         throw new IllegalArgumentException("Null path");
-
-      VFS vfs = VFS.instance;
-
-      final List<String> pathParts = PathTokenizer.getTokens(path);
-      VirtualFile current = this;
-      for (String part : pathParts)
-      {
-         if (PathTokenizer.isReverseToken(part))
-         {
-            final VirtualFile parent = current.parent;
-            current = parent == null ? current : parent;
-         }
-         else if (PathTokenizer.isCurrentToken(part) == false)
-         {
-            current = new VirtualFile(part, current);
-         }
-      }
-      try
-      {
-         if (current.exists())
-            return current;
-      }
-      catch (IOException e)
-      {
-         // Fall-through
-      }
-
-      return null;
-   }
-
-   /**
-    * Get file's URL.
-    *
-    * @return the url
-    * @throws IOException for any io error
-    */
-   public URL toURL() throws IOException
-   {
-      return VFSUtils.getVirtualURL(this);
-   }
-
-   /**
-    * Get file's URI.
-    *
-    * @return the uri
-    * @throws URISyntaxException for any error
-    */
-   public URI toURI() throws URISyntaxException
-   {
-      return VFSUtils.getVirtualURI(this);
-   }
-
-   /**
-    * Get a human-readable (but non-canonical) representation of this virtual file.
-    *
-    * @return the string
-    */
-   public String toString()
-   {
-      return "Virtual file \"" + getPathName() + "\" for " + VFS.instance;
-   }
-
-   /**
-    * Determine whether the given object is equal to this one.  Returns true if the argument is a {@code VirtualFile}
-    * from the same {@code VFS} instance with the same name.
-    *
-    * @param o the other object
-    * @return {@code true} if they are equal
-    */
-   public boolean equals(Object o)
-   {
-      if (this == o)
-         return true;
-      if (! (o instanceof VirtualFile))
-         return false;
-      VirtualFile that = (VirtualFile) o;
-      if (hashCode != that.hashCode)
-         return false;
-      if (! name.equals(that.name))
-         return false;
-      final VirtualFile parent = this.parent;
-      if (parent == null)
-         return that.parent == null;
-      else
-         return parent.equals(that.parent);
-   }
-
-   /**
-    * Get a hashcode for this virtual file.
-    *
-    * @return the hash code
-    */
-   public int hashCode()
-   {
-      return hashCode;
-   }
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFile.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VirtualFile.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFile.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFile.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,499 @@
+/*
+  * JBoss, Home of Professional Open Source
+  * Copyright 2005, JBoss Inc., and individual contributors as indicated
+  * by the @authors tag. See the copyright.txt in the distribution for a
+  * full listing of individual contributors.
+  *
+  * This is free software; you can redistribute it and/or modify it
+  * under the terms of the GNU Lesser General Public License as
+  * published by the Free Software Foundation; either version 2.1 of
+  * the License, or (at your option) any later version.
+  *
+  * This software is distributed in the hope that it will be useful,
+  * but WITHOUT ANY WARRANTY; without even the implied warranty of
+  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  * Lesser General Public License for more details.
+  *
+  * You should have received a copy of the GNU Lesser General Public
+  * License along with this software; if not, write to the Free
+  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+  */
+package org.jboss.vfs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.net.URI;
+import java.net.URL;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+import java.util.Arrays;
+
+import org.jboss.vfs.util.FilterVirtualFileVisitor;
+import org.jboss.vfs.util.MatchAllVirtualFileFilter;
+import org.jboss.vfs.util.PathTokenizer;
+
+/**
+ * A virtual file.  This is a symbolic reference to a location in the virtual file system hierarchy.  Holding a
+ * {@code VirtualFile} instance gives no guarantees as to the presence or immutability of the referenced file or
+ * any of its parent path elements.
+ *
+ * @author Scott.Stark at jboss.org
+ * @author adrian at jboss.org
+ * @author Ales.Justin at jboss.org
+ * @version $Revision: 44334 $
+ */
+public class VirtualFile implements Serializable
+{
+   private static final long serialVersionUID = 1L;
+   private final String name;
+   private final String lcname;
+   private final VirtualFile parent;
+   private final int hashCode;
+
+   VirtualFile(String name, VirtualFile parent)
+   {
+      this.name = name;
+      lcname = name.toLowerCase();
+      this.parent = parent;
+      int result = parent == null ? 1 : parent.hashCode();
+      result = 31 * result + name.hashCode();
+      hashCode = result;
+   }
+
+   /**
+    * Get the simple VF name (X.java)
+    *
+    * @return the simple file name
+    */
+   public String getName()
+   {
+      return name;
+   }
+
+   /**
+    * Get the simple VF name mapped to lowercase (x.java) (used by case-insensitive filesystems like ZIP).
+    *
+    * @return the lowercase simple file name
+    */
+   public String getLowerCaseName()
+   {
+      return lcname;
+   }
+
+   /**
+    * Get the absolute VFS full path name (/xxx/yyy/foo.ear/baz.jar/org/jboss/X.java)
+    *
+    * @return the VFS full path name
+    */
+   public String getPathName()
+   {
+      return getPathName(false);
+   }
+
+   /**
+    * Get the absolute VFS full path name. If this is a URL then directory entries will
+    * have a trailing slash.
+    *
+    * @param url whether or not this path is being used for a URL
+    * @return the VFS full path name
+    */
+   String getPathName(boolean url)
+   {
+      final StringBuilder builder = new StringBuilder(160);
+      final VirtualFile parent = this.parent;
+      if (parent == null) {
+         return "/";
+      } else {
+         builder.append(parent.getPathName());
+         if (parent.parent != null) {
+            builder.append('/');
+         }
+         builder.append(name);
+      }
+      // Perhaps this should be cached to avoid the fs stat call?
+      if (url && isDirectory())
+         builder.append("/");
+      return builder.toString();
+   }
+
+   /**
+    * When the file was last modified
+    *
+    * @return the last modified time
+    * @throws IOException for any problem accessing the virtual file system
+    */
+   public long getLastModified() throws IOException
+   {
+      final VFS.Mount mount = VFS.instance.getMount(this);
+      return mount.getFileSystem().getLastModified(mount.getMountPoint(), this);
+   }
+
+   /**
+    * Get the size
+    *
+    * @return the size
+    * @throws IOException for any problem accessing the virtual file system
+    */
+   public long getSize() throws IOException
+   {
+      final VFS.Mount mount = VFS.instance.getMount(this);
+      return mount.getFileSystem().getSize(mount.getMountPoint(), this);
+   }
+
+   /**
+    * Tests whether the underlying implementation file still exists.
+    * @return true if the file exists, false otherwise.
+    * @throws IOException - thrown on failure to detect existence.
+    */
+   public boolean exists() throws IOException
+   {
+      final VFS.Mount mount = VFS.instance.getMount(this);
+      return mount.getFileSystem().exists(mount.getMountPoint(), this);
+   }
+
+   /**
+    * Whether it is a simple leaf of the VFS,
+    * i.e. whether it can contain other files
+    *
+    * @return true if a simple file.
+    * @throws IOException for any problem accessing the virtual file system
+    * @deprecated use {@link #isDirectory()} instead
+    */
+   @Deprecated
+   public boolean isLeaf() throws IOException
+   {
+      return ! isDirectory();
+   }
+
+   /**
+    * Determine whether the named virtual file is a directory.
+    *
+    * @return {@code true} if it is a directory, {@code false} otherwise
+    * @throws IOException if an I/O error occurs
+    */
+   public boolean isDirectory()
+   {
+      final VFS.Mount mount = VFS.instance.getMount(this);
+      return mount.getFileSystem().isDirectory(mount.getMountPoint(), this);
+   }
+
+   /**
+    * Access the file contents.
+    *
+    * @return an InputStream for the file contents.
+    * @throws IOException for any error accessing the file system
+    */
+   public InputStream openStream() throws IOException
+   {
+      final VFS.Mount mount = VFS.instance.getMount(this);
+      return mount.getFileSystem().openInputStream(mount.getMountPoint(), this);
+   }
+
+   /**
+    * Delete this virtual file
+    *
+    * @return true if file was deleted
+    * @throws IOException if an error occurs
+    */
+   public boolean delete() throws IOException
+   {
+      final VFS.Mount mount = VFS.instance.getMount(this);
+      return mount.getFileSystem().delete(mount.getMountPoint(), this);
+   }
+
+   /**
+    * Get a physical file for this virtual file.  Depending on the underlying file system type, this may simply return
+    * an already-existing file; it may create a copy of a file; or it may reuse a preexisting copy of the file.  Furthermore,
+    * the retured file may or may not have any relationship to other files from the same or any other virtual
+    * directory.
+    *
+    * @return the physical file
+    * @throws IOException if an I/O error occurs while producing the physical file
+    */
+   public File getPhysicalFile() throws IOException
+   {
+      final VFS.Mount mount = VFS.instance.getMount(this);
+      return mount.getFileSystem().getFile(mount.getMountPoint(), this);
+   }
+
+   /**
+    * Get the VFS instance for this virtual file
+    *
+    * @return the VFS
+    */
+   public VFS getVFS()
+   {
+      return VFS.instance;
+   }
+
+   /**
+    * Get a {@code VirtualFile} which represents the parent of this instance.
+    *
+    * @return the parent or {@code null} if there is no parent
+    */
+   public VirtualFile getParent()
+   {
+      return parent;
+   }
+
+   /**
+    * Get the all the parent files of this virtual file from this file to the root.  The leafmost file will be at
+    * the start of the array, and the rootmost will be at the end.
+    *
+    * @return the array of parent files
+    */
+   public VirtualFile[] getParentFiles() {
+      return getParentFiles(0);
+   }
+
+   /**
+    * Get the all the parent files of this virtual file from this file to the root as a list.  The leafmost file will be at
+    * the start of the list, and the rootmost will be at the end.
+    *
+    * @return the list of parent files
+    */
+   public List<VirtualFile> getParentFileList() {
+      return Arrays.asList(getParentFiles());
+   }
+
+   private VirtualFile[] getParentFiles(int idx) {
+      final VirtualFile[] array;
+      if (parent == null) {
+         array = new VirtualFile[idx + 1];
+      } else {
+         array = parent.getParentFiles(idx + 1);
+      }
+      array[idx] = this;
+      return array;
+   }
+
+   /**
+    * Get the children.  This is the combined list of real children within this directory, as well as virtual
+    * children created by submounts.
+    *
+    * @return the children
+    * @throws IOException for any problem accessing the virtual file system
+    */
+   public List<VirtualFile> getChildren() throws IOException
+   {
+      if (! isDirectory())
+         return Collections.emptyList();
+
+      VFS vfs = VFS.instance;
+      final VFS.Mount mount = vfs.getMount(this);
+      final Set<String> submounts = vfs.getSubmounts(this);
+      final List<String> names = mount.getFileSystem().getDirectoryEntries(mount.getMountPoint(), this);
+      final List<VirtualFile> virtualFiles = new ArrayList<VirtualFile>(names.size() + submounts.size());
+      for (String name : names)
+      {
+         final VirtualFile child = new VirtualFile(name, this);
+         virtualFiles.add(child);
+         submounts.remove(name);
+      }
+      return virtualFiles;
+   }
+
+   /**
+    * Get the children
+    *
+    * @param filter to filter the children
+    * @return the children
+    * @throws IOException for any problem accessing the virtual file system
+    * @throws IllegalStateException if the file is closed or it is a leaf node
+    */
+   public List<VirtualFile> getChildren(VirtualFileFilter filter) throws IOException
+   {
+      if (! isDirectory())
+         return Collections.emptyList();
+
+      if (filter == null)
+         filter = MatchAllVirtualFileFilter.INSTANCE;
+      FilterVirtualFileVisitor visitor = new FilterVirtualFileVisitor(filter, null);
+      visit(visitor);
+      return visitor.getMatched();
+   }
+
+   /**
+    * Get all the children recursively<p>
+    *
+    * This always uses {@link VisitorAttributes#RECURSE}
+    *
+    * @return the children
+    * @throws IOException for any problem accessing the virtual file system
+    * @throws IllegalStateException if the file is closed
+    */
+   public List<VirtualFile> getChildrenRecursively() throws IOException
+   {
+      return getChildrenRecursively(null);
+   }
+
+   /**
+    * Get all the children recursively<p>
+    *
+    * This always uses {@link VisitorAttributes#RECURSE}
+    *
+    * @param filter to filter the children
+    * @return the children
+    * @throws IOException for any problem accessing the virtual file system
+    * @throws IllegalStateException if the file is closed or it is a leaf node
+    */
+   public List<VirtualFile> getChildrenRecursively(VirtualFileFilter filter) throws IOException
+   {
+      if (! isDirectory())
+         return Collections.emptyList();
+
+      if (filter == null)
+         filter = MatchAllVirtualFileFilter.INSTANCE;
+      FilterVirtualFileVisitor visitor = new FilterVirtualFileVisitor(filter, VisitorAttributes.RECURSE);
+      visit(visitor);
+      return visitor.getMatched();
+   }
+
+   /**
+    * Visit the virtual file system
+    *
+    * @param visitor the visitor
+    * @throws IOException for any problem accessing the virtual file system
+    * @throws IllegalArgumentException if the visitor is null
+    * @throws IllegalStateException if the file is closed
+    */
+   public void visit(VirtualFileVisitor visitor) throws IOException
+   {
+      visit(visitor, true);
+   }
+
+   private void visit(VirtualFileVisitor visitor, boolean root) throws IOException
+   {
+      final VisitorAttributes visitorAttributes = visitor.getAttributes();
+
+      if (root && visitorAttributes.isIncludeRoot())
+         visitor.visit(this);
+
+      if (! isDirectory())
+         return;
+
+      for (VirtualFile child : getChildren())
+      {
+         // Always visit a leaf, and visit directories when leaves only is false
+         if (!child.isDirectory() || !visitorAttributes.isLeavesOnly())
+            visitor.visit(child);
+
+         if (child.isDirectory() && visitorAttributes.isRecurse(child))
+            child.visit(visitor, false);
+      }
+   }
+
+   /**
+    * Get a child virtual file.
+    *
+    * @param path the path
+    * @return the child or {@code null} if not found
+    * @throws IllegalArgumentException if the path is null
+    */
+   public VirtualFile getChild(String path)
+   {
+      if (path == null)
+         throw new IllegalArgumentException("Null path");
+
+      VFS vfs = VFS.instance;
+
+      final List<String> pathParts = PathTokenizer.getTokens(path);
+      VirtualFile current = this;
+      for (String part : pathParts)
+      {
+         if (PathTokenizer.isReverseToken(part))
+         {
+            final VirtualFile parent = current.parent;
+            current = parent == null ? current : parent;
+         }
+         else if (PathTokenizer.isCurrentToken(part) == false)
+         {
+            current = new VirtualFile(part, current);
+         }
+      }
+      try
+      {
+         if (current.exists())
+            return current;
+      }
+      catch (IOException e)
+      {
+         // Fall-through
+      }
+
+      return null;
+   }
+
+   /**
+    * Get file's URL.
+    *
+    * @return the url
+    * @throws IOException for any io error
+    */
+   public URL toURL() throws IOException
+   {
+      return VFSUtils.getVirtualURL(this);
+   }
+
+   /**
+    * Get file's URI.
+    *
+    * @return the uri
+    * @throws URISyntaxException for any error
+    */
+   public URI toURI() throws URISyntaxException
+   {
+      return VFSUtils.getVirtualURI(this);
+   }
+
+   /**
+    * Get a human-readable (but non-canonical) representation of this virtual file.
+    *
+    * @return the string
+    */
+   public String toString()
+   {
+      return "Virtual file \"" + getPathName() + "\" for " + VFS.instance;
+   }
+
+   /**
+    * Determine whether the given object is equal to this one.  Returns true if the argument is a {@code VirtualFile}
+    * from the same {@code VFS} instance with the same name.
+    *
+    * @param o the other object
+    * @return {@code true} if they are equal
+    */
+   public boolean equals(Object o)
+   {
+      if (this == o)
+         return true;
+      if (! (o instanceof VirtualFile))
+         return false;
+      VirtualFile that = (VirtualFile) o;
+      if (hashCode != that.hashCode)
+         return false;
+      if (! name.equals(that.name))
+         return false;
+      final VirtualFile parent = this.parent;
+      if (parent == null)
+         return that.parent == null;
+      else
+         return parent.equals(that.parent);
+   }
+
+   /**
+    * Get a hashcode for this virtual file.
+    *
+    * @return the hash code
+    */
+   public int hashCode()
+   {
+      return hashCode;
+   }
+}

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilter.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VirtualFileFilter.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilter.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,40 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.virtual;
-
-/**
- * A filter for virtual files
- *
- * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
- * @author adrian at jboss.org
- * @version $Revision: 44334 $
- */
-public interface VirtualFileFilter
-{
-   /**
-    * Match the virtual file
-    * 
-    * @param file the virtual file
-    * @return true when it matches
-    */
-   boolean accepts(VirtualFile file);
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilter.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VirtualFileFilter.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilter.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilter.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,40 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.vfs;
+
+/**
+ * A filter for virtual files
+ *
+ * @author <a href="mailto:bill at jboss.org">Bill Burke</a>
+ * @author adrian at jboss.org
+ * @version $Revision: 44334 $
+ */
+public interface VirtualFileFilter
+{
+   /**
+    * Match the virtual file
+    * 
+    * @param file the virtual file
+    * @return true when it matches
+    */
+   boolean accepts(VirtualFile file);
+}

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilterWithAttributes.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VirtualFileFilterWithAttributes.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilterWithAttributes.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,38 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.virtual;
-
-/**
- * A filter for virtual files with attributes
- *
- * @author adrian at jboss.org
- * @version $Revision: 44334 $
- */
-public interface VirtualFileFilterWithAttributes extends VirtualFileFilter
-{
-   /**
-    * Get the attributes for this filter
-    * 
-    * @return the attributes
-    */
-   VisitorAttributes getAttributes();
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilterWithAttributes.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VirtualFileFilterWithAttributes.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilterWithAttributes.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileFilterWithAttributes.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,38 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.vfs;
+
+/**
+ * A filter for virtual files with attributes
+ *
+ * @author adrian at jboss.org
+ * @version $Revision: 44334 $
+ */
+public interface VirtualFileFilterWithAttributes extends VirtualFileFilter
+{
+   /**
+    * Get the attributes for this filter
+    * 
+    * @return the attributes
+    */
+   VisitorAttributes getAttributes();
+}

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileVisitor.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VirtualFileVisitor.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileVisitor.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,45 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.virtual;
-
-/**
- * Visits a virtual file and its children
- * 
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision: 1.1 $
- */
-public interface VirtualFileVisitor
-{
-   /**
-    * Get the search attribues for this visitor
-    * 
-    * @return the attributes
-    */
-   VisitorAttributes getAttributes();
-   
-   /**
-    * Visit a virtual file
-    * 
-    * @param virtualFile the virtual file being visited
-    */
-   void visit(VirtualFile virtualFile);
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileVisitor.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VirtualFileVisitor.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileVisitor.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VirtualFileVisitor.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,45 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.vfs;
+
+/**
+ * Visits a virtual file and its children
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface VirtualFileVisitor
+{
+   /**
+    * Get the search attribues for this visitor
+    * 
+    * @return the attributes
+    */
+   VisitorAttributes getAttributes();
+   
+   /**
+    * Visit a virtual file
+    * 
+    * @param virtualFile the virtual file being visited
+    */
+   void visit(VirtualFile virtualFile);
+}

Deleted: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VisitorAttributes.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VisitorAttributes.java	2009-08-04 22:20:47 UTC (rev 91986)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VisitorAttributes.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -1,253 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.virtual;
-
-/**
- * Attributes used when visiting a virtual file system
- * 
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author Scott.Stark at jboss.org
- * @version $Revision: 1.1 $
- */
-public class VisitorAttributes
-{
-   /** A VirtualFileFilter than accepts any file */
-   public static final AcceptAnyFilter RECURSE_ALL = new AcceptAnyFilter();
-
-   /** The default attributes - visit leaves and non-leaves, no recursion, no root */
-   public static final VisitorAttributes DEFAULT = new ImmutableVisitorAttributes();
-
-   /** Visit leaves only and do not recurse non-leaf files */
-   public static final VisitorAttributes LEAVES_ONLY = new ImmutableVisitorAttributes(true, null);
-
-   /** Recurse and visit all non-leaf files */
-   public static final VisitorAttributes RECURSE = new ImmutableVisitorAttributes(false, RECURSE_ALL);
-
-   /** Recurse all non-leaf files but only visit leaves */
-   public static final VisitorAttributes RECURSE_LEAVES_ONLY = new ImmutableVisitorAttributes(true, RECURSE_ALL);
-   
-   /** Whether to include the root */
-   private boolean includeRoot;
-
-   /** Whether to only visit leaves */
-   private boolean leavesOnly;
-
-   /** Whether to ignore individual file errors */
-   private boolean ignoreErrors;
-
-   /** Whether to include hidden files */
-   private boolean includeHidden;
-
-   /** A filter used to control whether a non-leaf is recursive visited */
-   private VirtualFileFilter recurseFilter;
-
-   /**
-    * Whether to visit leaves only<p>
-    * 
-    * Default: false
-    * 
-    * @return the visit leaves only.
-    */
-   public boolean isLeavesOnly()
-   {
-      return leavesOnly;
-   }
-
-   /**
-    * Set the leaves only.
-    * 
-    * @param leavesOnly the leaves only
-    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
-    */
-   public void setLeavesOnly(boolean leavesOnly)
-   {
-      this.leavesOnly = leavesOnly;
-   }
-
-   /**
-    * Whether to recurse into the non-leaf file<p>. If there is a recurse
-    * filter then the result will by its accepts(file) value.
-    * 
-    * Default: false
-    * 
-    * @param file the file
-    * @return the recurse flag.
-    */
-   public boolean isRecurse(VirtualFile file)
-   {
-      boolean recurse = false;
-      if( recurseFilter != null )
-         recurse = recurseFilter.accepts(file);
-      return recurse;
-   }
-
-   /**
-    * Get the recurse filter.
-    * @return the current recurse filter.
-    */
-   public VirtualFileFilter getRecurseFilter()
-   {
-      return recurseFilter;
-   }
-
-   /**
-    * Set the recurse filter.
-    * 
-    * @param filter - the recurse filter.
-    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
-    */
-   public void setRecurseFilter(VirtualFileFilter filter)
-   {
-      this.recurseFilter = filter;
-   }
-
-   /**
-    * Whether to include the root of the visit<p>
-    * 
-    * Default: false
-    * 
-    * @return the includeRoot.
-    */
-   public boolean isIncludeRoot()
-   {
-      return includeRoot;
-   }
-
-   /**
-    * Set the includeRoot.
-    * 
-    * @param includeRoot the includeRoot.
-    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
-    */
-   public void setIncludeRoot(boolean includeRoot)
-   {
-      this.includeRoot = includeRoot;
-   }
-
-   /**
-    * Whether to ignore individual errors<p>
-    * 
-    * Default: false
-    * 
-    * @return the ignoreErrors.
-    */
-   public boolean isIgnoreErrors()
-   {
-      return ignoreErrors;
-   }
-
-   /**
-    * Set the ignoreErrors.
-    * 
-    * @param ignoreErrors the ignoreErrors.
-    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
-    */
-   public void setIgnoreErrors(boolean ignoreErrors)
-   {
-      this.ignoreErrors = ignoreErrors;
-   }
-
-   /**
-    * Whether to include hidden files<p>
-    * 
-    * Default: false
-    * 
-    * @return the includeHidden.
-    */
-   public boolean isIncludeHidden()
-   {
-      return includeHidden;
-   }
-
-   /**
-    * Set the includeHidden.
-    * 
-    * @param includeHidden the includeHidden.
-    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
-    */
-   public void setIncludeHidden(boolean includeHidden)
-   {
-      this.includeHidden = includeHidden;
-   }
-
-   private static class AcceptAnyFilter implements VirtualFileFilter
-   {
-      public boolean accepts(VirtualFile file)
-      {
-         return true;
-      }      
-   }
-   /**
-    * Immutable version of the attribues
-    */
-   private static class ImmutableVisitorAttributes extends VisitorAttributes
-   {
-      /**
-       * Create a new ImmutableVirtualFileVisitorAttributes with default values
-       */
-      public ImmutableVisitorAttributes()
-      {
-      }
-      
-      /**
-       * Create a new ImmutableVirtualFileVisitorAttributes.
-       * 
-       * @param leavesOnly whether to visit leaves only 
-       * @param recurseFilter - filter which controls whether to recurse
-       */
-      public ImmutableVisitorAttributes(boolean leavesOnly, VirtualFileFilter recurseFilter)
-      {
-         super.setLeavesOnly(leavesOnly);
-         super.setRecurseFilter(recurseFilter);
-      }
-      
-      @Override
-      public void setLeavesOnly(boolean leavesOnly)
-      {
-         throw new IllegalStateException("The preconfigured attributes are immutable");
-      }
-
-      @Override
-      public void setIncludeRoot(boolean includeRoot)
-      {
-         throw new IllegalStateException("The preconfigured attributes are immutable");
-      }
-
-      @Override
-      public void setRecurseFilter(VirtualFileFilter filter)
-      {
-         throw new IllegalStateException("The preconfigured attributes are immutable");
-      }
-
-      @Override
-      public void setIgnoreErrors(boolean ignoreErrors)
-      {
-         throw new IllegalStateException("The preconfigured attributes are immutable");
-      }
-
-      @Override
-      public void setIncludeHidden(boolean includeHidden)
-      {
-         throw new IllegalStateException("The preconfigured attributes are immutable");
-      }
-   }
-}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VisitorAttributes.java (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/VisitorAttributes.java)
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VisitorAttributes.java	                        (rev 0)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/VisitorAttributes.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -0,0 +1,253 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.vfs;
+
+/**
+ * Attributes used when visiting a virtual file system
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author Scott.Stark at jboss.org
+ * @version $Revision: 1.1 $
+ */
+public class VisitorAttributes
+{
+   /** A VirtualFileFilter than accepts any file */
+   public static final AcceptAnyFilter RECURSE_ALL = new AcceptAnyFilter();
+
+   /** The default attributes - visit leaves and non-leaves, no recursion, no root */
+   public static final VisitorAttributes DEFAULT = new ImmutableVisitorAttributes();
+
+   /** Visit leaves only and do not recurse non-leaf files */
+   public static final VisitorAttributes LEAVES_ONLY = new ImmutableVisitorAttributes(true, null);
+
+   /** Recurse and visit all non-leaf files */
+   public static final VisitorAttributes RECURSE = new ImmutableVisitorAttributes(false, RECURSE_ALL);
+
+   /** Recurse all non-leaf files but only visit leaves */
+   public static final VisitorAttributes RECURSE_LEAVES_ONLY = new ImmutableVisitorAttributes(true, RECURSE_ALL);
+   
+   /** Whether to include the root */
+   private boolean includeRoot;
+
+   /** Whether to only visit leaves */
+   private boolean leavesOnly;
+
+   /** Whether to ignore individual file errors */
+   private boolean ignoreErrors;
+
+   /** Whether to include hidden files */
+   private boolean includeHidden;
+
+   /** A filter used to control whether a non-leaf is recursive visited */
+   private VirtualFileFilter recurseFilter;
+
+   /**
+    * Whether to visit leaves only<p>
+    * 
+    * Default: false
+    * 
+    * @return the visit leaves only.
+    */
+   public boolean isLeavesOnly()
+   {
+      return leavesOnly;
+   }
+
+   /**
+    * Set the leaves only.
+    * 
+    * @param leavesOnly the leaves only
+    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
+    */
+   public void setLeavesOnly(boolean leavesOnly)
+   {
+      this.leavesOnly = leavesOnly;
+   }
+
+   /**
+    * Whether to recurse into the non-leaf file<p>. If there is a recurse
+    * filter then the result will by its accepts(file) value.
+    * 
+    * Default: false
+    * 
+    * @param file the file
+    * @return the recurse flag.
+    */
+   public boolean isRecurse(VirtualFile file)
+   {
+      boolean recurse = false;
+      if( recurseFilter != null )
+         recurse = recurseFilter.accepts(file);
+      return recurse;
+   }
+
+   /**
+    * Get the recurse filter.
+    * @return the current recurse filter.
+    */
+   public VirtualFileFilter getRecurseFilter()
+   {
+      return recurseFilter;
+   }
+
+   /**
+    * Set the recurse filter.
+    * 
+    * @param filter - the recurse filter.
+    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
+    */
+   public void setRecurseFilter(VirtualFileFilter filter)
+   {
+      this.recurseFilter = filter;
+   }
+
+   /**
+    * Whether to include the root of the visit<p>
+    * 
+    * Default: false
+    * 
+    * @return the includeRoot.
+    */
+   public boolean isIncludeRoot()
+   {
+      return includeRoot;
+   }
+
+   /**
+    * Set the includeRoot.
+    * 
+    * @param includeRoot the includeRoot.
+    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
+    */
+   public void setIncludeRoot(boolean includeRoot)
+   {
+      this.includeRoot = includeRoot;
+   }
+
+   /**
+    * Whether to ignore individual errors<p>
+    * 
+    * Default: false
+    * 
+    * @return the ignoreErrors.
+    */
+   public boolean isIgnoreErrors()
+   {
+      return ignoreErrors;
+   }
+
+   /**
+    * Set the ignoreErrors.
+    * 
+    * @param ignoreErrors the ignoreErrors.
+    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
+    */
+   public void setIgnoreErrors(boolean ignoreErrors)
+   {
+      this.ignoreErrors = ignoreErrors;
+   }
+
+   /**
+    * Whether to include hidden files<p>
+    * 
+    * Default: false
+    * 
+    * @return the includeHidden.
+    */
+   public boolean isIncludeHidden()
+   {
+      return includeHidden;
+   }
+
+   /**
+    * Set the includeHidden.
+    * 
+    * @param includeHidden the includeHidden.
+    * @throws IllegalStateException if you attempt to modify one of the preconfigured static values of this class
+    */
+   public void setIncludeHidden(boolean includeHidden)
+   {
+      this.includeHidden = includeHidden;
+   }
+
+   private static class AcceptAnyFilter implements VirtualFileFilter
+   {
+      public boolean accepts(VirtualFile file)
+      {
+         return true;
+      }      
+   }
+   /**
+    * Immutable version of the attribues
+    */
+   private static class ImmutableVisitorAttributes extends VisitorAttributes
+   {
+      /**
+       * Create a new ImmutableVirtualFileVisitorAttributes with default values
+       */
+      public ImmutableVisitorAttributes()
+      {
+      }
+      
+      /**
+       * Create a new ImmutableVirtualFileVisitorAttributes.
+       * 
+       * @param leavesOnly whether to visit leaves only 
+       * @param recurseFilter - filter which controls whether to recurse
+       */
+      public ImmutableVisitorAttributes(boolean leavesOnly, VirtualFileFilter recurseFilter)
+      {
+         super.setLeavesOnly(leavesOnly);
+         super.setRecurseFilter(recurseFilter);
+      }
+      
+      @Override
+      public void setLeavesOnly(boolean leavesOnly)
+      {
+         throw new IllegalStateException("The preconfigured attributes are immutable");
+      }
+
+      @Override
+      public void setIncludeRoot(boolean includeRoot)
+      {
+         throw new IllegalStateException("The preconfigured attributes are immutable");
+      }
+
+      @Override
+      public void setRecurseFilter(VirtualFileFilter filter)
+      {
+         throw new IllegalStateException("The preconfigured attributes are immutable");
+      }
+
+      @Override
+      public void setIgnoreErrors(boolean ignoreErrors)
+      {
+         throw new IllegalStateException("The preconfigured attributes are immutable");
+      }
+
+      @Override
+      public void setIncludeHidden(boolean includeHidden)
+      {
+         throw new IllegalStateException("The preconfigured attributes are immutable");
+      }
+   }
+}

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/protocol)

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/VirtualFileURLConnection.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/protocol/VirtualFileURLConnection.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/VirtualFileURLConnection.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -19,7 +19,7 @@
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
-package org.jboss.virtual.protocol;
+package org.jboss.vfs.protocol;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -30,8 +30,8 @@
 import java.net.URLDecoder;
 import java.security.Permission;
 
-import org.jboss.virtual.VFS;
-import org.jboss.virtual.VirtualFile;
+import org.jboss.vfs.VFS;
+import org.jboss.vfs.VirtualFile;
 import sun.net.www.ParseUtil;
 
 /**

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/VirtualFileURLStreamHandler.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/protocol/VirtualFileURLStreamHandler.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/VirtualFileURLStreamHandler.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -20,7 +20,7 @@
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
-package org.jboss.virtual.protocol;
+package org.jboss.vfs.protocol;
 
 import java.net.URLStreamHandler;
 import java.net.URLConnection;

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/file/Handler.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/protocol/file/Handler.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/protocol/file/Handler.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -20,9 +20,9 @@
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
-package org.jboss.virtual.protocol.file;
+package org.jboss.vfs.protocol.file;
 
-import org.jboss.virtual.protocol.VirtualFileURLStreamHandler;
+import org.jboss.vfs.protocol.VirtualFileURLStreamHandler;
 
 /**
  * Stub handler class.

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi)

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/EnumerationIterable.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/EnumerationIterable.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/EnumerationIterable.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -20,7 +20,7 @@
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
-package org.jboss.virtual.spi;
+package org.jboss.vfs.spi;
 
 import java.util.Enumeration;
 import java.util.Iterator;

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/EnumerationIterator.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/EnumerationIterator.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/EnumerationIterator.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -20,7 +20,7 @@
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
-package org.jboss.virtual.spi;
+package org.jboss.vfs.spi;
 
 import java.util.Iterator;
 import java.util.Enumeration;

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/FileSystem.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/FileSystem.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/FileSystem.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -20,9 +20,9 @@
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
-package org.jboss.virtual.spi;
+package org.jboss.vfs.spi;
 
-import org.jboss.virtual.VirtualFile;
+import org.jboss.vfs.VirtualFile;
 
 import java.io.File;
 import java.io.IOException;

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/JZipFileSystem.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/JZipFileSystem.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/JZipFileSystem.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -20,16 +20,16 @@
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
-package org.jboss.virtual.spi;
+package org.jboss.vfs.spi;
 
 import org.jboss.jzipfile.ZipEntry;
 import org.jboss.jzipfile.Zip;
 import org.jboss.jzipfile.ZipCatalog;
 import org.jboss.jzipfile.ZipEntryType;
-import org.jboss.virtual.util.PathTokenizer;
-import org.jboss.virtual.VFSUtils;
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.TempDir;
+import org.jboss.vfs.util.PathTokenizer;
+import org.jboss.vfs.VFSUtils;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.TempDir;
 
 import java.io.File;
 import java.io.IOException;

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/JavaZipFileSystem.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/JavaZipFileSystem.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/JavaZipFileSystem.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -20,12 +20,12 @@
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
-package org.jboss.virtual.spi;
+package org.jboss.vfs.spi;
 
-import org.jboss.virtual.util.PathTokenizer;
-import org.jboss.virtual.VFSUtils;
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.TempDir;
+import org.jboss.vfs.util.PathTokenizer;
+import org.jboss.vfs.VFSUtils;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.TempDir;
 
 import java.io.File;
 import java.io.IOException;

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/RealFileSystem.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/spi/RealFileSystem.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/spi/RealFileSystem.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -20,9 +20,9 @@
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
-package org.jboss.virtual.spi;
+package org.jboss.vfs.spi;
 
-import org.jboss.virtual.VirtualFile;
+import org.jboss.vfs.VirtualFile;
 
 import java.io.File;
 import java.io.IOException;

Copied: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util (from rev 91987, projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/util)

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/AbstractVirtualFileFilterWithAttributes.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/util/AbstractVirtualFileFilterWithAttributes.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/AbstractVirtualFileFilterWithAttributes.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -19,10 +19,10 @@
   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   */
-package org.jboss.virtual.util;
+package org.jboss.vfs.util;
 
-import org.jboss.virtual.VirtualFileFilterWithAttributes;
-import org.jboss.virtual.VisitorAttributes;
+import org.jboss.vfs.VirtualFileFilterWithAttributes;
+import org.jboss.vfs.VisitorAttributes;
 
 /**
  * AbstractVirtualFileFilterWithAttributes

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/AbstractVirtualFileVisitor.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/util/AbstractVirtualFileVisitor.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/AbstractVirtualFileVisitor.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -19,10 +19,10 @@
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
-package org.jboss.virtual.util;
+package org.jboss.vfs.util;
 
-import org.jboss.virtual.VirtualFileVisitor;
-import org.jboss.virtual.VisitorAttributes;
+import org.jboss.vfs.VirtualFileVisitor;
+import org.jboss.vfs.VisitorAttributes;
 
 /**
  * AbstractVirtualFileVisitor.

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/ExtensibleFilter.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/util/ExtensibleFilter.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/ExtensibleFilter.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -19,7 +19,7 @@
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
-package org.jboss.virtual.util;
+package org.jboss.vfs.util;
 
 import java.util.Arrays;
 import java.util.Comparator;
@@ -27,8 +27,8 @@
 import java.util.Collections;
 import java.util.List;
 
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VirtualFileFilter;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.VirtualFileFilter;
 
 /**
  * An extensible filter for VFS files.  Three arrays are

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/FilterVirtualFileVisitor.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/util/FilterVirtualFileVisitor.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/FilterVirtualFileVisitor.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -19,16 +19,16 @@
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
-package org.jboss.virtual.util;
+package org.jboss.vfs.util;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VirtualFileFilter;
-import org.jboss.virtual.VirtualFileFilterWithAttributes;
-import org.jboss.virtual.VisitorAttributes;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.VirtualFileFilter;
+import org.jboss.vfs.VirtualFileFilterWithAttributes;
+import org.jboss.vfs.VisitorAttributes;
 
 /**
  * A visitor based on a virtual file filter

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/MatchAllVirtualFileFilter.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/util/MatchAllVirtualFileFilter.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/MatchAllVirtualFileFilter.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -19,10 +19,10 @@
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
-package org.jboss.virtual.util;
+package org.jboss.vfs.util;
 
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VirtualFileFilter;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.VirtualFileFilter;
 
 /**
  * MatchAllVirtualFileFilter.

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/PathTokenizer.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/util/PathTokenizer.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/PathTokenizer.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -19,9 +19,8 @@
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
-package org.jboss.virtual.util;
+package org.jboss.vfs.util;
 
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/SuffixMatchFilter.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/util/SuffixMatchFilter.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/SuffixMatchFilter.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -19,15 +19,15 @@
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
-package org.jboss.virtual.util;
+package org.jboss.vfs.util;
 
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashSet;
 
 import org.jboss.logging.Logger;
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VisitorAttributes;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.VisitorAttributes;
 
 /**
  * Matches a file name against a list of suffixes. 

Modified: projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/SuffixesExcludeFilter.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/virtual/util/SuffixesExcludeFilter.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/main/java/org/jboss/vfs/util/SuffixesExcludeFilter.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -19,12 +19,12 @@
   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
   */
-package org.jboss.virtual.util;
+package org.jboss.vfs.util;
 
 import java.util.Collection;
 
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VirtualFileFilter;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.VirtualFileFilter;
 
 /**
  * Filters out a set of suffixes

Modified: projects/vfs/branches/dml-zip-rework/src/test/java/org/jboss/test/vfs/FileVFSUnitTestCase.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/test/java/org/jboss/test/vfs/FileVFSUnitTestCase.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/test/java/org/jboss/test/vfs/FileVFSUnitTestCase.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -47,12 +47,12 @@
 
 import org.jboss.test.vfs.support.ClassPathIterator;
 import org.jboss.test.vfs.support.ClassPathIterator.ClassPathEntry;
-import org.jboss.virtual.TempFileProvider;
-import org.jboss.virtual.VFS;
-import org.jboss.virtual.VFSUtils;
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VisitorAttributes;
-import org.jboss.virtual.util.SuffixMatchFilter;
+import org.jboss.vfs.TempFileProvider;
+import org.jboss.vfs.VFS;
+import org.jboss.vfs.VFSUtils;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.VisitorAttributes;
+import org.jboss.vfs.util.SuffixMatchFilter;
 
 /**
  * Tests of the VFS implementation

Modified: projects/vfs/branches/dml-zip-rework/src/test/java/org/jboss/test/vfs/support/ClassPathIterator.java
===================================================================
--- projects/vfs/branches/dml-zip-rework/src/test/java/org/jboss/test/vfs/support/ClassPathIterator.java	2009-08-04 22:24:08 UTC (rev 91987)
+++ projects/vfs/branches/dml-zip-rework/src/test/java/org/jboss/test/vfs/support/ClassPathIterator.java	2009-08-04 22:31:25 UTC (rev 91988)
@@ -34,8 +34,8 @@
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipInputStream;
 
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VirtualFileFilter;
+import org.jboss.vfs.VirtualFile;
+import org.jboss.vfs.VirtualFileFilter;
 
 /**
  * ClassPathIterator logic used by UCL package mapping




More information about the jboss-cvs-commits mailing list