[jboss-cvs] JBossAS SVN: r80463 - in projects/vfs/tags: 2.0.0.CR2 and 5 other directories.

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Nov 4 05:24:27 EST 2008


Author: alesj
Date: 2008-11-04 05:24:27 -0500 (Tue, 04 Nov 2008)
New Revision: 80463

Added:
   projects/vfs/tags/2.0.0.CR2/
   projects/vfs/tags/2.0.0.CR2/pom.xml
   projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFS.java
   projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFSUtils.java
   projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/plugins/cache/
   projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileURLConnection.java
   projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/spi/cache/
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/AbstractVFSTest.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/CachePolicyVFSCacheTest.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/LRUCacheTestCase.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/MapVFSCacheTest.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/SoftRefCacheTestCase.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/TimedCacheTestCase.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSCacheTest.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/WeakRefCacheTestCase.java
Removed:
   projects/vfs/tags/2.0.0.CR2/pom.xml
   projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFS.java
   projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFSUtils.java
   projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileURLConnection.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/AbstractVFSTest.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
   projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java
Log:
[maven-release-plugin]  copy for tag 2.0.0.CR2

Copied: projects/vfs/tags/2.0.0.CR2 (from rev 79734, projects/vfs/branches/Branch_2_0)

Deleted: projects/vfs/tags/2.0.0.CR2/pom.xml
===================================================================
--- projects/vfs/branches/Branch_2_0/pom.xml	2008-10-20 08:32:12 UTC (rev 79734)
+++ projects/vfs/tags/2.0.0.CR2/pom.xml	2008-11-04 10:24:27 UTC (rev 80463)
@@ -1,122 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-  <parent>
-    <groupId>org.jboss</groupId>
-    <artifactId>jboss-parent</artifactId>
-    <version>4</version>
-  </parent>
-  <modelVersion>4.0.0</modelVersion>
-  <groupId>org.jboss</groupId>
-  <artifactId>jboss-vfs</artifactId>
-  <packaging>jar</packaging>
-  <version>2.0.0-SNAPSHOT</version>
-  <name>JBoss VFS</name>
-  <url>http://www.jboss.org</url>
-  <description>A VFS library</description>
- <scm>
-    <connection>scm:svn:http://anonsvn.jboss.org/repos/jbossas/projects/vfs/trunk</connection>    
-    <developerConnection>scm:svn:https://svn.jboss.org/repos/jbossas/projects/vfs/trunk</developerConnection>
-    <url>https://svn.jboss.org/repos/jbossas/projects/vfs/trunk</url>
-  </scm>
-  <licenses>
-    <license>
-      <name>lgpl</name>
-      <url>http://repository.jboss.org/licenses/lgpl.txt</url>
-    </license>
-  </licenses>
-  <organization>
-    <name>JBoss, A division of Red Hat, Inc</name>
-    <url>http://www.jboss.org</url>
-  </organization>
-
-  <properties>
-    <version.jboss.common.core>2.2.8.GA</version.jboss.common.core>
-    <version.jboss.logging>2.0.5.GA</version.jboss.logging>
-    <version.jboss.test>1.1.0.GA</version.jboss.test>
-    <version.junit>4.4</version.junit>
-  </properties>
-
-  <build>
-    <sourceDirectory>src/main/java</sourceDirectory>
-    <testSourceDirectory>src/test/java</testSourceDirectory>
-    <finalName>${artifactId}</finalName>
-    <testResources>
-      <testResource>
-        <directory>src/test/resources</directory>
-      </testResource>
-    </testResources>
-    <plugins>
-      
-      <!-- define how we want compilation to take place
-        here, we accept most of the defaults but say that we want the
-        optimization flag set, and define the source and target to be 1.5,
-        these setting will be inherited by child projects -->
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-compiler-plugin</artifactId>
-        <version>2.0</version>
-        <configuration>
-          <debug>true</debug>
-          <source>1.5</source>
-          <target>1.5</target>
-        </configuration>
-      </plugin>
-      <!-- define that we wish to create src jars -->
-      <plugin>
-        <artifactId>maven-source-plugin</artifactId>
-        <inherited>true</inherited>
-        <executions>
-          <execution>
-            <goals>
-              <goal>jar</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.3.1</version>
-        <configuration>
-          <forkMode>always</forkMode> <!-- required to correctly run the PojoServer tests -->
-          <useSystemClassLoader>true</useSystemClassLoader>
-          <redirectTestOutputToFile>true</redirectTestOutputToFile>
-          <testFailureIgnore>true</testFailureIgnore>
-        </configuration>
-      </plugin>
-      <plugin>
-         <groupId>org.apache.maven.plugins</groupId>
-         <artifactId>maven-release-plugin</artifactId>
-         <version>2.0-beta-7</version>
-         <configuration>
-           <tagBase>https://svn.jboss.org/repos/jbossas/projects/vfs/tags</tagBase>
-         </configuration>
-       </plugin>
-    </plugins>
-  </build>
-
-  <dependencies>
-    <dependency>
-      <groupId>org.jboss</groupId>
-      <artifactId>jboss-common-core</artifactId>
-      <version>${version.jboss.common.core}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.logging</groupId>
-      <artifactId>jboss-logging-spi</artifactId>
-      <version>${version.jboss.logging}</version>
-    </dependency>
-    <dependency>
-      <groupId>org.jboss.test</groupId>
-      <artifactId>jboss-test</artifactId>
-      <version>${version.jboss.test}</version>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <version>${version.junit}</version>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-</project>

Copied: projects/vfs/tags/2.0.0.CR2/pom.xml (from rev 80462, projects/vfs/branches/Branch_2_0/pom.xml)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/pom.xml	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/pom.xml	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,122 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.jboss</groupId>
+    <artifactId>jboss-parent</artifactId>
+    <version>4</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>org.jboss</groupId>
+  <artifactId>jboss-vfs</artifactId>
+  <packaging>jar</packaging>
+  <version>2.0.0.CR2</version>
+  <name>JBoss VFS</name>
+  <url>http://www.jboss.org</url>
+  <description>A VFS library</description>
+ <scm>
+    <connection>scm:svn:http://anonsvn.jboss.org/repos/jbossas/projects/vfs/tags/2.0.0.CR2</connection>    
+    <developerConnection>scm:svn:https://svn.jboss.org/repos/jbossas/projects/vfs/tags/2.0.0.CR2</developerConnection>
+    <url>https://svn.jboss.org/repos/jbossas/projects/vfs/tags/2.0.0.CR2</url>
+  </scm>
+  <licenses>
+    <license>
+      <name>lgpl</name>
+      <url>http://repository.jboss.org/licenses/lgpl.txt</url>
+    </license>
+  </licenses>
+  <organization>
+    <name>JBoss, A division of Red Hat, Inc</name>
+    <url>http://www.jboss.org</url>
+  </organization>
+
+  <properties>
+    <version.jboss.common.core>2.2.9.GA</version.jboss.common.core>
+    <version.jboss.logging>2.0.5.GA</version.jboss.logging>
+    <version.jboss.test>1.1.0.GA</version.jboss.test>
+    <version.junit>4.4</version.junit>
+  </properties>
+
+  <build>
+    <sourceDirectory>src/main/java</sourceDirectory>
+    <testSourceDirectory>src/test/java</testSourceDirectory>
+    <finalName>${artifactId}</finalName>
+    <testResources>
+      <testResource>
+        <directory>src/test/resources</directory>
+      </testResource>
+    </testResources>
+    <plugins>
+      
+      <!-- define how we want compilation to take place
+        here, we accept most of the defaults but say that we want the
+        optimization flag set, and define the source and target to be 1.5,
+        these setting will be inherited by child projects -->
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.0</version>
+        <configuration>
+          <debug>true</debug>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>
+      <!-- define that we wish to create src jars -->
+      <plugin>
+        <artifactId>maven-source-plugin</artifactId>
+        <inherited>true</inherited>
+        <executions>
+          <execution>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <version>2.3.1</version>
+        <configuration>
+          <forkMode>always</forkMode> <!-- required to correctly run the PojoServer tests -->
+          <useSystemClassLoader>true</useSystemClassLoader>
+          <redirectTestOutputToFile>true</redirectTestOutputToFile>
+          <testFailureIgnore>true</testFailureIgnore>
+        </configuration>
+      </plugin>
+      <plugin>
+         <groupId>org.apache.maven.plugins</groupId>
+         <artifactId>maven-release-plugin</artifactId>
+         <version>2.0-beta-7</version>
+         <configuration>
+           <tagBase>https://svn.jboss.org/repos/jbossas/projects/vfs/tags</tagBase>
+         </configuration>
+       </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.jboss</groupId>
+      <artifactId>jboss-common-core</artifactId>
+      <version>${version.jboss.common.core}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.logging</groupId>
+      <artifactId>jboss-logging-spi</artifactId>
+      <version>${version.jboss.logging}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.jboss.test</groupId>
+      <artifactId>jboss-test</artifactId>
+      <version>${version.jboss.test}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>${version.junit}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+</project>

Deleted: projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFS.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFS.java	2008-10-20 08:32:12 UTC (rev 79734)
+++ projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFS.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -1,358 +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.net.URI;
-import java.net.URL;
-import java.util.List;
-
-import org.jboss.virtual.plugins.vfs.helpers.WrappingVirtualFileHandlerVisitor;
-import org.jboss.virtual.plugins.context.VfsArchiveBrowserFactory;
-import org.jboss.virtual.spi.VFSContext;
-import org.jboss.virtual.spi.VFSContextFactory;
-import org.jboss.virtual.spi.VFSContextFactoryLocator;
-import org.jboss.virtual.spi.VirtualFileHandler;
-import org.jboss.util.file.ArchiveBrowser;
-
-/**
- * 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 VFS
-{
-   /** The VFS Context */
-   private final VFSContext context;
-
-   static
-   {
-      init();
-   }
-
-   /**
-    * Initialize VFS protocol handlers package property. 
-    */
-   public static void init()
-   {
-      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"))
-      {
-         pkgs += "|org.jboss.virtual.protocol";
-         System.setProperty("java.protocol.handler.pkgs", pkgs);
-      }
-      // keep this until AOP and HEM uses VFS internally instead of the stupid ArchiveBrowser crap.
-      ArchiveBrowser.factoryFinder.put("vfsfile", new VfsArchiveBrowserFactory());
-      ArchiveBrowser.factoryFinder.put("vfsjar", new VfsArchiveBrowserFactory());
-      ArchiveBrowser.factoryFinder.put("vfs", new VfsArchiveBrowserFactory());      
-   }
-
-   /**
-    * Get the virtual file system for a root uri
-    * 
-    * @param rootURI the root URI
-    * @return the virtual file system
-    * @throws IOException if there is a problem accessing the VFS
-    * @throws IllegalArgumentException if the rootURL is null
-    */
-   public static VFS getVFS(URI rootURI) throws IOException
-   {
-      VFSContextFactory factory = VFSContextFactoryLocator.getFactory(rootURI);
-      if (factory == null)
-         throw new IOException("No context factory for " + rootURI);
-      VFSContext context = factory.getVFS(rootURI);
-      return context.getVFS();
-   }
-
-   /**
-    * Get the root virtual file
-    * 
-    * @param rootURI the root uri
-    * @return the virtual file
-    * @throws IOException if there is a problem accessing the VFS
-    * @throws IllegalArgumentException if the rootURL
-    */
-   public static VirtualFile getRoot(URI rootURI) throws IOException
-   {
-      VFS vfs = getVFS(rootURI);
-      return vfs.getRoot();
-   }
-
-   /**
-    * Get a virtual file
-    * 
-    * @param rootURI the root uri
-    * @param name the path name
-    * @return the virtual file
-    * @throws IOException if there is a problem accessing the VFS
-    * @throws IllegalArgumentException if the rootURL or name is null
-    */
-   public static VirtualFile getVirtualFile(URI rootURI, String name) throws IOException
-   {
-      VFS vfs = getVFS(rootURI);
-      return vfs.findChild(name);
-   }
-
-   /**
-    * Get the virtual file system for a root url
-    * 
-    * @param rootURL the root url
-    * @return the virtual file system
-    * @throws IOException if there is a problem accessing the VFS
-    * @throws IllegalArgumentException if the rootURL is null
-    */
-   public static VFS getVFS(URL rootURL) throws IOException
-   {
-      VFSContextFactory factory = VFSContextFactoryLocator.getFactory(rootURL);
-      if (factory == null)
-         throw new IOException("No context factory for " + rootURL);
-      VFSContext context = factory.getVFS(rootURL);
-      return context.getVFS();
-   }
-
-   /**
-    * Get the root virtual file
-    * 
-    * @param rootURL the root url
-    * @return the virtual file
-    * @throws IOException if there is a problem accessing the VFS
-    * @throws IllegalArgumentException if the rootURL
-    */
-   public static VirtualFile getRoot(URL rootURL) throws IOException
-   {
-      VFS vfs = getVFS(rootURL);
-      return vfs.getRoot();
-   }
-
-   /**
-    * Get a virtual file
-    * 
-    * @param rootURL the root url
-    * @param name the path name
-    * @return the virtual file
-    * @throws IOException if there is a problem accessing the VFS
-    * @throws IllegalArgumentException if the rootURL or name is null
-    */
-   public static VirtualFile getVirtualFile(URL rootURL, String name) throws IOException
-   {
-      VFS vfs = getVFS(rootURL);
-      return vfs.findChild(name);
-   }
-
-   /**
-    * Create a new VFS.
-    * 
-    * @param context the context
-    * @throws IllegalArgumentException for a null context
-    */
-   public VFS(VFSContext context)
-   {
-      if (context == null)
-         throw new IllegalArgumentException("Null name");
-      this.context = context;
-   }
-   
-   /**
-    * Get the root file of this VFS
-    * 
-    * @return the root
-    * @throws IOException for any problem accessing the VFS
-    */
-   public VirtualFile getRoot() throws IOException
-   {
-      VirtualFileHandler handler = context.getRoot();
-      return handler.getVirtualFile();
-   }
-   
-   /**
-    * Find a child from the root
-    *
-    * @param path the child path
-    * @return the child
-    * @throws IOException for any problem accessing the VFS (including the child does not exist)
-    * @throws IllegalArgumentException if the path is null
-    * @deprecated use getChild, and handle null if not found
-    */
-   @Deprecated
-   public VirtualFile findChild(String path) throws IOException
-   {
-      if (path == null)
-         throw new IllegalArgumentException("Null path");
-      
-      VirtualFileHandler handler = context.getRoot();
-      VirtualFileHandler result = context.getChild(handler, VFSUtils.fixName(path));
-      if (result == null)
-      {
-         List<VirtualFileHandler> children = handler.getChildren(true);
-         throw new IOException("Child not found " + path + " for " + handler + ", available children: " + children);
-      }
-      return result.getVirtualFile();
-   }
-   
-   /**
-   * Get a child
-   *
-   * @param path the child path
-   * @return the child or <code>null</code> if not found
-   * @throws IOException if a real problem occurs
-   */
-   public VirtualFile getChild(String path) throws IOException
-   {
-      if (path == null)
-         throw new IllegalArgumentException("Null path");
-
-      VirtualFileHandler handler = context.getRoot();
-      VirtualFileHandler result = context.getChild(handler, VFSUtils.fixName(path));
-      return result != null ? result.getVirtualFile() : null;
-   }
-
-   /**
-    * Find a child from the root
-    * 
-    * @deprecated use {@link #findChild(String)}
-    * @param path the child path
-    * @return the child
-    * @throws IOException for any problem accessing the VFS (including the child does not exist)
-    * @throws IllegalArgumentException if the path is null
-    */
-   @Deprecated
-   public VirtualFile findChildFromRoot(String path) throws IOException
-   {
-      return findChild(path);
-   }
-   
-   /**
-    * Get the children
-    * 
-    * @return the children
-    * @throws IOException for any problem accessing the virtual file system
-    */
-   public List<VirtualFile> getChildren() throws IOException
-   {
-      return getRoot().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 getRoot().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 getRoot().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 getRoot().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
-   {
-      VirtualFileHandler handler = context.getRoot();
-      if (handler.isLeaf() == false)
-      {
-         WrappingVirtualFileHandlerVisitor wrapper = new WrappingVirtualFileHandlerVisitor(visitor);
-         context.visit(handler, wrapper);
-      }
-   }
-
-   /**
-    * 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");
-
-      VirtualFileHandler handler = file.getHandler();
-      WrappingVirtualFileHandlerVisitor wrapper = new WrappingVirtualFileHandlerVisitor(visitor);
-      VFSContext handlerContext = handler.getVFSContext();
-      handlerContext.visit(handler, wrapper);
-   }
-
-   @Override
-   public String toString()
-   {
-      return context.toString();
-   }
-
-   @Override
-   public int hashCode()
-   {
-      return context.hashCode();
-   }
-   
-   @Override
-   public boolean equals(Object obj)
-   {
-      if (obj == this)
-         return true;
-      if (obj == null || obj instanceof VFS == false)
-         return false;
-      VFS other = (VFS) obj;
-      return context.equals(other.context);
-   }
-}

Copied: projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFS.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFS.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFS.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFS.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,399 @@
+/*
+* 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.net.URI;
+import java.net.URL;
+import java.util.List;
+
+import org.jboss.virtual.plugins.vfs.helpers.WrappingVirtualFileHandlerVisitor;
+import org.jboss.virtual.plugins.context.VfsArchiveBrowserFactory;
+import org.jboss.virtual.spi.VFSContext;
+import org.jboss.virtual.spi.VFSContextFactory;
+import org.jboss.virtual.spi.VFSContextFactoryLocator;
+import org.jboss.virtual.spi.VirtualFileHandler;
+import org.jboss.virtual.spi.cache.VFSCacheFactory;
+import org.jboss.virtual.spi.cache.VFSCache;
+import org.jboss.util.file.ArchiveBrowser;
+
+/**
+ * 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
+{
+   /** The VFS Context */
+   private final VFSContext context;
+
+   static
+   {
+      init();
+   }
+
+   /**
+    * Initialize VFS protocol handlers package property. 
+    */
+   public static void init()
+   {
+      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"))
+      {
+         pkgs += "|org.jboss.virtual.protocol";
+         System.setProperty("java.protocol.handler.pkgs", pkgs);
+      }
+      // keep this until AOP and HEM uses VFS internally instead of the stupid ArchiveBrowser crap.
+      ArchiveBrowser.factoryFinder.put("vfsfile", new VfsArchiveBrowserFactory());
+      ArchiveBrowser.factoryFinder.put("vfsjar", new VfsArchiveBrowserFactory());
+      ArchiveBrowser.factoryFinder.put("vfs", new VfsArchiveBrowserFactory());      
+   }
+
+   /**
+    * Get the virtual file system for a root uri
+    * 
+    * @param rootURI the root URI
+    * @return the virtual file system
+    * @throws IOException if there is a problem accessing the VFS
+    * @throws IllegalArgumentException if the rootURL is null
+    */
+   public static VFS getVFS(URI rootURI) throws IOException
+   {
+      VFSContextFactory factory = VFSContextFactoryLocator.getFactory(rootURI);
+      if (factory == null)
+         throw new IOException("No context factory for " + rootURI);
+      VFSContext context = factory.getVFS(rootURI);
+      VFSCacheFactory.getInstance().putContext(context);
+      return context.getVFS();
+   }
+
+   /**
+    * Get the root virtual file
+    * 
+    * @param rootURI the root uri
+    * @return the virtual file
+    * @throws IOException if there is a problem accessing the VFS
+    * @throws IllegalArgumentException if the rootURL is null
+    */
+   public static VirtualFile getRoot(URI rootURI) throws IOException
+   {
+      VFS vfs = getVFS(rootURI);
+      return vfs.getRoot();
+   }
+
+   /**
+    * Get cached file.
+    *
+    * If VFSContext matching the rootURI parameter is cached
+    * this method will return cached virtual file
+    * else it will use VFS::getRoot(rootURI).
+    *
+    * @param rootURI the root uri
+    * @return the cached virtual file
+    * @throws IOException for any error
+    * @throws IllegalArgumentException if the rootURL is null
+    */
+   public static VirtualFile getCachedFile(URI rootURI) throws IOException
+   {
+      VFSCache cache = VFSCacheFactory.getInstance();
+      return cache.getFile(rootURI);
+   }
+
+   /**
+    * Get a virtual file
+    * 
+    * @param rootURI the root uri
+    * @param name the path name
+    * @return the virtual file
+    * @throws IOException if there is a problem accessing the VFS
+    * @throws IllegalArgumentException if the rootURL or name is null
+    */
+   public static VirtualFile getVirtualFile(URI rootURI, String name) throws IOException
+   {
+      VFS vfs = getVFS(rootURI);
+      return vfs.findChild(name);
+   }
+
+   /**
+    * Get the virtual file system for a root url
+    * 
+    * @param rootURL the root url
+    * @return the virtual file system
+    * @throws IOException if there is a problem accessing the VFS
+    * @throws IllegalArgumentException if the rootURL is null
+    */
+   public static VFS getVFS(URL rootURL) throws IOException
+   {
+      VFSContextFactory factory = VFSContextFactoryLocator.getFactory(rootURL);
+      if (factory == null)
+         throw new IOException("No context factory for " + rootURL);
+      VFSContext context = factory.getVFS(rootURL);
+      VFSCacheFactory.getInstance().putContext(context);
+      return context.getVFS();
+   }
+
+   /**
+    * Get the root virtual file
+    * 
+    * @param rootURL the root url
+    * @return the virtual file
+    * @throws IOException if there is a problem accessing the VFS
+    * @throws IllegalArgumentException if the rootURL
+    */
+   public static VirtualFile getRoot(URL rootURL) throws IOException
+   {
+      VFS vfs = getVFS(rootURL);
+      return vfs.getRoot();
+   }
+
+   /**
+    * Get cached file.
+    *
+    * If VFSContext matching the rootURL parameter is cached
+    * this method will return cached virtual file
+    * else it will use VFS::getRoot(rootURL).
+    *
+    * @param rootURL the root url
+    * @return the cached virtual file
+    * @throws IOException for any error
+    * @throws IllegalArgumentException if the rootURL is null
+    */
+   public static VirtualFile getCachedFile(URL rootURL) throws IOException
+   {
+      VFSCache cache = VFSCacheFactory.getInstance();
+      return cache.getFile(rootURL);
+   }
+
+   /**
+    * Get a virtual file
+    * 
+    * @param rootURL the root url
+    * @param name the path name
+    * @return the virtual file
+    * @throws IOException if there is a problem accessing the VFS
+    * @throws IllegalArgumentException if the rootURL or name is null
+    */
+   public static VirtualFile getVirtualFile(URL rootURL, String name) throws IOException
+   {
+      VFS vfs = getVFS(rootURL);
+      return vfs.findChild(name);
+   }
+
+   /**
+    * Create a new VFS.
+    * 
+    * @param context the context
+    * @throws IllegalArgumentException for a null context
+    */
+   public VFS(VFSContext context)
+   {
+      if (context == null)
+         throw new IllegalArgumentException("Null name");
+      this.context = context;
+   }
+   
+   /**
+    * Get the root file of this VFS
+    * 
+    * @return the root
+    * @throws IOException for any problem accessing the VFS
+    */
+   public VirtualFile getRoot() throws IOException
+   {
+      VirtualFileHandler handler = context.getRoot();
+      return handler.getVirtualFile();
+   }
+   
+   /**
+    * Find a child from the root
+    *
+    * @param path the child path
+    * @return the child
+    * @throws IOException for any problem accessing the VFS (including the child does not exist)
+    * @throws IllegalArgumentException if the path is null
+    * @deprecated use getChild, and handle null if not found
+    */
+   @Deprecated
+   public VirtualFile findChild(String path) throws IOException
+   {
+      if (path == null)
+         throw new IllegalArgumentException("Null path");
+      
+      VirtualFileHandler handler = context.getRoot();
+      VirtualFileHandler result = context.getChild(handler, VFSUtils.fixName(path));
+      if (result == null)
+      {
+         List<VirtualFileHandler> children = handler.getChildren(true);
+         throw new IOException("Child not found " + path + " for " + handler + ", available children: " + children);
+      }
+      return result.getVirtualFile();
+   }
+   
+   /**
+   * Get a child
+   *
+   * @param path the child path
+   * @return the child or <code>null</code> if not found
+   * @throws IOException if a real problem occurs
+   */
+   public VirtualFile getChild(String path) throws IOException
+   {
+      if (path == null)
+         throw new IllegalArgumentException("Null path");
+
+      VirtualFileHandler handler = context.getRoot();
+      VirtualFileHandler result = context.getChild(handler, VFSUtils.fixName(path));
+      return result != null ? result.getVirtualFile() : null;
+   }
+
+   /**
+    * Find a child from the root
+    * 
+    * @deprecated use {@link #findChild(String)}
+    * @param path the child path
+    * @return the child
+    * @throws IOException for any problem accessing the VFS (including the child does not exist)
+    * @throws IllegalArgumentException if the path is null
+    */
+   @Deprecated
+   public VirtualFile findChildFromRoot(String path) throws IOException
+   {
+      return findChild(path);
+   }
+   
+   /**
+    * Get the children
+    * 
+    * @return the children
+    * @throws IOException for any problem accessing the virtual file system
+    */
+   public List<VirtualFile> getChildren() throws IOException
+   {
+      return getRoot().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 getRoot().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 getRoot().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 getRoot().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
+   {
+      VirtualFileHandler handler = context.getRoot();
+      if (handler.isLeaf() == false)
+      {
+         WrappingVirtualFileHandlerVisitor wrapper = new WrappingVirtualFileHandlerVisitor(visitor);
+         context.visit(handler, wrapper);
+      }
+   }
+
+   /**
+    * 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");
+
+      VirtualFileHandler handler = file.getHandler();
+      WrappingVirtualFileHandlerVisitor wrapper = new WrappingVirtualFileHandlerVisitor(visitor);
+      VFSContext handlerContext = handler.getVFSContext();
+      handlerContext.visit(handler, wrapper);
+   }
+
+   @Override
+   public String toString()
+   {
+      return context.toString();
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return context.hashCode();
+   }
+   
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj == this)
+         return true;
+      if (obj == null || obj instanceof VFS == false)
+         return false;
+      VFS other = (VFS) obj;
+      return context.equals(other.context);
+   }
+}

Deleted: projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFSUtils.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFSUtils.java	2008-10-20 08:32:12 UTC (rev 79734)
+++ projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFSUtils.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -1,896 +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.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.net.URLDecoder;
-import java.net.MalformedURLException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.StringTokenizer;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.jar.Manifest;
-
-import org.jboss.logging.Logger;
-import org.jboss.util.StringPropertyReplacer;
-import org.jboss.util.collection.CollectionsFactory;
-import org.jboss.virtual.plugins.copy.CopyMechanism;
-import org.jboss.virtual.plugins.copy.ExplodedCopyMechanism;
-import org.jboss.virtual.plugins.copy.TempCopyMechanism;
-import org.jboss.virtual.plugins.copy.UnpackCopyMechanism;
-import org.jboss.virtual.spi.LinkInfo;
-import org.jboss.virtual.spi.VFSContext;
-import org.jboss.virtual.spi.VirtualFileHandler;
-
-/**
- * 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";
-
-   /** The link */
-   public static final String VFS_LINK_INFIX = ".vfslink";
-
-   /** The link properties */
-   public static final String VFS_LINK_PROPERTIES_SUFFIX = ".vfslink.properties";
-
-   /** The link name */
-   public static final String VFS_LINK_NAME = "vfs.link.name";
-   /** The link target */
-   public static final String VFS_LINK_TARGET = "vfs.link.target";
-
-   /**
-    * The system no force copy key / query
-    */
-   public static final String FORCE_COPY_KEY = "jboss.vfs.forceCopy";
-   public static final String USE_COPY_QUERY = "useCopyJarHandler";
-
-   /**
-    * Key used to force fallback from vfszip (default) to vfsjar
-    */
-   public static final String FORCE_VFS_JAR_KEY = "jboss.vfs.forceVfsJar";
-
-   /**
-    * Key used to turn off reaper mode in vfszip - forcing synchronous (slower) handling of files
-    */
-   public static final String FORCE_NO_REAPER_KEY = "jboss.vfs.forceNoReaper";
-   public static final String NO_REAPER_QUERY = "noReaper";
-
-   /**
-    * Key used to force case sensitive path checking in vfsfile
-    */
-   public static final String FORCE_CASE_SENSITIVE_KEY = "jboss.vfs.forceCaseSensitive";
-   public static final String CASE_SENSITIVE_QUERY = "caseSensitive";
-
-   /**
-    * Key used to turn on memory optimizations - less cache use at the expense of performance
-    */
-   public static final String OPTIMIZE_FOR_MEMORY_KEY = "jboss.vfs.optimizeForMemory";
-
-   /**
-    * 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");
-
-      Manifest manifest = getManifest(file);
-      if (manifest == null)
-         return;
-
-      Attributes mainAttributes = manifest.getMainAttributes();
-      String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
-
-      if (classPath == null)
-      {
-         if (log.isTraceEnabled())
-            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;
-      }
-
-      URL parentURL;
-      URL vfsRootURL;
-      int rootPathLength;
-      try
-      {
-         parentURL = parent.toURL();
-         vfsRootURL = file.getVFS().getRoot().toURL();
-         rootPathLength = vfsRootURL.getPath().length();
-      }
-      catch(URISyntaxException e)
-      {
-         log.debug("Failed to get parent URL for " + file + ", reason=" + e);
-         return;
-      }
-
-      String parentPath = parentURL.toString();
-      if(parentPath.endsWith("/") == false)
-         parentPath += "/";
-
-      StringTokenizer tokenizer = new StringTokenizer(classPath);
-      while (tokenizer.hasMoreTokens())
-      {
-         String path = tokenizer.nextToken();
-         try
-         {
-            URL libURL = new URL(parentPath + path);
-            String libPath = libURL.getPath();
-            if(rootPathLength > libPath.length())
-            {
-               log.debug("Invalid rootPath: " + vfsRootURL + ", libPath: " + libPath);
-               continue;
-            }
-
-            String vfsLibPath = libPath.substring(rootPathLength);
-            VirtualFile vf = file.getVFS().getChild(vfsLibPath);
-            if(vf != null)
-            {
-               if(paths.contains(vf) == false)
-               {
-                  paths.add(vf);
-                  // Recursively process the jar
-                  addManifestLocations(vf, paths);
-               }
-            }
-         }
-         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
-      {
-         try
-         {
-            stream.close();
-         }
-         catch (IOException ignored)
-         {
-         }
-      }
-   }
-
-   /**
-     * Get a manifest from a virtual file system,
-     * assuming the root of the VFS is the root of an archive
-     *
-     * @param archive the vfs
-     * @return the manifest or null if not found
-     * @throws IOException if there is an error reading the manifest
-     * @throws IllegalArgumentException for a null archive
-     */
-    public static Manifest getManifest(VFS archive) throws IOException
-    {
-       if (archive == null)
-         throw new IllegalArgumentException("Null vfs archive");
-
-       VirtualFile root = archive.getRoot();
-       return getManifest(root);
-    }
-
-   /**
-    * 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;
-   }
-
-   /**
-    * Does a vf name contain the VFS link prefix
-    * @param name - the name portion of a virtual file
-    * @return true if the name starts with VFS_LINK_PREFIX, false otherwise
-    */
-   public static boolean isLink(String name)
-   {
-      if (name == null)
-         throw new IllegalArgumentException("Null name");
-
-      return name.indexOf(VFS_LINK_INFIX) >= 0;
-   }
-
-   /**
-    * Read the link information from the stream based on the type as determined
-    * from the name suffix.
-    *
-    * @param is - input stream to the link file contents
-    * @param name - the name of the virtual file representing the link
-    * @param props the propertes
-    * @return a list of the links read from the stream
-    * @throws IOException on failure to read/parse the stream
-    * @throws URISyntaxException for an error parsing a URI
-    */
-   public static List<LinkInfo> readLinkInfo(InputStream is, String name, Properties props)
-      throws IOException, URISyntaxException
-   {
-      if (name == null)
-         throw new IllegalArgumentException("Null name");
-
-      if(name.endsWith(VFS_LINK_PROPERTIES_SUFFIX))
-      {
-         List<LinkInfo> info = new ArrayList<LinkInfo>();
-         parseLinkProperties(is, info, props);
-         return info;
-      }
-      else
-         throw new UnsupportedEncodingException("Unknown link format: " + name);
-   }
-
-   /**
-    * Parse a properties link file
-    *
-    * @param is - input stream to the link file contents
-    * @param info the link infos
-    * @param props the propertes
-    * @throws IOException on failure to read/parse the stream
-    * @throws URISyntaxException for an error parsing a URI
-    */
-   public static void parseLinkProperties(InputStream is, List<LinkInfo> info, Properties props)
-      throws IOException, URISyntaxException
-   {
-      if (is == null)
-         throw new IllegalArgumentException("Null input stream");
-      if (info == null)
-         throw new IllegalArgumentException("Null info");
-      if (props == null)
-         throw new IllegalArgumentException("Null properties");
-
-      props.load(is);
-      // Iterate over the property tuples
-      for(int n = 0; ; n ++)
-      {
-         String nameKey = VFS_LINK_NAME + "." + n;
-         String name = props.getProperty(nameKey);
-         String uriKey = VFS_LINK_TARGET + "." + n;
-         String uri = props.getProperty(uriKey);
-         // End when the value is null since a link may not have a name
-         if (uri == null)
-         {
-            break;
-         }
-         // Replace any system property references
-         uri = StringPropertyReplacer.replaceProperties(uri);
-         LinkInfo link = new LinkInfo(name, new URI(uri));
-         info.add(link);
-      }
-   }
-
-   /**
-    * 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();
-   }
-
-   /**
-    * Get the options for this file.
-    *
-    * @param file the file
-    * @return options map
-    */
-   private static Map<String, String> getOptions(VirtualFile file)
-   {
-      if (file == null)
-         throw new IllegalArgumentException("Null file");
-
-      VirtualFileHandler handler = file.getHandler();
-      VFSContext context = handler.getVFSContext();
-      return context.getOptions();
-   }
-
-   /**
-    * Get the option.
-    *
-    * @param file the file
-    * @param key the option key
-    * @return key's option
-    */
-   public static String getOption(VirtualFile file, String key)
-   {
-      Map<String, String> options = getOptions(file);
-      return options != null ? options.get(key) : null;
-   }
-
-   /**
-    * Enable option.
-    *
-    * @param file the file
-    * @param optionName option name
-    */
-   protected static void enableOption(VirtualFile file, String optionName)
-   {
-      Map<String, String> options = getOptions(file);
-      if (options == null)
-         throw new IllegalArgumentException("Cannot enable " + optionName + " on null options: " + file);
-
-      options.put(optionName, Boolean.TRUE.toString());
-   }
-
-   /**
-    * Disable option.
-    *
-    * @param file the file
-    * @param optionName option name
-    */
-   protected static void disableOption(VirtualFile file, String optionName)
-   {
-      Map<String, String> options = getOptions(file);
-      if (options == null)
-         throw new IllegalArgumentException("Cannot disable " + optionName + " on null options: " + file);
-
-      options.remove(optionName);
-   }
-
-   /**
-    * Enable copy for file param.
-    *
-    * @param file the file
-    */
-   public static void enableCopy(VirtualFile file)
-   {
-      enableOption(file, USE_COPY_QUERY);
-   }
-
-   /**
-    * Disable copy for file param.
-    *
-    * @param file the file
-    */
-   public static void disableCopy(VirtualFile file)
-   {
-      disableOption(file, USE_COPY_QUERY);
-   }
-
-   /**
-    * Enable repaer for file param.
-    *
-    * @param file the file
-    */
-   public static void enableNoReaper(VirtualFile file)
-   {
-      enableOption(file, NO_REAPER_QUERY);
-   }
-
-   /**
-    * Disable reaper for file param.
-    *
-    * @param file the file
-    */
-   public static void disableNoReaper(VirtualFile file)
-   {
-      disableOption(file, NO_REAPER_QUERY);
-   }
-
-   /**
-    * Enable case sensitive for file param.
-    *
-    * @param file the file
-    */
-   public static void enableCaseSensitive(VirtualFile file)
-   {
-      enableOption(file, CASE_SENSITIVE_QUERY);
-   }
-
-   /**
-    * Disable case sensitive for file param.
-    *
-    * @param file the file
-    */
-   public static void disableCaseSensitive(VirtualFile file)
-   {
-      disableOption(file, CASE_SENSITIVE_QUERY);
-   }
-
-   /**
-    * Unpack the nested artifact under file param.
-    *
-    * @param file the file to unpack
-    * @return unpacked file
-    * @throws IOException for any io error
-    * @throws URISyntaxException for any uri error
-    */
-   public static VirtualFile unpack(VirtualFile file) throws IOException, URISyntaxException
-   {
-      return copy(file, UnpackCopyMechanism.INSTANCE);
-   }
-
-   /**
-    * Force explode.
-    * Explode archives or nested entries.
-    *
-    * @param file the file to explode
-    * @return exploded file
-    * @throws IOException for any io error
-    * @throws URISyntaxException for any uri error
-    */
-   public static VirtualFile explode(VirtualFile file) throws IOException, URISyntaxException
-   {
-      return copy(file, ExplodedCopyMechanism.INSTANCE);
-   }
-
-   /**
-    * Create temp.
-    *
-    * @param file the file to temp
-    * @return temp file
-    * @throws IOException for any io error
-    * @throws URISyntaxException for any uri error
-    */
-   public static VirtualFile temp(VirtualFile file) throws IOException, URISyntaxException
-   {
-      return copy(file, TempCopyMechanism.INSTANCE);
-   }
-
-   /**
-    * Create temp.
-    *
-    * @param file the file to unpack/explode
-    * @param mechanism the copy mechanism
-    * @return temp file
-    * @throws IOException for any io error
-    * @throws URISyntaxException for any uri error
-    */
-   protected static VirtualFile copy(VirtualFile file, CopyMechanism mechanism) throws IOException, URISyntaxException
-   {
-      if (file == null)
-         throw new IllegalArgumentException("Null file");
-      if (mechanism == null)
-         throw new IllegalArgumentException("Null copy mechanism");
-
-      return mechanism.copy(file, file.getHandler());
-   }
-
-   /**
-    * Is file handle nested.
-    *
-    * @param file the file handle to check
-    * @return true if file/dir is nested otherwise false
-    * @throws IOException for any error
-    */
-   public static boolean isNestedFile(VirtualFile file) throws IOException
-   {
-      if (file == null)
-         throw new IllegalArgumentException("Null file");
-
-      VirtualFileHandler handler = file.getHandler();
-      return handler.isNested();
-   }
-
-   /**
-    * 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
-   {
-      try
-      {
-         copyStream(is, os);
-      }
-      finally
-      {
-         if (is != null)
-         {
-            try
-            {
-               is.close();
-            }
-            catch(IOException ignored)
-            {
-            }
-         }
-         if (os != null)
-            os.close();
-      }
-   }
-
-   /**
-    * 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
-   {
-      if (is == null)
-         throw new IllegalArgumentException("input stream is null");
-      if (os == null)
-         throw new IllegalArgumentException("output stream is null");
-
-      try
-      {
-         byte [] buff = new byte[65536];
-         int rc = is.read(buff);
-         while (rc != -1)
-         {
-            os.write(buff, 0, rc);
-            rc = is.read(buff);
-         }
-      }
-      finally
-      {
-         os.flush();
-      }
-   }
-
-   /**
-    * Get spec compatilbe url from virtual file.
-    *
-    * @param file the virtual file
-    * @return spec compatible url
-    * @throws Exception for any error
-    */
-   public static URL getCompatibleURL(VirtualFile file) throws Exception
-   {
-      return getCompatibleResource(file, URL_CREATOR);
-   }
-
-   /**
-    * Get spec compatilbe uri from virtual file.
-    *
-    * @param file the virtual file
-    * @return spec compatible uri
-    * @throws Exception for any error
-    */
-   public static URI getCompatibleURI(VirtualFile file) throws Exception
-   {
-      return getCompatibleResource(file, URI_CREATOR);
-   }
-
-   /**
-    * Create new compatible resource.
-    *
-    * @param file the virtual file
-    * @param creator resoruce creator
-    * @return new resource
-    * @throws Exception for any error
-    * @param <T> exact resource type
-    */
-   private static <T> T getCompatibleResource(VirtualFile file, ResourceCreator<T> creator) throws Exception
-   {
-      if (file == null)
-         throw new IllegalArgumentException("Null file");
-      if (creator == null)
-         throw new IllegalArgumentException("Null creator");
-
-      T resource = creator.getResource(file);
-      if (resource == null)
-         throw new IllegalArgumentException("Null resource: " + file);
-
-      // is not nested, so direct VFS resource is not an option
-      if (isNestedFile(file) == false)
-      {
-         String uriString = creator.getString(resource);
-         if (uriString.startsWith("vfs"))
-         {
-            // treat vfszip as file
-            if (uriString.startsWith("vfszip"))
-               resource = creator.createResource("file" + uriString.substring(6));
-            else
-               resource = creator.createResource(uriString.substring(3)); // (vfs)file and (vfs)jar are ok
-         }
-      }
-      return resource;
-   }
-
-   /**
-    * @param <T> exact resource type
-    */
-   private static interface ResourceCreator<T>
-   {
-      /**
-       * Get resource from virtual file.
-       *
-       * @param file the virtual file
-       * @return resource instance from file
-       * @throws Exception for any error
-       */
-      T getResource(VirtualFile file) throws Exception;
-
-      /**
-       * Get string from resource.
-       *
-       * @param resource the resource
-       * @return resoruce's string representation
-       */
-      String getString(T resource);
-
-      /**
-       * Create new resource.
-       *
-       * @param string the string to create resource from
-       * @return new resoruce instance
-       * @throws Exception for any error
-       */
-      T createResource(String string) throws Exception;
-   }
-
-   private static final ResourceCreator<URL> URL_CREATOR = new ResourceCreator<URL>()
-   {
-      public URL getResource(VirtualFile file) throws Exception
-      {
-         return file.toURL();
-      }
-
-      public String getString(URL resource)
-      {
-         return resource.toExternalForm();
-      }
-
-      public URL createResource(String string) throws Exception
-      {
-         return new URL(string);
-      }
-   };
-
-   private static final ResourceCreator<URI> URI_CREATOR = new ResourceCreator<URI>()
-   {
-      public URI getResource(VirtualFile file) throws Exception
-      {
-         return file.toURI();
-      }
-
-      public String getString(URI resource)
-      {
-         return resource.toString();
-      }
-
-      public URI createResource(String string) throws Exception
-      {
-         return new URI(string);
-      }
-   };
-}

Copied: projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFSUtils.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/VFSUtils.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFSUtils.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/VFSUtils.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,910 @@
+/*
+* 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.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+import org.jboss.logging.Logger;
+import org.jboss.util.StringPropertyReplacer;
+import org.jboss.util.collection.CollectionsFactory;
+import org.jboss.virtual.plugins.copy.CopyMechanism;
+import org.jboss.virtual.plugins.copy.ExplodedCopyMechanism;
+import org.jboss.virtual.plugins.copy.TempCopyMechanism;
+import org.jboss.virtual.plugins.copy.UnpackCopyMechanism;
+import org.jboss.virtual.spi.LinkInfo;
+import org.jboss.virtual.spi.VFSContext;
+import org.jboss.virtual.spi.VirtualFileHandler;
+import org.jboss.virtual.spi.cache.VFSCacheFactory;
+
+/**
+ * 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";
+
+   /** The link */
+   public static final String VFS_LINK_INFIX = ".vfslink";
+
+   /** The link properties */
+   public static final String VFS_LINK_PROPERTIES_SUFFIX = ".vfslink.properties";
+
+   /** The link name */
+   public static final String VFS_LINK_NAME = "vfs.link.name";
+   /** The link target */
+   public static final String VFS_LINK_TARGET = "vfs.link.target";
+
+   /**
+    * The system no force copy key / query
+    */
+   public static final String FORCE_COPY_KEY = "jboss.vfs.forceCopy";
+   public static final String USE_COPY_QUERY = "useCopyJarHandler";
+
+   /**
+    * Key used to force fallback from vfszip (default) to vfsjar
+    */
+   public static final String FORCE_VFS_JAR_KEY = "jboss.vfs.forceVfsJar";
+
+   /**
+    * Key used to turn off reaper mode in vfszip - forcing synchronous (slower) handling of files
+    */
+   public static final String FORCE_NO_REAPER_KEY = "jboss.vfs.forceNoReaper";
+   public static final String NO_REAPER_QUERY = "noReaper";
+
+   /**
+    * Key used to force case sensitive path checking in vfsfile
+    */
+   public static final String FORCE_CASE_SENSITIVE_KEY = "jboss.vfs.forceCaseSensitive";
+   public static final String CASE_SENSITIVE_QUERY = "caseSensitive";
+
+   /**
+    * Key used to turn on memory optimizations - less cache use at the expense of performance
+    */
+   public static final String OPTIMIZE_FOR_MEMORY_KEY = "jboss.vfs.optimizeForMemory";
+
+   /**
+    * Key used to determine VFS Cache impl
+    */
+   public static final String VFS_CACHE_KEY = "jboss.vfs.cache";
+
+   /**
+    * Stop cache.
+    */
+   public static void stopCache()
+   {
+      VFSCacheFactory.getInstance().stop();
+   }
+
+   /**
+    * 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");
+
+      Manifest manifest = getManifest(file);
+      if (manifest == null)
+         return;
+
+      Attributes mainAttributes = manifest.getMainAttributes();
+      String classPath = mainAttributes.getValue(Attributes.Name.CLASS_PATH);
+
+      if (classPath == null)
+      {
+         if (log.isTraceEnabled())
+            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;
+      }
+
+      URL parentURL;
+      URL vfsRootURL;
+      int rootPathLength;
+      try
+      {
+         parentURL = parent.toURL();
+         vfsRootURL = file.getVFS().getRoot().toURL();
+         rootPathLength = vfsRootURL.getPath().length();
+      }
+      catch(URISyntaxException e)
+      {
+         log.debug("Failed to get parent URL for " + file + ", reason=" + e);
+         return;
+      }
+
+      String parentPath = parentURL.toString();
+      if(parentPath.endsWith("/") == false)
+         parentPath += "/";
+
+      StringTokenizer tokenizer = new StringTokenizer(classPath);
+      while (tokenizer.hasMoreTokens())
+      {
+         String path = tokenizer.nextToken();
+         try
+         {
+            URL libURL = new URL(parentPath + path);
+            String libPath = libURL.getPath();
+            if(rootPathLength > libPath.length())
+            {
+               log.debug("Invalid rootPath: " + vfsRootURL + ", libPath: " + libPath);
+               continue;
+            }
+
+            String vfsLibPath = libPath.substring(rootPathLength);
+            VirtualFile vf = file.getVFS().getChild(vfsLibPath);
+            if(vf != null)
+            {
+               if(paths.contains(vf) == false)
+               {
+                  paths.add(vf);
+                  // Recursively process the jar
+                  addManifestLocations(vf, paths);
+               }
+            }
+         }
+         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
+      {
+         try
+         {
+            stream.close();
+         }
+         catch (IOException ignored)
+         {
+         }
+      }
+   }
+
+   /**
+     * Get a manifest from a virtual file system,
+     * assuming the root of the VFS is the root of an archive
+     *
+     * @param archive the vfs
+     * @return the manifest or null if not found
+     * @throws IOException if there is an error reading the manifest
+     * @throws IllegalArgumentException for a null archive
+     */
+    public static Manifest getManifest(VFS archive) throws IOException
+    {
+       if (archive == null)
+         throw new IllegalArgumentException("Null vfs archive");
+
+       VirtualFile root = archive.getRoot();
+       return getManifest(root);
+    }
+
+   /**
+    * 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;
+   }
+
+   /**
+    * Does a vf name contain the VFS link prefix
+    * @param name - the name portion of a virtual file
+    * @return true if the name starts with VFS_LINK_PREFIX, false otherwise
+    */
+   public static boolean isLink(String name)
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+
+      return name.indexOf(VFS_LINK_INFIX) >= 0;
+   }
+
+   /**
+    * Read the link information from the stream based on the type as determined
+    * from the name suffix.
+    *
+    * @param is - input stream to the link file contents
+    * @param name - the name of the virtual file representing the link
+    * @param props the propertes
+    * @return a list of the links read from the stream
+    * @throws IOException on failure to read/parse the stream
+    * @throws URISyntaxException for an error parsing a URI
+    */
+   public static List<LinkInfo> readLinkInfo(InputStream is, String name, Properties props)
+      throws IOException, URISyntaxException
+   {
+      if (name == null)
+         throw new IllegalArgumentException("Null name");
+
+      if(name.endsWith(VFS_LINK_PROPERTIES_SUFFIX))
+      {
+         List<LinkInfo> info = new ArrayList<LinkInfo>();
+         parseLinkProperties(is, info, props);
+         return info;
+      }
+      else
+         throw new UnsupportedEncodingException("Unknown link format: " + name);
+   }
+
+   /**
+    * Parse a properties link file
+    *
+    * @param is - input stream to the link file contents
+    * @param info the link infos
+    * @param props the propertes
+    * @throws IOException on failure to read/parse the stream
+    * @throws URISyntaxException for an error parsing a URI
+    */
+   public static void parseLinkProperties(InputStream is, List<LinkInfo> info, Properties props)
+      throws IOException, URISyntaxException
+   {
+      if (is == null)
+         throw new IllegalArgumentException("Null input stream");
+      if (info == null)
+         throw new IllegalArgumentException("Null info");
+      if (props == null)
+         throw new IllegalArgumentException("Null properties");
+
+      props.load(is);
+      // Iterate over the property tuples
+      for(int n = 0; ; n ++)
+      {
+         String nameKey = VFS_LINK_NAME + "." + n;
+         String name = props.getProperty(nameKey);
+         String uriKey = VFS_LINK_TARGET + "." + n;
+         String uri = props.getProperty(uriKey);
+         // End when the value is null since a link may not have a name
+         if (uri == null)
+         {
+            break;
+         }
+         // Replace any system property references
+         uri = StringPropertyReplacer.replaceProperties(uri);
+         LinkInfo link = new LinkInfo(name, new URI(uri));
+         info.add(link);
+      }
+   }
+
+   /**
+    * 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();
+   }
+
+   /**
+    * Get the options for this file.
+    *
+    * @param file the file
+    * @return options map
+    */
+   private static Map<String, String> getOptions(VirtualFile file)
+   {
+      if (file == null)
+         throw new IllegalArgumentException("Null file");
+
+      VirtualFileHandler handler = file.getHandler();
+      VFSContext context = handler.getVFSContext();
+      return context.getOptions();
+   }
+
+   /**
+    * Get the option.
+    *
+    * @param file the file
+    * @param key the option key
+    * @return key's option
+    */
+   public static String getOption(VirtualFile file, String key)
+   {
+      Map<String, String> options = getOptions(file);
+      return options != null ? options.get(key) : null;
+   }
+
+   /**
+    * Enable option.
+    *
+    * @param file the file
+    * @param optionName option name
+    */
+   protected static void enableOption(VirtualFile file, String optionName)
+   {
+      Map<String, String> options = getOptions(file);
+      if (options == null)
+         throw new IllegalArgumentException("Cannot enable " + optionName + " on null options: " + file);
+
+      options.put(optionName, Boolean.TRUE.toString());
+   }
+
+   /**
+    * Disable option.
+    *
+    * @param file the file
+    * @param optionName option name
+    */
+   protected static void disableOption(VirtualFile file, String optionName)
+   {
+      Map<String, String> options = getOptions(file);
+      if (options == null)
+         throw new IllegalArgumentException("Cannot disable " + optionName + " on null options: " + file);
+
+      options.remove(optionName);
+   }
+
+   /**
+    * Enable copy for file param.
+    *
+    * @param file the file
+    */
+   public static void enableCopy(VirtualFile file)
+   {
+      enableOption(file, USE_COPY_QUERY);
+   }
+
+   /**
+    * Disable copy for file param.
+    *
+    * @param file the file
+    */
+   public static void disableCopy(VirtualFile file)
+   {
+      disableOption(file, USE_COPY_QUERY);
+   }
+
+   /**
+    * Enable repaer for file param.
+    *
+    * @param file the file
+    */
+   public static void enableNoReaper(VirtualFile file)
+   {
+      enableOption(file, NO_REAPER_QUERY);
+   }
+
+   /**
+    * Disable reaper for file param.
+    *
+    * @param file the file
+    */
+   public static void disableNoReaper(VirtualFile file)
+   {
+      disableOption(file, NO_REAPER_QUERY);
+   }
+
+   /**
+    * Enable case sensitive for file param.
+    *
+    * @param file the file
+    */
+   public static void enableCaseSensitive(VirtualFile file)
+   {
+      enableOption(file, CASE_SENSITIVE_QUERY);
+   }
+
+   /**
+    * Disable case sensitive for file param.
+    *
+    * @param file the file
+    */
+   public static void disableCaseSensitive(VirtualFile file)
+   {
+      disableOption(file, CASE_SENSITIVE_QUERY);
+   }
+
+   /**
+    * Unpack the nested artifact under file param.
+    *
+    * @param file the file to unpack
+    * @return unpacked file
+    * @throws IOException for any io error
+    * @throws URISyntaxException for any uri error
+    */
+   public static VirtualFile unpack(VirtualFile file) throws IOException, URISyntaxException
+   {
+      return copy(file, UnpackCopyMechanism.INSTANCE);
+   }
+
+   /**
+    * Force explode.
+    * Explode archives or nested entries.
+    *
+    * @param file the file to explode
+    * @return exploded file
+    * @throws IOException for any io error
+    * @throws URISyntaxException for any uri error
+    */
+   public static VirtualFile explode(VirtualFile file) throws IOException, URISyntaxException
+   {
+      return copy(file, ExplodedCopyMechanism.INSTANCE);
+   }
+
+   /**
+    * Create temp.
+    *
+    * @param file the file to temp
+    * @return temp file
+    * @throws IOException for any io error
+    * @throws URISyntaxException for any uri error
+    */
+   public static VirtualFile temp(VirtualFile file) throws IOException, URISyntaxException
+   {
+      return copy(file, TempCopyMechanism.INSTANCE);
+   }
+
+   /**
+    * Create temp.
+    *
+    * @param file the file to unpack/explode
+    * @param mechanism the copy mechanism
+    * @return temp file
+    * @throws IOException for any io error
+    * @throws URISyntaxException for any uri error
+    */
+   protected static VirtualFile copy(VirtualFile file, CopyMechanism mechanism) throws IOException, URISyntaxException
+   {
+      if (file == null)
+         throw new IllegalArgumentException("Null file");
+      if (mechanism == null)
+         throw new IllegalArgumentException("Null copy mechanism");
+
+      return mechanism.copy(file, file.getHandler());
+   }
+
+   /**
+    * Is file handle nested.
+    *
+    * @param file the file handle to check
+    * @return true if file/dir is nested otherwise false
+    * @throws IOException for any error
+    */
+   public static boolean isNestedFile(VirtualFile file) throws IOException
+   {
+      if (file == null)
+         throw new IllegalArgumentException("Null file");
+
+      VirtualFileHandler handler = file.getHandler();
+      return handler.isNested();
+   }
+
+   /**
+    * 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
+   {
+      try
+      {
+         copyStream(is, os);
+      }
+      finally
+      {
+         if (is != null)
+         {
+            try
+            {
+               is.close();
+            }
+            catch(IOException ignored)
+            {
+            }
+         }
+         if (os != null)
+            os.close();
+      }
+   }
+
+   /**
+    * 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
+   {
+      if (is == null)
+         throw new IllegalArgumentException("input stream is null");
+      if (os == null)
+         throw new IllegalArgumentException("output stream is null");
+
+      try
+      {
+         byte [] buff = new byte[65536];
+         int rc = is.read(buff);
+         while (rc != -1)
+         {
+            os.write(buff, 0, rc);
+            rc = is.read(buff);
+         }
+      }
+      finally
+      {
+         os.flush();
+      }
+   }
+
+   /**
+    * Get spec compatilbe url from virtual file.
+    *
+    * @param file the virtual file
+    * @return spec compatible url
+    * @throws Exception for any error
+    */
+   public static URL getCompatibleURL(VirtualFile file) throws Exception
+   {
+      return getCompatibleResource(file, URL_CREATOR);
+   }
+
+   /**
+    * Get spec compatilbe uri from virtual file.
+    *
+    * @param file the virtual file
+    * @return spec compatible uri
+    * @throws Exception for any error
+    */
+   public static URI getCompatibleURI(VirtualFile file) throws Exception
+   {
+      return getCompatibleResource(file, URI_CREATOR);
+   }
+
+   /**
+    * Create new compatible resource.
+    *
+    * @param file the virtual file
+    * @param creator resoruce creator
+    * @return new resource
+    * @throws Exception for any error
+    * @param <T> exact resource type
+    */
+   private static <T> T getCompatibleResource(VirtualFile file, ResourceCreator<T> creator) throws Exception
+   {
+      if (file == null)
+         throw new IllegalArgumentException("Null file");
+      if (creator == null)
+         throw new IllegalArgumentException("Null creator");
+
+      T resource = creator.getResource(file);
+      if (resource == null)
+         throw new IllegalArgumentException("Null resource: " + file);
+
+      // is not nested, so direct VFS resource is not an option
+      if (isNestedFile(file) == false)
+      {
+         String uriString = creator.getString(resource);
+         if (uriString.startsWith("vfs"))
+         {
+            // treat vfszip as file
+            if (uriString.startsWith("vfszip"))
+               resource = creator.createResource("file" + uriString.substring(6));
+            else
+               resource = creator.createResource(uriString.substring(3)); // (vfs)file and (vfs)jar are ok
+         }
+      }
+      return resource;
+   }
+
+   /**
+    * @param <T> exact resource type
+    */
+   private static interface ResourceCreator<T>
+   {
+      /**
+       * Get resource from virtual file.
+       *
+       * @param file the virtual file
+       * @return resource instance from file
+       * @throws Exception for any error
+       */
+      T getResource(VirtualFile file) throws Exception;
+
+      /**
+       * Get string from resource.
+       *
+       * @param resource the resource
+       * @return resoruce's string representation
+       */
+      String getString(T resource);
+
+      /**
+       * Create new resource.
+       *
+       * @param string the string to create resource from
+       * @return new resoruce instance
+       * @throws Exception for any error
+       */
+      T createResource(String string) throws Exception;
+   }
+
+   private static final ResourceCreator<URL> URL_CREATOR = new ResourceCreator<URL>()
+   {
+      public URL getResource(VirtualFile file) throws Exception
+      {
+         return file.toURL();
+      }
+
+      public String getString(URL resource)
+      {
+         return resource.toExternalForm();
+      }
+
+      public URL createResource(String string) throws Exception
+      {
+         return new URL(string);
+      }
+   };
+
+   private static final ResourceCreator<URI> URI_CREATOR = new ResourceCreator<URI>()
+   {
+      public URI getResource(VirtualFile file) throws Exception
+      {
+         return file.toURI();
+      }
+
+      public String getString(URI resource)
+      {
+         return resource.toString();
+      }
+
+      public URI createResource(String string) throws Exception
+      {
+         return new URI(string);
+      }
+   };
+}

Copied: projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/plugins/cache (from rev 80461, projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/cache)

Deleted: projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileURLConnection.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileURLConnection.java	2008-10-20 08:32:12 UTC (rev 79734)
+++ projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileURLConnection.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -1,153 +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.plugins.vfs;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Collections;
-import java.util.Map;
-
-import org.jboss.util.collection.SoftValueHashMap;
-import org.jboss.virtual.VFS;
-import org.jboss.virtual.VirtualFile;
-
-/**
- * Implements basic URLConnection for a VirtualFile
- *
- * @author <a href="bill at jboss.com">Bill Burke</a>
- * @author <a href="ales.justin at jboss.com">Ales Justin</a>
- * @version $Revision: 1.1 $
- */
-public class VirtualFileURLConnection extends URLConnection
-{
-   @SuppressWarnings("unchecked")
-   public static Map<URL, VFS> urlCache = Collections.<URL, VFS>synchronizedMap(new SoftValueHashMap());
-
-   protected VirtualFile file;
-   protected URL vfsurl;
-   protected String relativePath;
-
-   public VirtualFileURLConnection(URL url, URL vfsurl, String relativePath)
-   {
-      super(url);
-      this.vfsurl = vfsurl;
-      this.relativePath = relativePath;
-   }
-
-   public VirtualFileURLConnection(URL url, VirtualFile file)
-   {
-      super(url);
-      this.file = file;
-   }
-
-   public void connect() throws IOException
-   {
-   }
-
-   public VirtualFile getContent() throws IOException
-   {
-      return getVirtualFile();
-   }
-
-   public int getContentLength()
-   {
-      try
-      {
-         return (int)getVirtualFile().getSize();
-      }
-      catch (IOException e)
-      {
-         throw new RuntimeException(e);
-      }
-   }
-
-   public long getLastModified()
-   {
-      try
-      {
-         return getVirtualFile().getLastModified();
-      }
-      catch (IOException e)
-      {
-         throw new RuntimeException(e);
-      }
-   }
-
-   public InputStream getInputStream() throws IOException
-   {
-      return getVirtualFile().openStream();
-   }
-
-   @SuppressWarnings("deprecation")
-   protected static VirtualFile resolveCachedVirtualFile(URL vfsurl, String relativePath) throws IOException
-   {
-      VFS vfs = urlCache.get(vfsurl);
-      if (vfs == null)
-      {
-         vfs = VFS.getVFS(vfsurl);
-         urlCache.put(vfsurl, vfs);
-      }
-      else
-      {
-         // if the root of VFS has changed on disk, lets purge it
-         // this is important for Jar files as we don't want stale jars as the
-         // root of the VFS (i.e., on redeployment)
-         if (vfs.getRoot().hasBeenModified())
-         {
-            vfs = VFS.getVFS(vfsurl);
-            urlCache.put(vfsurl, vfs);
-         }
-      }
-      return vfs.findChild(relativePath);
-   }
-
-   @SuppressWarnings("deprecation")
-   protected static VirtualFile resolveVirtualFile(URL vfsurl, String relativePath) throws IOException
-   {
-      VFS vfs = VFS.getVFS(vfsurl);
-      return vfs.findChild(relativePath);
-   }
-
-   /**
-    * Get the virtual file.
-    *
-    * @return the underlying virtual file
-    * @throws IOException for any error
-    */
-   protected synchronized VirtualFile getVirtualFile() throws IOException
-   {
-      if (file == null)
-      {
-         if (getUseCaches())
-         {
-            file = resolveCachedVirtualFile(vfsurl, relativePath);
-         }
-         else
-         {
-            file = resolveVirtualFile(vfsurl, relativePath);
-         }
-      }
-      return file;
-   }
-}

Copied: projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileURLConnection.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileURLConnection.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileURLConnection.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/plugins/vfs/VirtualFileURLConnection.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,122 @@
+/*
+* 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.plugins.vfs;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+
+/**
+ * Implements basic URLConnection for a VirtualFile
+ *
+ * @author <a href="bill at jboss.com">Bill Burke</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @version $Revision: 1.1 $
+ */
+public class VirtualFileURLConnection extends URLConnection
+{
+   protected VirtualFile file;
+   protected URL vfsurl;
+   protected String relativePath;
+
+   public VirtualFileURLConnection(URL url, URL vfsurl, String relativePath)
+   {
+      super(url);
+      this.vfsurl = vfsurl;
+      this.relativePath = relativePath;
+   }
+
+   public VirtualFileURLConnection(URL url, VirtualFile file)
+   {
+      super(url);
+      this.file = file;
+   }
+
+   public void connect() throws IOException
+   {
+   }
+
+   public VirtualFile getContent() throws IOException
+   {
+      return getVirtualFile();
+   }
+
+   public int getContentLength()
+   {
+      try
+      {
+         return (int)getVirtualFile().getSize();
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   public long getLastModified()
+   {
+      try
+      {
+         return getVirtualFile().getLastModified();
+      }
+      catch (IOException e)
+      {
+         throw new RuntimeException(e);
+      }
+   }
+
+   public InputStream getInputStream() throws IOException
+   {
+      return getVirtualFile().openStream();
+   }
+
+   @SuppressWarnings("deprecation")
+   protected static VirtualFile resolveCachedVirtualFile(URL vfsurl, String relativePath) throws IOException
+   {
+      return resolveVirtualFile(vfsurl, relativePath);
+   }
+
+   @SuppressWarnings("deprecation")
+   protected static VirtualFile resolveVirtualFile(URL vfsurl, String relativePath) throws IOException
+   {
+      VirtualFile file = VFS.getCachedFile(vfsurl);
+      return file.findChild(relativePath);
+   }
+
+   /**
+    * Get the virtual file.
+    *
+    * @return the underlying virtual file
+    * @throws IOException for any error
+    */
+   protected synchronized VirtualFile getVirtualFile() throws IOException
+   {
+      if (file == null)
+         file = resolveVirtualFile(vfsurl, relativePath);
+      
+      return file;
+   }
+}

Copied: projects/vfs/tags/2.0.0.CR2/src/main/java/org/jboss/virtual/spi/cache (from rev 80461, projects/vfs/branches/Branch_2_0/src/main/java/org/jboss/virtual/spi/cache)

Deleted: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/AbstractVFSTest.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/AbstractVFSTest.java	2008-10-20 08:32:12 UTC (rev 79734)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/AbstractVFSTest.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -1,136 +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.test.virtual.test;
-
-import java.net.URL;
-
-import junit.framework.AssertionFailedError;
-import org.jboss.test.BaseTestCase;
-import org.jboss.test.virtual.support.FileOAContextFactory;
-import org.jboss.test.virtual.support.JarOAContextFactory;
-import org.jboss.test.virtual.support.OptionsAwareURI;
-import org.jboss.virtual.VFSUtils;
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.spi.VFSContextFactory;
-import org.jboss.virtual.spi.VFSContextFactoryLocator;
-
-/**
- * AbstractVFSTest.
- * 
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @version $Revision: 1.1 $
- */
-public abstract class AbstractVFSTest extends BaseTestCase
-{
-   private static final VFSContextFactory fileFactory = new FileOAContextFactory();
-   private static final VFSContextFactory jarFactory = new JarOAContextFactory();
-
-   private boolean forceCopy;
-   private boolean forceNoReaper;
-
-   public AbstractVFSTest(String name)
-   {
-      super(name);
-   }
-
-   public AbstractVFSTest(String name, boolean forceCopy)
-   {
-      super(name);
-      this.forceCopy = forceCopy;
-   }
-
-   public AbstractVFSTest(String name, boolean forceCopy, boolean forceNoReaper)
-   {
-      super(name);
-      this.forceCopy = forceCopy;
-      this.forceNoReaper = forceNoReaper;
-   }
-
-   protected void setUp() throws Exception
-   {
-      super.setUp();
-
-      VFSContextFactoryLocator.registerFactory(fileFactory);
-      VFSContextFactoryLocator.registerFactory(jarFactory);
-
-      getLog().info("Force copy: " + forceCopy);
-      if (forceCopy)
-         OptionsAwareURI.set(OptionsAwareURI.Copy);
-
-      if (forceNoReaper)
-         OptionsAwareURI.set(OptionsAwareURI.NoReaper);
-   }
-
-   protected void tearDown() throws Exception
-   {
-      VFSContextFactoryLocator.unregisterFactory(jarFactory);
-      VFSContextFactoryLocator.unregisterFactory(fileFactory);
-
-      if (forceCopy)
-         OptionsAwareURI.clear(OptionsAwareURI.Copy);
-
-      if (forceNoReaper)
-         OptionsAwareURI.clear(OptionsAwareURI.NoReaper);
-
-      super.tearDown();
-   }
-
-   // TODO move to AbstractTestCase
-   public URL getResource(String name)
-   {
-      URL url = super.getResource(name);
-      assertNotNull("Resource not found: " + name, url);
-      return url;
-   }
-
-   protected <T> void checkThrowableTemp(Class<T> expected, Throwable throwable)
-   {
-      if (expected == null)
-         fail("Must provide an expected class");
-      if (throwable == null)
-         fail("Must provide a throwable for comparison");
-      if (throwable instanceof AssertionFailedError || throwable instanceof AssertionError)
-         throw (Error) throwable;
-      // TODO move to AbstractTestCase if (expected.equals(throwable.getClass()) == false)
-      if (expected.isAssignableFrom(throwable.getClass()) == false)
-      {
-         getLog().error("Unexpected throwable", throwable);
-         fail("Unexpected throwable: " + throwable);
-      }
-      else
-      {
-         getLog().debug("Got expected " + expected.getName() + "(" + throwable + ")");
-      }
-   }
-
-   /**
-    * Do we force copy handling of jars.
-    *
-    * @param file the virtual file
-    * @return true if we force copy handling
-    */
-   protected boolean isForceCopyEnabled(VirtualFile file)
-   {
-      boolean systemProperty = Boolean.parseBoolean(System.getProperty(VFSUtils.FORCE_COPY_KEY, "false"));
-      return systemProperty || VFSUtils.getOption(file, VFSUtils.FORCE_COPY_KEY) != null;
-   }
-}

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/AbstractVFSTest.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/AbstractVFSTest.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/AbstractVFSTest.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/AbstractVFSTest.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,148 @@
+/*
+* 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.test.virtual.test;
+
+import java.net.URL;
+
+import junit.framework.AssertionFailedError;
+import org.jboss.test.BaseTestCase;
+import org.jboss.test.virtual.support.FileOAContextFactory;
+import org.jboss.test.virtual.support.JarOAContextFactory;
+import org.jboss.test.virtual.support.OptionsAwareURI;
+import org.jboss.virtual.VFSUtils;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.spi.VFSContextFactory;
+import org.jboss.virtual.spi.VFSContextFactoryLocator;
+
+/**
+ * AbstractVFSTest.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractVFSTest extends BaseTestCase
+{
+   private static final VFSContextFactory fileFactory = new FileOAContextFactory();
+   private static final VFSContextFactory jarFactory = new JarOAContextFactory();
+
+   private boolean forceCopy;
+   private boolean forceNoReaper;
+
+   public AbstractVFSTest(String name)
+   {
+      super(name);
+   }
+
+   public AbstractVFSTest(String name, boolean forceCopy)
+   {
+      super(name);
+      this.forceCopy = forceCopy;
+   }
+
+   public AbstractVFSTest(String name, boolean forceCopy, boolean forceNoReaper)
+   {
+      super(name);
+      this.forceCopy = forceCopy;
+      this.forceNoReaper = forceNoReaper;
+   }
+
+   protected void setUp() throws Exception
+   {
+      super.setUp();
+
+/*
+      // LRU
+      System.setProperty(VFSUtils.VFS_CACHE_KEY, LRUVFSCache.class.getName());
+      System.setProperty(VFSUtils.VFS_CACHE_KEY + ".LRUPolicyCaching.min", "2");
+      System.setProperty(VFSUtils.VFS_CACHE_KEY + ".LRUPolicyCaching.max", "100");
+*/
+/*
+      // Timed
+      System.setProperty(VFSUtils.VFS_CACHE_KEY, TimedVFSCache.class.getName());
+      System.setProperty(VFSUtils.VFS_CACHE_KEY + ".TimedPolicyCaching.lifetime", "60");
+*/
+
+      VFSContextFactoryLocator.registerFactory(fileFactory);
+      VFSContextFactoryLocator.registerFactory(jarFactory);
+
+      getLog().info("Force copy: " + forceCopy);
+      if (forceCopy)
+         OptionsAwareURI.set(OptionsAwareURI.Copy);
+
+      if (forceNoReaper)
+         OptionsAwareURI.set(OptionsAwareURI.NoReaper);
+   }
+
+   protected void tearDown() throws Exception
+   {
+      VFSContextFactoryLocator.unregisterFactory(jarFactory);
+      VFSContextFactoryLocator.unregisterFactory(fileFactory);
+
+      if (forceCopy)
+         OptionsAwareURI.clear(OptionsAwareURI.Copy);
+
+      if (forceNoReaper)
+         OptionsAwareURI.clear(OptionsAwareURI.NoReaper);
+
+      super.tearDown();
+   }
+
+   // TODO move to AbstractTestCase
+   public URL getResource(String name)
+   {
+      URL url = super.getResource(name);
+      assertNotNull("Resource not found: " + name, url);
+      return url;
+   }
+
+   protected <T> void checkThrowableTemp(Class<T> expected, Throwable throwable)
+   {
+      if (expected == null)
+         fail("Must provide an expected class");
+      if (throwable == null)
+         fail("Must provide a throwable for comparison");
+      if (throwable instanceof AssertionFailedError || throwable instanceof AssertionError)
+         throw (Error) throwable;
+      // TODO move to AbstractTestCase if (expected.equals(throwable.getClass()) == false)
+      if (expected.isAssignableFrom(throwable.getClass()) == false)
+      {
+         getLog().error("Unexpected throwable", throwable);
+         fail("Unexpected throwable: " + throwable);
+      }
+      else
+      {
+         getLog().debug("Got expected " + expected.getName() + "(" + throwable + ")");
+      }
+   }
+
+   /**
+    * Do we force copy handling of jars.
+    *
+    * @param file the virtual file
+    * @return true if we force copy handling
+    */
+   protected boolean isForceCopyEnabled(VirtualFile file)
+   {
+      boolean systemProperty = Boolean.parseBoolean(System.getProperty(VFSUtils.FORCE_COPY_KEY, "false"));
+      return systemProperty || VFSUtils.getOption(file, VFSUtils.FORCE_COPY_KEY) != null;
+   }
+}

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/CachePolicyVFSCacheTest.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/CachePolicyVFSCacheTest.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/CachePolicyVFSCacheTest.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/CachePolicyVFSCacheTest.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,42 @@
+/*
+* 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.test.virtual.test;
+
+import org.jboss.virtual.spi.VFSContext;
+
+/**
+ * Map VFSCache Test.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public abstract class CachePolicyVFSCacheTest extends VFSCacheTest
+{
+   public CachePolicyVFSCacheTest(String name)
+   {
+      super(name);
+   }
+
+   protected void testCachedContexts(Iterable<VFSContext> iter)
+   {
+      assertFalse(iter.iterator().hasNext());
+   }
+}
\ No newline at end of file

Deleted: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	2008-10-20 08:32:12 UTC (rev 79734)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -1,1699 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2006, Red Hat Middleware LLC, and individual contributors
- * 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.test.virtual.test;
-
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.net.URI;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Properties;
-import java.util.jar.Attributes;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.JarOutputStream;
-import java.util.jar.Manifest;
-import java.util.zip.ZipInputStream;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import org.jboss.test.virtual.support.ClassPathIterator;
-import org.jboss.test.virtual.support.ClassPathIterator.ClassPathEntry;
-import org.jboss.test.virtual.support.MetaDataMatchFilter;
-import org.jboss.virtual.MemoryFileFactory;
-import org.jboss.virtual.VFS;
-import org.jboss.virtual.VFSUtils;
-import org.jboss.virtual.VirtualFile;
-import org.jboss.virtual.VisitorAttributes;
-import org.jboss.virtual.plugins.context.file.FileSystemContext;
-import org.jboss.virtual.plugins.context.jar.NestedJarFromStream;
-import org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter;
-import org.jboss.virtual.spi.LinkInfo;
-import org.jboss.virtual.spi.VFSContext;
-import org.jboss.virtual.spi.VFSContextFactory;
-import org.jboss.virtual.spi.VFSContextFactoryLocator;
-import org.jboss.virtual.spi.VirtualFileHandler;
-
-/**
- * Tests of the VFS implementation
- * 
- * @author Scott.Stark at jboss.org
- * @author adrian at jboss.org
- * @version $Revision: 55523 $
- */
-public class FileVFSUnitTestCase extends AbstractVFSTest
-{
-   public FileVFSUnitTestCase(String name)
-   {
-      super(name);
-   }
-   
-   protected FileVFSUnitTestCase(String name, boolean forceCopy)
-   {
-      super(name, forceCopy);
-   }
-
-   public static Test suite()
-   {
-      return new TestSuite(FileVFSUnitTestCase.class);
-   }
-
-   /**
-    * Test that a VFSContextFactory can be created from the testcase CodeSource url
-    * @throws Exception
-    */
-   public void testVFSContextFactory()
-      throws Exception
-   {
-      URL root = getClass().getProtectionDomain().getCodeSource().getLocation();
-      VFSContextFactory factory = VFSContextFactoryLocator.getFactory(root);
-      assertTrue("VFSContextFactory(CodeSource.Location) != null", factory != null);
-   }
-
-   /**
-    * Test that one can go from a file uri to VirtualFile and obtain the
-    * same VirtualFile using VirtualFile vfsfile uri
-    * @throws Exception
-    */
-   public void testVFSFileURIFactory()
-      throws Exception
-   {
-      URL rootURL = getClass().getProtectionDomain().getCodeSource().getLocation();
-      VFS rootVFS0 = VFS.getVFS(rootURL.toURI());
-      VirtualFile root0 = rootVFS0.getRoot();
-      VFS rootVFS1 = VFS.getVFS(root0.toURI());
-      VirtualFile root1 = rootVFS1.getRoot();
-      assertEquals(root0, root1);
-   }
-
-   /**
-    * Test that NestedJarFromStream can provide access to nested jar content
-    * @throws Exception
-    */
-   public void testNestedJarFromStream()
-      throws Exception
-   {
-      URL outer = getResource("/vfs/test/outer.jar");
-      String path = outer.getPath();
-      File outerJar = new File(path);
-      assertTrue(outerJar.getAbsolutePath()+" exists", outerJar.exists());
-      JarFile jf = new JarFile(outerJar);
-
-      URL rootURL = outerJar.getParentFile().toURL();
-      VFSContextFactory factory = VFSContextFactoryLocator.getFactory(rootURL);
-      VFSContext context = factory.getVFS(rootURL);
-
-      JarEntry jar1 = jf.getJarEntry("jar1.jar");
-      URL jar1URL = new URL(outerJar.toURL(), "jar1.jar");
-      VFSContextFactory pf1 = VFSContextFactoryLocator.getFactory(jar1URL);
-      VFSContext parent1 = pf1.getVFS(jar1URL);
-
-      ZipInputStream jis1 = new ZipInputStream(jf.getInputStream(jar1));
-      NestedJarFromStream njfs = new NestedJarFromStream(context, parent1.getRoot(), jis1, jar1URL, jf, jar1, "jar1.jar");
-      VirtualFileHandler e1 = njfs.getChild("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
-      assertNotNull(e1);
-      log.info("org/jboss/test/vfs/support/CommonClass.class: "+e1);
-      VirtualFileHandler mfe1 = njfs.getChild("META-INF/MANIFEST.MF");
-      assertNotNull("jar1!/META-INF/MANIFEST.MF", mfe1);
-      InputStream mfIS = mfe1.openStream();
-      Manifest mf = new Manifest(mfIS);
-      Attributes mainAttrs = mf.getMainAttributes();
-      String title1 = mainAttrs.getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals("jar1", title1);
-      mfIS.close();
-      njfs.close();
-
-      JarEntry jar2 = jf.getJarEntry("jar2.jar");
-      URL jar2URL = new URL(outerJar.toURL(), "jar2.jar");
-      VFSContextFactory pf2 = VFSContextFactoryLocator.getFactory(jar2URL);
-      VFSContext parent2 = pf2.getVFS(jar2URL);
-
-      ZipInputStream jis2 = new ZipInputStream(jf.getInputStream(jar2));
-      NestedJarFromStream njfs2 = new NestedJarFromStream(context, parent2.getRoot(), jis2, jar2URL, jf, jar2, "jar2.jar");
-      VirtualFileHandler e2 = njfs2.getChild("org/jboss/test/vfs/support/jar2/ClassInJar2.class");
-      assertNotNull(e2);
-      log.info("org/jboss/test/vfs/support/CommonClass.class: "+e2);
-      VirtualFileHandler mfe2 = njfs2.getChild("META-INF/MANIFEST.MF");
-      assertNotNull("jar2!/META-INF/MANIFEST.MF", mfe2);
-      InputStream mf2IS = mfe2.openStream();
-      Manifest mf2 = new Manifest(mf2IS);
-      Attributes mainAttrs2 = mf2.getMainAttributes();
-      String title2 = mainAttrs2.getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals("jar2", title2);
-      mf2IS.close();
-      njfs2.close();
-   }
-
-   /**
-    * Test reading the contents of nested jar entries.
-    * @throws Exception
-    */
-   public void testInnerJarFile()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile outerjar = vfs.findChild("outer.jar");
-      assertTrue("outer.jar != null", outerjar != null);
-      VirtualFile jar1 = outerjar.findChild("jar1.jar");
-      assertTrue("outer.jar/jar1.jar != null", jar1 != null);
-      VirtualFile jar2 = outerjar.findChild("jar2.jar");
-      assertTrue("outer.jar/jar2.jar != null", jar2 != null);
-
-      VirtualFile jar1MF = jar1.findChild("META-INF/MANIFEST.MF");
-      assertNotNull("jar1!/META-INF/MANIFEST.MF", jar1MF);
-      InputStream mfIS = jar1MF.openStream();
-      Manifest mf1 = new Manifest(mfIS);
-      Attributes mainAttrs1 = mf1.getMainAttributes();
-      String title1 = mainAttrs1.getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals("jar1", title1);
-      jar1MF.close();
-
-      VirtualFile jar2MF = jar2.findChild("META-INF/MANIFEST.MF");
-      assertNotNull("jar2!/META-INF/MANIFEST.MF", jar2MF);
-      InputStream mfIS2 = jar2MF.openStream();
-      Manifest mf2 = new Manifest(mfIS2);
-      Attributes mainAttrs2 = mf2.getMainAttributes();
-      String title2 = mainAttrs2.getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals("jar2", title2);
-      jar2MF.close();
-   }
-
-   /**
-    * Basic tests of accessing resources in a jar
-    * @throws Exception
-    */
-   public void testFindResource()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile jar = vfs.findChild("outer.jar");
-      assertTrue("outer.jar != null", jar != null);
-
-      /*
-      ArrayList<String> searchCtx = new ArrayList<String>();
-      searchCtx.add("outer.jar");
-      VirtualFile metaInf = vfs.resolveFile("META-INF/MANIFEST.MF", searchCtx);
-      */
-      VirtualFile metaInf = jar.findChild("META-INF/MANIFEST.MF");
-      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
-      InputStream mfIS = metaInf.openStream();
-      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
-      Manifest mf = new Manifest(mfIS);
-      Attributes mainAttrs = mf.getMainAttributes();
-      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
-      assertEquals("1.0.0.GA", version);
-      mfIS.close();
-   }
-
-   /**
-    * Basic tests of accessing resources in a jar
-    * @throws Exception
-    */
-   public void testFindResourceUsingURLStream()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile jar = vfs.findChild("outer.jar");
-      assertTrue("outer.jar != null", jar != null);
-
-      /*
-      ArrayList<String> searchCtx = new ArrayList<String>();
-      searchCtx.add("outer.jar");
-      VirtualFile metaInf = vfs.resolveFile("META-INF/MANIFEST.MF", searchCtx);
-      */
-      VirtualFile metaInf = jar.findChild("META-INF/MANIFEST.MF");
-      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
-      InputStream mfIS = metaInf.toURL().openStream();
-      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
-      Manifest mf = new Manifest(mfIS);
-      Attributes mainAttrs = mf.getMainAttributes();
-      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
-      assertEquals("1.0.0.GA", version);
-      mfIS.close();
-
-      String urlString = metaInf.toURL().toString();
-      URL mfURL = new URL(urlString);
-      mfIS = mfURL.openStream();
-      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
-      mf = new Manifest(mfIS);
-      mainAttrs = mf.getMainAttributes();
-      version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
-      assertEquals("1.0.0.GA", version);
-      mfIS.close();
-   }
-
-   /**
-    * Basic tests of accessing resources in a jar that does not
-    * have parent directory entries.
-    * @throws Exception
-    */
-   public void testFindResourceInFilesOnlyJar()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile jar = vfs.findChild("jar1-filesonly.jar");
-      assertTrue("jar1-filesonly.jar != null", jar != null);
-
-      VirtualFile metaInf = jar.findChild("META-INF/MANIFEST.MF");
-      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
-      InputStream mfIS = metaInf.toURL().openStream();
-      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
-      Manifest mf = new Manifest(mfIS);
-      Attributes mainAttrs = mf.getMainAttributes();
-      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
-      assertEquals("1.0.0.GA", version);
-      String title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals("jar1-filesonly", title);
-      mfIS.close();
-
-      String urlString = metaInf.toURL().toString();
-      URL mfURL = new URL(urlString);
-      mfIS = mfURL.openStream();
-      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
-      mf = new Manifest(mfIS);
-      mainAttrs = mf.getMainAttributes();
-      version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
-      assertEquals("1.0.0.GA", version);
-      title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals("jar1-filesonly", title);
-      mfIS.close();
-   }
-
-   /**
-    * Basic tests of accessing resources in a war that does not
-    * have parent directory entries.
-    * @throws Exception
-    */
-   public void testFindResourceInFilesOnlyWar()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      VirtualFile war2 = vfs.findChild("WarDeployApp_web.war");
-      assertTrue("WarDeployApp_web.war != null", war2 != null);
-
-      VirtualFile classes2 = war2.findChild("WEB-INF/classes");
-      assertTrue("WEB-INF/classes != null", classes2 != null);
-      assertTrue("WEB-INF/classes is not a leaf", classes2.isLeaf()==false);
-      classes2 = war2.findChild("WEB-INF/classes");
-      assertTrue("WEB-INF/classes != null", classes2 != null);
-      assertTrue("WEB-INF/classes is not a leaf", classes2.isLeaf()==false);
-
-      VirtualFile HelloJavaBean = classes2.findChild("com/sun/ts/tests/webservices/deploy/warDeploy/HelloJavaBean.class");
-      assertTrue("HelloJavaBean.class != null", HelloJavaBean != null);
-      assertTrue("HelloJavaBean.class is a leaf", HelloJavaBean.isLeaf());
-
-      VirtualFile war = vfs.findChild("filesonly.war");
-      assertTrue("filesonly.war != null", war != null);
-
-      VirtualFile classes = war.findChild("WEB-INF/classes");
-      assertTrue("WEB-INF/classes != null", classes != null);
-      assertTrue("WEB-INF/classes is not a leaf", classes.isLeaf()==false);
-
-      VirtualFile jar1 = war.findChild("WEB-INF/lib/jar1.jar");
-      assertTrue("WEB-INF/lib/jar1.jar != null", jar1 != null);
-      assertTrue("WEB-INF/lib/jar1.jar is not a leaf", jar1.isLeaf()==false);
-      VirtualFile ClassInJar1 = jar1.findChild("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
-      assertTrue("ClassInJar1.class != null", ClassInJar1 != null);
-      assertTrue("ClassInJar1.class is a leaf", ClassInJar1.isLeaf());
-
-      VirtualFile metaInf = war.findChild("META-INF/MANIFEST.MF");
-      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
-      InputStream mfIS = metaInf.toURL().openStream();
-      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
-      Manifest mf = new Manifest(mfIS);
-      Attributes mainAttrs = mf.getMainAttributes();
-      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
-      assertEquals("1.0.0.GA", version);
-      String title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals("filesonly-war", title);
-      mfIS.close();
-
-      war.findChild("WEB-INF/classes");
-      assertTrue("WEB-INF/classes != null", classes != null);
-      assertTrue("WEB-INF/classes is not a leaf", classes.isLeaf()==false);
-   }
-
-   /**
-    * Validate iterating over a vfs url from a files only war.
-    * 
-    * @throws Exception
-    */
-   public void testFindClassesInFilesOnlyWar()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      VirtualFile war = vfs.findChild("filesonly.war");
-      assertTrue("filesonly.war != null", war != null);
-
-      VirtualFile classes = war.findChild("WEB-INF/classes");
-      assertTrue("WEB-INF/classes != null", classes != null);
-      HashSet<String> names = new HashSet<String>();
-      ClassPathIterator iter = new ClassPathIterator(classes.toURL());
-      ClassPathEntry entry = null;
-      while( (entry = iter.getNextEntry()) != null )
-      {
-         names.add(entry.name);
-      }
-      log.debug(names);
-      assertTrue("org/jboss/test/vfs/support/jar1", names.contains("org/jboss/test/vfs/support/jar1"));
-      assertTrue("ClassInJar1.class", names.contains("org/jboss/test/vfs/support/jar1/ClassInJar1.class"));
-      assertTrue("ClassInJar1$InnerClass.class", names.contains("org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class"));
-   }
-
-   public void testFindResourceUnpackedJar()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile jar = vfs.findChild("unpacked-outer.jar");
-      assertTrue("unpacked-outer.jar != null", jar != null);
-
-      /**
-      ArrayList<String> searchCtx = new ArrayList<String>();
-      searchCtx.add("unpacked-outer.jar");
-      VirtualFile metaInf = vfs.resolveFile("META-INF/MANIFEST.MF", searchCtx);
-      */
-      VirtualFile metaInf = jar.findChild("META-INF/MANIFEST.MF");
-      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
-      InputStream mfIS = metaInf.openStream();
-      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
-      Manifest mf = new Manifest(mfIS);
-      Attributes mainAttrs = mf.getMainAttributes();
-      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
-      assertEquals("1.0.0.GA", version);
-      mfIS.close();
-   }
-
-   /**
-    * Test simple file resolution without search contexts
-    * @throws Exception
-    */
-   public void testResolveFile()
-      throws Exception
-   {
-      log.info("+++ testResolveFile, cwd="+(new File(".").getCanonicalPath()));
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      // Check resolving the root file
-      VirtualFile root = vfs.findChild("");
-      assertEquals("root name", "test", root.getName());
-      assertEquals("root path", "", root.getPathName());
-      assertFalse("root isDirectory", root.isLeaf());
-
-      // Find the outer.jar
-      VirtualFile outerJar = vfs.findChild("outer.jar");
-      assertNotNull("outer.jar", outerJar);
-      assertEquals("outer.jar name", "outer.jar", outerJar.getName());
-      assertEquals("outer.jar path", "outer.jar", outerJar.getPathName());
-      
-      VirtualFile outerJarMF = vfs.findChild("outer.jar/META-INF/MANIFEST.MF");
-      assertNotNull("outer.jar/META-INF/MANIFEST.MF", outerJarMF);
-
-      // Test a non-canonical path
-      rootURL = getResource("/vfs/sundry/../test");
-      // Check resolving the root file
-      root = vfs.findChild("");
-      assertEquals("root name", "test", root.getName());
-      assertEquals("root path", "", root.getPathName());
-      assertFalse("root isDirectory", root.isLeaf());
-   }
-
-   /**
-    * Validate resolving a .class file given a set of search contexts in the
-    * vfs that make up a classpath.
-    * 
-    * @throws Exception
-    */
-   public void testResolveClassFileInClassPath()
-      throws Exception
-   {
-      log.info("+++ testResolveFile, cwd="+(new File(".").getCanonicalPath()));
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      
-      // Find ClassInJar1.class
-      VirtualFile vf = vfs.findChild("jar1.jar");
-      VirtualFile c1 = vf.findChild("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
-      assertNotNull("ClassInJar1.class VF", c1);
-      log.debug("Found ClassInJar1.class: "+c1);
-
-      // Find ClassInJar1$InnerClass.class
-      VirtualFile c1i = vf.findChild("org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
-      assertNotNull("ClassInJar1$InnerClass.class VF", c1i);
-      log.debug("Found ClassInJar1$InnerClass.class: "+c1i);
-
-      // Find ClassInJar2.class
-      vf = vfs.findChild("jar2.jar");
-      VirtualFile c2 = vf.findChild("org/jboss/test/vfs/support/jar2/ClassInJar2.class");
-      assertNotNull("ClassInJar2.class VF", c2);
-      log.debug("Found ClassInJar2.class: "+c2);
-   }
-
-   public void testResolveFileInUnpackedJar()
-      throws Exception
-   {
-      log.info("+++ testResolveFileInUnpackedJar, cwd="+(new File(".").getCanonicalPath()));
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      // Check resolving the root file
-      VirtualFile root = vfs.findChild("");
-      assertEquals("root name", "test", root.getName());
-      assertEquals("root path", "", root.getPathName());
-      assertFalse("root isDirectory", root.isLeaf());
-
-      // Find the outer.jar
-      VirtualFile outerJar = vfs.findChild("unpacked-outer.jar");
-      assertNotNull("unpacked-outer.jar", outerJar);
-      assertEquals("unpacked-outer.jar name", "unpacked-outer.jar", outerJar.getName());
-      assertEquals("unpacked-outer.jar path", "unpacked-outer.jar", outerJar.getPathName());
-      
-      VirtualFile outerJarMF = vfs.findChild("unpacked-outer.jar/META-INF/MANIFEST.MF");
-      assertNotNull("unpacked-outer.jar/META-INF/MANIFEST.MF", outerJarMF);
-
-      // Check resolving the root file
-      root = vfs.findChild("");
-      assertEquals("root name", "test", root.getName());
-      assertEquals("root path", "", root.getPathName());
-      assertFalse("root isDirectory", root.isLeaf());
-   }
-
-   public void testFileNotFoundInUnpackedJar()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      // Find the outer.jar
-      VirtualFile outerJar = vfs.findChild("unpacked-outer.jar");
-      assertNotNull("unpacked-outer.jar", outerJar);
-      assertNull(outerJar.getChild("WEB-INF"));
-   }
-
-   public void testNestedNestedParent() throws Exception
-   {
-      // TODO
-   }
-
-   public void testCopyNestedStream() throws Exception
-   {
-      // TODO
-   }
-
-/*
-   public void testNoCopyNestedStream()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/seam/jboss-seam-booking.ear");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      VirtualFile clazz = vfs.getChild("lib/commons-beanutils.jar/org/apache/commons/beanutils/BeanComparator.class");
-      assertNotNull(clazz);
-      URL url = clazz.toURL();
-      InputStream is = url.openStream();
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      byte[] tmp = new byte[1024];
-      int read = 0;
-      while ( (read = is.read(tmp)) >= 0 )
-         baos.write(tmp, 0, read);
-      byte[] bytes = baos.toByteArray();
-      int size = bytes.length;
-      System.out.println("size = " + size);
-   }
-*/
-
-   /**
-    * Test file resolution with nested jars
-    * @throws Exception
-    */
-   public void testInnerJar()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile inner = vfs.findChild("outer.jar/jar1.jar");
-      log.info("IsFile: "+inner.isLeaf());
-      log.info(inner.getLastModified());
-      List<VirtualFile> contents = inner.getChildren();
-      // META-INF/*, org/jboss/test/vfs/support/jar1/* at least
-      assertTrue("jar1.jar children.length("+contents.size()+") >= 2", contents.size() >= 2);
-      for(VirtualFile vf : contents)
-      {
-         log.info("  "+vf.getName());
-      }
-      VirtualFile vf = vfs.findChild("outer.jar/jar1.jar");
-      VirtualFile jar1MF = vf.findChild("META-INF/MANIFEST.MF");
-      InputStream mfIS = jar1MF.openStream();
-      Manifest mf = new Manifest(mfIS);
-      Attributes mainAttrs = mf.getMainAttributes();
-      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1", version);
-      mfIS.close();
-   }
-
-   public void testInnerJarUsingURLStream()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile inner = vfs.findChild("outer.jar/jar1.jar");
-      log.info("IsFile: "+inner.isLeaf());
-      log.info(inner.getLastModified());
-      List<VirtualFile> contents = inner.getChildren();
-      // META-INF/*, org/jboss/test/vfs/support/jar1/* at least
-      assertTrue("jar1.jar children.length("+contents.size()+") >= 2", contents.size() >= 2);
-      for(VirtualFile vf : contents)
-      {
-         log.info("  "+vf.getName());
-      }
-      VirtualFile vf = vfs.findChild("outer.jar/jar1.jar");
-      VirtualFile jar1MF = vf.findChild("META-INF/MANIFEST.MF");
-      InputStream mfIS = jar1MF.toURL().openStream();
-      Manifest mf = new Manifest(mfIS);
-      Attributes mainAttrs = mf.getMainAttributes();
-      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1", version);
-      mfIS.close();
-   }
-
-   /**
-    * Test a scan of the outer.jar vfs to locate all .class files
-    * @throws Exception
-    */
-   public void testClassScan()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test/outer.jar");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      HashSet<String> expectedClasses = new HashSet<String>();
-      expectedClasses.add("jar1.jar/org/jboss/test/vfs/support/jar1/ClassInJar1.class");
-      expectedClasses.add("jar1.jar/org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
-      expectedClasses.add("jar1-filesonly.jar/org/jboss/test/vfs/support/jar1/ClassInJar1.class");
-      expectedClasses.add("jar1-filesonly.jar/org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
-      expectedClasses.add("jar2.jar/org/jboss/test/vfs/support/jar2/ClassInJar2.class");
-      expectedClasses.add("org/jboss/test/vfs/support/CommonClass.class");
-      super.enableTrace("org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter");
-      SuffixMatchFilter classVisitor = new SuffixMatchFilter(".class", VisitorAttributes.RECURSE);
-      List<VirtualFile> classes = vfs.getChildren(classVisitor);
-      int count = 0;
-      for (VirtualFile cf : classes)
-      {
-         String path = cf.getPathName();
-         if( path.endsWith(".class") )
-         {
-            assertTrue(path, expectedClasses.contains(path));
-            count ++;
-         }
-      }
-      assertEquals("There were 6 classes", 6, count);
-   }
-
-   /**
-    * Test a scan of the unpacked-outer.jar vfs to locate all .class files
-    * @throws Exception
-    */
-   public void testClassScanUnpacked()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test/unpacked-outer.jar");
-      VFS vfs = VFS.getVFS(rootURL);
-   
-      HashSet<String> expectedClasses = new HashSet<String>();
-      expectedClasses.add("jar1.jar/org/jboss/test/vfs/support/jar1/ClassInJar1.class");
-      expectedClasses.add("jar1.jar/org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
-      expectedClasses.add("jar2.jar/org/jboss/test/vfs/support/jar2/ClassInJar2.class");
-      // FIXME: .class files are not being copied from the resources directory
-      expectedClasses.add("org/jboss/test/vfs/support/CommonClass.class");
-      super.enableTrace("org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter");
-      SuffixMatchFilter classVisitor = new SuffixMatchFilter(".class", VisitorAttributes.RECURSE);
-      List<VirtualFile> classes = vfs.getChildren(classVisitor);
-      int count = 0;
-      for (VirtualFile cf : classes)
-      {
-         String path = cf.getPathName();
-         if( path.endsWith(".class") )
-         {
-            assertTrue(path, expectedClasses.contains(path));
-            count ++;
-         }
-      }
-      assertEquals("There were 4 classes", 4, count);
-   }
-
-   /**
-    * Test a scan of the jar1-filesonly.jar vfs to locate all .class files
-    * @throws Exception
-    */
-   public void testClassScanFilesonly()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test/jar1-filesonly.jar");
-      VFS vfs = VFS.getVFS(rootURL);
-   
-      HashSet<String> expectedClasses = new HashSet<String>();
-      expectedClasses.add("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
-      expectedClasses.add("org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
-      super.enableTrace("org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter");
-      SuffixMatchFilter classVisitor = new SuffixMatchFilter(".class", VisitorAttributes.RECURSE);
-      List<VirtualFile> classes = vfs.getChildren(classVisitor);
-      int count = 0;
-      for (VirtualFile cf : classes)
-      {
-         String path = cf.getPathName();
-         if( path.endsWith(".class") )
-         {
-            assertTrue(path, expectedClasses.contains(path));
-            count ++;
-         }
-      }
-      assertEquals("There were 2 classes", 2, count);
-
-      // Make sure we can walk path-wise to the class
-      VirtualFile parent = vfs.getRoot();
-      String className = "org/jboss/test/vfs/support/jar1/ClassInJar1.class";
-      VirtualFile classInJar1 = vfs.findChild(className);
-      String[] paths = className.split("/");
-      StringBuilder vfsPath = new StringBuilder();
-      for(String path : paths)
-      {
-         vfsPath.append(path);
-         VirtualFile vf = parent.findChild(path);
-         if( path.equals("ClassInJar1.class") )
-            assertEquals("ClassInJar1.class", classInJar1, vf);
-         else
-         {
-            assertEquals("vfsPath", vfsPath.toString(), vf.getPathName());
-            // why should this be equal?
-            // assertEquals("lastModified", classInJar1.getLastModified(), vf.getLastModified());
-            assertTrue("lastModified", classInJar1.getLastModified() <= vf.getLastModified());
-         }
-         vfsPath.append('/');
-         parent = vf;
-      }
-   }
-
-   /**
-    * Test access of directories in a jar that only stores files
-    * @throws Exception
-    */
-   public void testFilesOnlyJar()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      VirtualFile jar = vfs.findChild("jar1-filesonly.jar");
-      VirtualFile metadataLocation = jar.findChild("META-INF");
-      assertNotNull(metadataLocation);
-      VirtualFile mfFile = metadataLocation.findChild("MANIFEST.MF");
-      assertNotNull(mfFile);
-      InputStream is = mfFile.openStream();
-      Manifest mf = new Manifest(is);
-      mfFile.close();
-      String title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1-filesonly", title);
-
-      // Retry starting from the jar root
-      mfFile = jar.findChild("META-INF/MANIFEST.MF");
-      is = mfFile.openStream();
-      mf = new Manifest(is);
-      mfFile.close();
-      title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1-filesonly", title);
-   }
-
-   /**
-    * Test the serialization of VirtualFiles
-    * @throws Exception
-    */
-   public void testVFSerialization()
-      throws Exception
-   {
-      File tmpRoot = File.createTempFile("vfs", ".root");
-      tmpRoot.delete();
-      tmpRoot.mkdir();
-      tmpRoot.deleteOnExit();
-      File tmp = new File(tmpRoot, "vfs.ser");
-      tmp.createNewFile();
-      tmp.deleteOnExit();
-      log.info("+++ testVFSerialization, tmp="+tmp.getCanonicalPath());
-      URL rootURL = tmpRoot.toURL();
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile tmpVF = vfs.findChild("vfs.ser");
-      FileOutputStream fos = new FileOutputStream(tmp);
-      ObjectOutputStream oos = new ObjectOutputStream(fos);
-      oos.writeObject(tmpVF);
-      oos.close();
-
-      // Check the tmpVF attributes against the tmp file
-      long lastModified = tmp.lastModified();
-      long size = tmp.length();
-      String name = tmp.getName();
-      String vfsPath = tmp.getPath();
-      vfsPath = vfsPath.substring(tmpRoot.getPath().length()+1);
-      URL url = new URL("vfs" + tmp.toURL());
-      log.debug("name: "+name);
-      log.debug("vfsPath: "+vfsPath);
-      log.debug("url: "+url);
-      log.debug("lastModified: "+lastModified);
-      log.debug("size: "+size);
-      assertEquals("name", name, tmpVF.getName());
-      assertEquals("pathName", vfsPath, tmpVF.getPathName());
-      assertEquals("lastModified", lastModified, tmpVF.getLastModified());
-      assertEquals("size", size, tmpVF.getSize());
-      assertEquals("url", url, tmpVF.toURL());
-      assertEquals("isLeaf", true, tmpVF.isLeaf());
-      assertEquals("isHidden", false, tmpVF.isHidden());
-
-      // Read in the VF from the serialized file
-      FileInputStream fis = new FileInputStream(tmp);
-      ObjectInputStream ois = new ObjectInputStream(fis);
-      VirtualFile tmpVF2 = (VirtualFile) ois.readObject();
-      ois.close();
-      // Validated the deserialized attribtes against the tmp file
-      assertEquals("name", name, tmpVF2.getName());
-      assertEquals("pathName", vfsPath, tmpVF2.getPathName());
-      assertEquals("lastModified", lastModified, tmpVF2.getLastModified());
-      assertEquals("size", size, tmpVF2.getSize());
-      assertEquals("url", url, tmpVF2.toURL());
-      assertEquals("isLeaf", true, tmpVF2.isLeaf());
-      assertEquals("isHidden", false, tmpVF2.isHidden());
-   }
-
-   /**
-    * Test the serialization of VirtualFiles representing a jar
-    * @throws Exception
-    */
-   public void testVFJarSerialization()
-      throws Exception
-   {
-      File tmpRoot = File.createTempFile("vfs", ".root");
-      tmpRoot.delete();
-      tmpRoot.mkdir();
-      tmpRoot.deleteOnExit();
-      // Create a test jar containing a txt file
-      File tmpJar = new File(tmpRoot, "tst.jar");
-      tmpJar.createNewFile();
-      tmpJar.deleteOnExit();
-      FileOutputStream fos = new FileOutputStream(tmpJar);
-      JarOutputStream jos = new JarOutputStream(fos);
-      // Write a text file to include in a test jar
-      JarEntry txtEntry = new JarEntry("tst.txt");
-      jos.putNextEntry(txtEntry);
-      txtEntry.setSize("testVFJarSerialization".length());
-      txtEntry.setTime(System.currentTimeMillis());
-      jos.write("testVFJarSerialization".getBytes());
-      jos.close();
-      log.info("+++ testVFJarSerialization, tmp="+tmpJar.getCanonicalPath());
-
-      URI rootURI = tmpRoot.toURI();
-      VFS vfs = VFS.getVFS(rootURI);
-      File vfsSer = new File(tmpRoot, "vfs.ser");
-      vfsSer.createNewFile();
-      vfsSer.deleteOnExit();
-
-      VirtualFile tmpVF = vfs.findChild("tst.jar");
-      // Validate the vf jar against the tmp file attributes
-      long lastModified = tmpJar.lastModified();
-      long size = tmpJar.length();
-      String name = tmpJar.getName();
-      String vfsPath = tmpJar.getPath();
-      vfsPath = vfsPath.substring(tmpRoot.getPath().length()+1);
-      URL url = new URL("vfs" + tmpJar.toURL());
-      //url = JarUtils.createJarURL(url);
-      log.debug("name: "+name);
-      log.debug("vfsPath: "+vfsPath);
-      log.debug("url: "+url);
-      log.debug("lastModified: "+lastModified);
-      log.debug("size: "+size);
-      assertEquals("name", name, tmpVF.getName());
-      assertEquals("pathName", vfsPath, tmpVF.getPathName());
-      assertEquals("lastModified", lastModified, tmpVF.getLastModified());
-      assertEquals("size", size, tmpVF.getSize());
-      assertEquals("url", url.getPath(), tmpVF.toURL().getPath());
-      // TODO: these should pass
-      //assertEquals("isFile", true, tmpVF.isFile());
-      //assertEquals("isDirectory", false, tmpVF.isDirectory());
-      assertEquals("isHidden", false, tmpVF.isHidden());
-      // Write out the vfs jar file
-      fos = new FileOutputStream(vfsSer);
-      ObjectOutputStream oos = new ObjectOutputStream(fos);
-      oos.writeObject(tmpVF);
-      oos.close();
-
-      // Read in the VF from the serialized file
-      FileInputStream fis = new FileInputStream(vfsSer);
-      ObjectInputStream ois = new ObjectInputStream(fis);
-      VirtualFile tmpVF2 = (VirtualFile) ois.readObject();
-      ois.close();
-      // Validate the vf jar against the tmp file attributes
-      assertEquals("name", name, tmpVF2.getName());
-      assertEquals("pathName", vfsPath, tmpVF2.getPathName());
-      assertEquals("lastModified", lastModified, tmpVF2.getLastModified());
-      assertEquals("size", size, tmpVF2.getSize());
-      assertEquals("url", url.getPath(), tmpVF2.toURL().getPath());
-      // TODO: these should pass
-      //assertEquals("isFile", true, tmpVF2.isFile());
-      //assertEquals("isDirectory", false, tmpVF2.isDirectory());
-      assertEquals("isHidden", false, tmpVF2.isHidden());
-   }
-
-   /**
-    * Test the serialization of VirtualFiles representing a jar
-    * @throws Exception
-    */
-   public void testVFNestedJarSerialization()
-      throws Exception
-   {
-      // this expects to be run with a working dir of the container root
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile inner = vfs.findChild("outer.jar/jar1.jar");
-
-      File vfsSer = File.createTempFile("testVFNestedJarSerialization", ".ser");
-      vfsSer.deleteOnExit();
-      // Write out the vfs inner jar file
-      FileOutputStream fos = new FileOutputStream(vfsSer);
-      ObjectOutputStream oos = new ObjectOutputStream(fos);
-      oos.writeObject(inner);
-      oos.close();
-      
-      // Read in the VF from the serialized file
-      FileInputStream fis = new FileInputStream(vfsSer);
-      ObjectInputStream ois = new ObjectInputStream(fis);
-      inner = (VirtualFile) ois.readObject();
-      ois.close();
-      List<VirtualFile> contents = inner.getChildren();
-      // META-INF/*, org/jboss/test/vfs/support/jar1/* at least
-      // TODO - fix this once no_copy serialization is working
-      int size = isForceCopyEnabled(inner) ? 2 : 0;
-      assertTrue("jar1.jar children.length("+contents.size()+") is not " + size, contents.size() >= size);
-      for(VirtualFile vf : contents)
-      {
-         log.info("  "+vf.getName());
-      }
-      VirtualFile vf = vfs.findChild("outer.jar/jar1.jar");
-/*
-      VirtualFile jar1MF = vf.findChild("META-INF/MANIFEST.MF");
-      InputStream mfIS = jar1MF.openStream();
-      Manifest mf = new Manifest(mfIS);
-      Attributes mainAttrs = mf.getMainAttributes();
-      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_TITLE);
-      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1", version);
-      mfIS.close();
-*/
-   }
-
-   /**
-    * Test parsing of a vfs link properties file. It contains test.classes.url
-    * and test.lib.url system property references that are configured to
-    * point to the CodeSource location of this class and /vfs/sundry/jar/
-    * respectively.
-    * 
-    * @throws Exception
-    */
-   public void testVfsLinkProperties()
-      throws Exception
-   {
-      URL linkURL = super.getResource("/vfs/links/test-link.war.vfslink.properties");
-      assertNotNull("vfs/links/test-link.war.vfslink.properties", linkURL);
-      // Find resources to use as the WEB-INF/{classes,lib} link targets
-      URL classesURL = getClass().getProtectionDomain().getCodeSource().getLocation();
-      assertNotNull("classesURL", classesURL);
-      System.setProperty("test.classes.url", classesURL.toString());
-      URL libURL = super.getResource("/vfs/sundry/jar");
-      assertNotNull("libURL", libURL);      
-      System.setProperty("test.lib.url", libURL.toString());
-
-      assertTrue("isLink", VFSUtils.isLink(linkURL.getPath()));
-      Properties props = new Properties();
-      InputStream linkIS = linkURL.openStream();
-      List<LinkInfo> infos = VFSUtils.readLinkInfo(linkIS, linkURL.getPath(), props);
-      assertEquals("LinkInfo count", 2, infos.size());
-      LinkInfo classesInfo = null;
-      LinkInfo libInfo = null;
-      for(LinkInfo info :infos)
-      {
-         if( info.getName().equals("WEB-INF/classes") )
-            classesInfo = info;
-         else if(info.getName().equals("WEB-INF/lib") )
-            libInfo = info;
-      }
-      assertNotNull("classesInfo", classesInfo);
-      assertEquals("classesInfo.target", classesURL.toURI(), classesInfo.getLinkTarget());
-      assertNotNull("libInfo", libInfo);
-      assertEquals("libInfo.target", libURL.toURI(), libInfo.getLinkTarget());
-   }
-
-   /**
-    * Test the test-link.war link
-    * @throws Exception
-    */
-   public void testWarLink()
-      throws Exception
-   {
-      // Find resources to use as the WEB-INF/{classes,lib} link targets
-      URL classesURL = getClass().getProtectionDomain().getCodeSource().getLocation();
-      assertNotNull("classesURL", classesURL);
-      System.setProperty("test.classes.url", classesURL.toString());
-      URL libURL = super.getResource("/vfs/sundry/jar");
-      assertNotNull("libURL", libURL);      
-      System.setProperty("test.lib.url", libURL.toString());
-
-      // Root the vfs at the link file parent directory
-      URL linkURL = super.getResource("/vfs/links/test-link.war.vfslink.properties");
-      File linkFile = new File(linkURL.toURI());
-      File vfsRoot = linkFile.getParentFile();
-      assertNotNull("vfs/links/test-link.war.vfslink.properties", linkURL);
-      VFS vfs = VFS.getVFS(vfsRoot.toURI());
-
-      // We should find the test-link.war the link represents
-      VirtualFile war = vfs.findChild("test-link.war");
-      assertNotNull("war", war);
-
-      // Validate the WEB-INF/classes child link
-      VirtualFile classes = war.findChild("WEB-INF/classes");
-      String classesName = classes.getName();
-      String classesPathName = classes.getPathName();
-      boolean classesIsDirectory = classes.isLeaf() == false;
-      assertEquals("classes.name", "classes", classesName);
-      assertEquals("classes.pathName", "test-link.war/WEB-INF/classes", classesPathName);
-      assertEquals("classes.isDirectory", true, classesIsDirectory);
-      // Should be able to find this class since classes points to out codesource
-      VirtualFile thisClass = classes.findChild("org/jboss/test/virtual/test/FileVFSUnitTestCase.class");
-      assertEquals("FileVFSUnitTestCase.class", thisClass.getName());
-
-      // Validate the WEB-INF/lib child link
-      VirtualFile lib = war.findChild("WEB-INF/lib");
-      String libName = lib.getName();
-      String libPathName = lib.getPathName();
-      boolean libIsDirectory = lib.isLeaf() == false;
-      assertEquals("lib.name", "lib", libName);
-      assertEquals("lib.pathName", "test-link.war/WEB-INF/lib", libPathName);
-      assertEquals("lib.isDirectory", true, libIsDirectory);
-      // Should be able to find archive.jar under lib
-      VirtualFile archiveJar = lib.findChild("archive.jar");
-      assertEquals("archive.jar", archiveJar.getName());
-   }
-
-   /**
-    * Test configuration change detection on test-link.war link
-    * @throws Exception
-    */
-   public void testWarLinkUpdate()
-      throws Exception
-   {
-      // Setup the system properties used in test-link.war.vfslink.properties 
-      URL classesURL = getClass().getProtectionDomain().getCodeSource().getLocation();
-      assertNotNull("classesURL", classesURL);
-      System.setProperty("test.classes.url", classesURL.toString());
-      URL libURL = super.getResource("/vfs/sundry/jar");
-      assertNotNull("libURL", libURL);
-      System.setProperty("test.lib.url", libURL.toString());
-
-      // Root the vfs at the link file parent directory
-      URL linkURL = super.getResource("/vfs/links/test-link.war.vfslink.properties");
-      File linkFile = new File(linkURL.toURI());
-      assertNotNull("vfs/links/test-link.war.vfslink.properties", linkURL);
-
-      // Setup VFS root in a temp directory
-      File root = File.createTempFile("jboss-vfs-testWarLinkUpdate", ".tmp");
-      root.delete();
-      root.mkdir();
-      log.info("Using root: "+root);
-
-      // There should be no test-link.war under the new tmp root
-      VFS vfs = VFS.getVFS(root.toURI());
-      VirtualFile link = vfs.getChild("test-link.war");
-      assertNull("test-link.war", link);
-
-      // Add the link properties, now test-link.war should exist
-      File propsFile = new File(root, "test-link.war.vfslink.properties");
-      VFSUtils.copyStreamAndClose(new FileInputStream(linkFile), new FileOutputStream(propsFile));
-      link = vfs.getChild("test-link.war");
-      assertNotNull("test-link.war", link);
-
-      List<VirtualFile> children = link.getChildren();
-      assertEquals("test-link.war has 1 child", 1, children.size());
-      assertEquals("WEB-INF has 2 children", 2, children.get(0).getChildren().size());
-
-      // Sleep 1sec+ to allow timestamp changes in files to be > 1000ms, JBVFS-59
-      Thread.sleep(1005);
-
-      // modify properties file - add more children
-      URL dynamicClassRoot = new URL("vfsmemory", ".vfslink-test", "");
-      MemoryFileFactory.createRoot(dynamicClassRoot);
-
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-      PrintWriter webOut = new PrintWriter(new OutputStreamWriter(baos, "UTF-8"));
-      webOut.println("<?xml version=\"1.0\" ?>");
-      webOut.println("<web-app xmlns=\"http://java.sun.com/xml/ns/javaee\"\n" +
-         "         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
-         "         xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd\"\n" +
-         "         version=\"2.5\">");
-      webOut.println("</web-app>");
-      webOut.close();
-
-      MemoryFileFactory.putFile(dynamicClassRoot, baos.toByteArray());
-
-      PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(propsFile, true)));
-      out.println("vfs.link.name.2=WEB-INF/web.xml");
-      out.println("vfs.link.target.2=" + dynamicClassRoot.toExternalForm());
-      out.close();
-
-      Properties linkProps = new Properties();
-      InputStream propsIn = new FileInputStream(propsFile);
-      linkProps.load(propsIn);
-      assertEquals(1+3*2, linkProps.size());
-      assertEquals("vfs.link.name.0", "WEB-INF/classes", linkProps.getProperty("vfs.link.name.0"));
-      assertEquals("vfs.link.name.1", "WEB-INF/lib", linkProps.getProperty("vfs.link.name.1"));
-      assertEquals("vfs.link.name.2", "WEB-INF/web.xml", linkProps.getProperty("vfs.link.name.2"));
-      assertEquals("vfs.link.target.2", dynamicClassRoot.toExternalForm(), linkProps.getProperty("vfs.link.target.2"));
-      propsIn.close();
-
-      // You need to get a new reference to LinkHandler - to get up-to-date configuration
-      children = link.getChildren();
-      assertEquals("test-link.war has 1 child", 1, children.size());
-      log.info("WEB-INF children after update: "+children.get(0).getChildren());
-      assertEquals("WEB-INF has 3 children", 3, children.get(0).getChildren().size());
-
-      // Sleep 1sec+ to allow timestamp changes in files to be > 1000ms, JBVFS-59
-      Thread.sleep(1005);
-      // modify properties file - remove all but first
-      BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(propsFile)));
-      baos = new ByteArrayOutputStream();
-      out = new PrintWriter(new OutputStreamWriter(baos));
-      String line = in.readLine();
-      while(line != null)
-      {
-         if (line.indexOf(".0=") != -1)
-            out.println(line);
-         line = in.readLine();
-      }
-      out.close();
-      in.close();
-
-      FileOutputStream fos = new FileOutputStream(propsFile);
-      fos.write(baos.toByteArray());
-      fos.close();
-
-      children = link.getChildren();
-      assertEquals("test-link.war has 1 child", 1, children.size());
-      assertEquals("WEB-INF has 1 child", 1, children.get(0).getChildren().size());
-
-      // Sleep 1sec+ to allow timestamp changes in files to be > 1000ms, JBVFS-59
-      Thread.sleep(1005);
-      // modify properties file - remove all
-      fos = new FileOutputStream(propsFile);
-      fos.write(' ');
-      fos.close();
-
-      assertNotNull(link.getName() + " not null", link);
-      assertTrue(link.getName() + " exists()", link.exists());
-
-      children = link.getChildren();
-      assertTrue("Wrong number of children", children.size() == 0);
-
-      // remove properties file
-      assertTrue(propsFile.getName() + " delete()", propsFile.delete());
-
-      assertFalse(link.getName() + " exists() == false", link.exists());
-      VirtualFile oldLink = link;
-      link = vfs.getChild("test-link.war");
-      assertNull(oldLink.getName() + " is null", link);
-
-      children = vfs.getChildren();
-      assertTrue("Wrong number of children", children.size() == 0);
-
-      // put back .vfslink.properties
-      VFSUtils.copyStreamAndClose(new FileInputStream(linkFile), new FileOutputStream(propsFile));
-
-      assertTrue(oldLink.getName() + " exists()", oldLink.exists());
-      link = vfs.getChild("test-link.war");
-      assertNotNull("test-link.war", link);
-
-      children = link.getChildren();
-      assertTrue("Wrong number of children", children.size() == 1);
-      assertTrue("Wrong number of WEB-INF link children", children.get(0).getChildren().size() == 2);
-   }
-
-  /**
-    * Test that the URL of a VFS corresponding to a directory ends in '/' so that
-    * URLs created relative to it are under the directory. This requires that
-    * build-test.xml artifacts exist.
-    * 
-    * @throws Exception
-    */
-   public void testDirURLs() throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      VirtualFile outerJar = vfs.findChild("unpacked-outer.jar");
-      URL outerURL = outerJar.toURL();
-      log.debug("outerURL: "+outerURL);
-      assertTrue(outerURL+" ends in '/'", outerURL.getPath().endsWith("/"));
-      // Validate that jar1 is under unpacked-outer.jar
-      URL jar1URL = new URL(outerURL, "jar1.jar");
-      log.debug("jar1URL: "+jar1URL+", path="+jar1URL.getPath());
-      assertTrue("jar1URL path ends in unpacked-outer.jar/jar1.jar!/",
-            jar1URL.getPath().endsWith("unpacked-outer.jar/jar1.jar"));
-      VirtualFile jar1 = outerJar.findChild("jar1.jar");
-      assertEquals(jar1URL.getPath(), jar1.toURL().getPath());
-
-      VirtualFile packedJar = vfs.findChild("jar1.jar");
-      jar1URL = packedJar.findChild("org/jboss/test/vfs/support").toURL();
-      assertTrue("Jar directory entry URLs must end in /: " + jar1URL.toString(), jar1URL.toString().endsWith("/"));
-   }
-
-   /**
-    * Test that the URI of a VFS corresponding to a directory ends in '/' so that
-    * URIs created relative to it are under the directory. This requires that
-    * build-test.xml artifacts exist.
-    * 
-    * @throws Exception
-    */
-   public void testDirURIs() throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-
-      VirtualFile outerJar = vfs.findChild("unpacked-outer.jar");
-      URI outerURI = outerJar.toURI();
-      log.debug("outerURI: "+outerURI);
-      assertTrue(outerURI+" ends in '/'", outerURI.getPath().endsWith("/"));
-      // Validate that jar1 is under unpacked-outer.jar
-      URI jar1URI = new URI(outerURI+"jar1.jar");
-      log.debug("jar1URI: "+jar1URI+", path="+jar1URI.getPath());
-      assertTrue("jar1URI path ends in unpacked-outer.jar/jar1.jar!/",
-            jar1URI.getPath().endsWith("unpacked-outer.jar/jar1.jar"));
-      VirtualFile jar1 = outerJar.findChild("jar1.jar");
-      assertEquals(jar1URI.getPath(), jar1.toURI().getPath());
-
-      VirtualFile packedJar = vfs.findChild("jar1.jar");
-      jar1URI = packedJar.findChild("org/jboss/test/vfs/support").toURI();
-      assertTrue("Jar directory entry URLs must end in /: " + jar1URI.toString(),
-            jar1URI.toString().endsWith("/"));
-   }
-
-   /**
-    * Test copying a jar
-    * 
-    * @throws Exception
-    */
-   public void testCopyJar()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile jar = vfs.findChild("outer.jar");
-      assertTrue("outer.jar != null", jar != null);
-      File tmpJar = File.createTempFile("testCopyJar", ".jar");
-      tmpJar.deleteOnExit();
-
-      try
-      {
-         InputStream is = jar.openStream();
-         FileOutputStream fos = new FileOutputStream(tmpJar);
-         byte[] buffer = new byte[1024];
-         int read;
-         while( (read = is.read(buffer)) > 0 )
-         {
-            fos.write(buffer, 0, read);
-         }
-         fos.close();
-         log.debug("outer.jar size is: "+jar.getSize());
-         log.debug(tmpJar.getAbsolutePath()+" size is: "+tmpJar.length());
-         assertTrue("outer.jar > 0", jar.getSize() > 0);
-         assertEquals("copy jar size", jar.getSize(), tmpJar.length());
-         jar.close();
-      }
-      finally
-      {
-         try
-         {
-            tmpJar.delete();
-         }
-         catch(Exception ignore)
-         {
-         }
-      }
-   }
-
-   /**
-    * Test copying a jar that is nested in another jar.
-    * 
-    * @throws Exception
-    */
-   public void testCopyInnerJar()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile outerjar = vfs.findChild("outer.jar");
-      assertTrue("outer.jar != null", outerjar != null);
-      VirtualFile jar = outerjar.findChild("jar1.jar");
-      assertTrue("outer.jar/jar1.jar != null", jar != null);
-
-      File tmpJar = File.createTempFile("testCopyInnerJar", ".jar");
-      tmpJar.deleteOnExit();
-
-      try
-      {
-         InputStream is = jar.openStream();
-         FileOutputStream fos = new FileOutputStream(tmpJar);
-         byte[] buffer = new byte[1024];
-         int read;
-         while( (read = is.read(buffer)) > 0 )
-         {
-            fos.write(buffer, 0, read);
-         }
-         fos.close();
-         log.debug("outer.jar/jar1.jar size is: "+jar.getSize());
-         log.debug(tmpJar.getAbsolutePath()+" size is: "+tmpJar.length());
-         assertTrue("outer.jar > 0", jar.getSize() > 0);
-         assertEquals("copy jar size", jar.getSize(), tmpJar.length());
-         jar.close();
-      }
-      finally
-      {
-         try
-         {
-            tmpJar.delete();
-         }
-         catch(Exception ignore)
-         {
-         }
-      }
-   }
-
-   /**
-    * Test that the outermf.jar manifest classpath is parsed
-    * correctly.
-    * 
-    * @throws Exception
-    */
-   public void testManifestClasspath()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile outerjar = vfs.findChild("outermf.jar");
-      assertNotNull("outermf.jar != null", outerjar);
-
-      ArrayList<VirtualFile> cp = new ArrayList<VirtualFile>();
-      VFSUtils.addManifestLocations(outerjar, cp);
-      // The p0.jar should be found in the classpath
-      assertEquals("cp size 2", 2, cp.size());
-      assertEquals("jar1.jar == cp[0]", "jar1.jar", cp.get(0).getName());
-      assertEquals("jar2.jar == cp[1]", "jar2.jar", cp.get(1).getName());
-   }
-   /**
-    * Test that an inner-inner jar that is extracted does not blowup
-    * the addManifestLocations routine.
-    * 
-    * @throws Exception
-    */
-   public void testInnerManifestClasspath()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile outerjar = vfs.getChild("withalong/rootprefix/outermf.jar");
-      assertNotNull(outerjar);
-      VirtualFile jar1 = outerjar.getChild("jar1.jar");
-      assertNotNull(jar1);
-      VirtualFile jar2 = outerjar.getChild("jar2.jar");
-      assertNotNull(jar2);
-      VirtualFile innerjar = outerjar.getChild("innermf.jar");
-      assertNotNull("innermf.jar != null", innerjar);
-   
-      ArrayList<VirtualFile> cp = new ArrayList<VirtualFile>();
-      VFSUtils.addManifestLocations(innerjar, cp);
-      assertEquals(2, cp.size());
-      VirtualFile cp0 = cp.get(0);
-      assertEquals(jar1, cp0);
-      VirtualFile cp1 = cp.get(1);
-      assertEquals(jar2, cp1);
-   }
-
-   /**
-    * Validate accessing an packed jar vf and its uri when the vfs path
-    * contains spaces
-    * @throws Exception
-    */
-   public void testJarWithSpacesInPath()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile tstjar = vfs.findChild("path with spaces/tst.jar");
-      assertNotNull("tstjar != null", tstjar);
-      URI uri = tstjar.toURI();
-      URI expectedURI = new URI("vfs"+rootURL.toString()+"/path%20with%20spaces/tst.jar");
-      assertEquals(uri.getPath(), expectedURI.getPath());
-
-      InputStream is = uri.toURL().openStream();
-      is.close();
-
-      tstjar = vfs.findChild("path with spaces/tst%20nospace.jar");
-      assertNotNull("tstjar != null", tstjar);
-      uri = tstjar.toURI();
-      expectedURI = new URI("vfs"+rootURL.toString()+"/path%20with%20spaces/tst%2520nospace.jar");
-      assertEquals(uri.getPath(), expectedURI.getPath());
-
-      is = uri.toURL().openStream();
-      is.close();
-   }
-
-   public static void main(String[] args) throws Exception
-   {
-      File file = new File("C:\\Documents and Settings");
-      System.out.println(file.toURI());
-      System.out.println(file.toURL().getHost());
-      URI uri = new URI("file", null, "/Document and Settings", null);
-      System.out.println(uri);
-   }
-
-   /**
-    * Validate accessing an unpacked jar vf and its uri when the vfs path
-    * contains spaces
-    * @throws Exception
-    */
-   public void testUnpackedJarWithSpacesInPath()
-      throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile tstjar = vfs.findChild("path with spaces/unpacked-tst.jar");
-      assertNotNull("tstjar != null", tstjar);
-      URI uri = tstjar.toURI();
-      URI expectedURI = new URI("vfs" + rootURL.toString()+"/path%20with%20spaces/unpacked-tst.jar/");
-      assertEquals(uri, expectedURI);
-   }
-
-   /**
-    * Tests that we can find the META-INF/some-data.xml in an unpacked deployment
-    * 
-    * @throws Exception for any error
-    */
-   public void testGetMetaDataUnpackedJar() throws Exception
-   {
-      testGetMetaDataFromJar("unpacked-with-metadata.jar");
-   }
-   
-   /**
-    * Tests that we can find the META-INF/some-data.xml in a packed deployment
-    * 
-    * @throws Exception for any error
-    */
-   public void testGetMetaDataPackedJar() throws Exception
-   {
-      testGetMetaDataFromJar("with-metadata.jar");
-   }
-   
-   private void testGetMetaDataFromJar(String name) throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      
-      VirtualFile jar = vfs.findChild(name);
-      assertNotNull(jar);
-      VirtualFile metadataLocation = jar.findChild("META-INF");
-      assertNotNull(metadataLocation);
-
-      VirtualFile metadataByName = metadataLocation.findChild("some-data.xml");
-      assertNotNull(metadataByName);
-      
-      //This is the same code as is called by AbstractDeploymentContext.getMetaDataFiles(String name, String suffix). 
-      //The MetaDataMatchFilter is a copy of the one used there
-      List<VirtualFile> metaDataList = metadataLocation.getChildren(new MetaDataMatchFilter(null, "-data.xml"));
-      assertNotNull(metaDataList);
-      assertEquals("Wrong size", 1, metaDataList.size());
-   }
-
-   /**
-    * Validate that a URLClassLoader.findReource/getResourceAsStream calls for non-existing absolute
-    * resources that should fail as expected with null results. Related to JBMICROCONT-139.
-    * 
-    * @throws Exception
-    */
-   public void testURLClassLoaderFindResourceFailure() throws Exception
-   {
-      URL rootURL = getResource("/vfs/test");
-      VFS vfs = VFS.getVFS(rootURL);
-      URL[] cp = {vfs.getRoot().toURL()};
-      URLClassLoader ucl = new URLClassLoader(cp);
-      // Search for a non-existent absolute resource
-      URL qp = ucl.findResource("/nosuch-quartz.props");
-      assertNull("findResource(/nosuch-quartz.props)", qp);
-      InputStream is = ucl.getResourceAsStream("/nosuch-quartz.props");
-      assertNull("getResourceAsStream(/nosuch-quartz.props)", is);
-   }
-
-   /**
-    * Test VirtualFile.exists for vfsfile based urls.
-    * 
-    * @throws Exception
-    */
-   public void testFileExists()
-      throws Exception
-   {
-      File tmpRoot = File.createTempFile("vfs", ".root");
-      tmpRoot.delete();
-      tmpRoot.mkdir();
-      File tmp = File.createTempFile("testFileExists", null, tmpRoot);
-      log.info("+++ testFileExists, tmp="+tmp.getCanonicalPath());
-
-      URL rootURL = tmpRoot.toURL();
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile tmpVF = vfs.findChild(tmp.getName());
-      assertTrue(tmpVF.getPathName()+".exists()", tmpVF.exists());
-      assertTrue("tmp.delete()", tmpVF.delete());
-      assertFalse(tmpVF.getPathName()+".exists()", tmpVF.exists());
-      assertTrue(tmpRoot+".delete()", tmpRoot.delete());
-   }
-
-   /**
-    * Test VirtualFile.exists for vfsfile based urls for a directory.
-    * 
-    * @throws Exception
-    */
-   public void testDirFileExists()
-      throws Exception
-   {
-      File tmpRoot = File.createTempFile("vfs", ".root");
-      tmpRoot.delete();
-      tmpRoot.mkdir();
-      File tmp = File.createTempFile("testFileExists", null, tmpRoot);
-      assertTrue(tmp+".delete()", tmp.delete());
-      assertTrue(tmp+".mkdir()", tmp.mkdir());
-      log.info("+++ testDirFileExists, tmp="+tmp.getCanonicalPath());
-
-      URL rootURL = tmpRoot.toURL();
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile tmpVF = vfs.findChild(tmp.getName());
-      assertTrue(tmpVF.getPathName()+".exists()", tmpVF.exists());
-      assertFalse(tmpVF.getPathName()+".isLeaf()", tmpVF.isLeaf());
-      assertTrue(tmp+".delete()", tmp.delete());
-      assertFalse(tmpVF.getPathName()+".exists()", tmpVF.exists());
-      assertTrue(tmpRoot+".delete()", tmpRoot.delete());
-   }
-
-   /**
-    * Test VirtualFile.exists for vfsjar based urls.
-    * 
-    * @throws Exception
-    */
-   public void testJarExists()
-      throws Exception
-   {
-      File tmpRoot = File.createTempFile("vfs", ".root");
-      tmpRoot.delete();
-      tmpRoot.mkdir();
-      File tmpJar = File.createTempFile("testJarExists", ".jar", tmpRoot);
-      log.info("+++ testJarExists, tmpJar="+tmpJar.getCanonicalPath());
-      Manifest mf = new Manifest();
-      mf.getMainAttributes().putValue("Created-By", "FileVFSUnitTestCase.testJarExists");
-      FileOutputStream fos = new FileOutputStream(tmpJar);
-      JarOutputStream jos = new JarOutputStream(fos, mf);
-      jos.setComment("testJarExists");
-      jos.setLevel(0);
-      jos.close();
-
-      URL rootURL = tmpRoot.toURL();
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile tmpVF = vfs.findChild(tmpJar.getName());
-      assertTrue(tmpVF.getPathName()+".exists()", tmpVF.exists());
-      assertTrue(tmpVF.getPathName()+".size() > 0", tmpVF.getSize() > 0);
-      assertTrue("tmp.delete()", tmpVF.delete());
-      assertFalse(tmpVF.getPathName()+".exists()", tmpVF.exists());
-      assertTrue(tmpRoot+".delete()", tmpRoot.delete());
-   }
-
-   /**
-    * Test VirtualFile.exists for vfsjar based urls for a directory.
-    * 
-    * @throws Exception
-    */
-   public void testDirJarExists()
-      throws Exception
-   {
-      File tmpRoot = File.createTempFile("vfs", ".root");
-      tmpRoot.delete();
-      tmpRoot.mkdir();
-      File tmp = File.createTempFile("testDirJarExists", ".jar", tmpRoot);
-      assertTrue(tmp+".delete()", tmp.delete());
-      assertTrue(tmp+".mkdir()", tmp.mkdir());
-      log.info("+++ testDirJarExists, tmp="+tmp.getCanonicalPath());
-
-      URL rootURL = tmpRoot.toURL();
-      VFS vfs = VFS.getVFS(rootURL);
-      VirtualFile tmpVF = vfs.findChild(tmp.getName());
-      log.info(tmpVF);
-      assertTrue(tmpVF.getPathName()+".exists()", tmpVF.exists());
-      assertFalse(tmpVF.getPathName()+".isLeaf()", tmpVF.isLeaf());
-      assertTrue(tmp+".delete()", tmp.delete());
-      assertFalse(tmpVF.getPathName()+".exists()", tmpVF.exists());
-      assertTrue(tmpRoot+".delete()", tmpRoot.delete());
-   }
-
-   /**
-    * Test VirtualFile.delete() for file based urls
-    *
-    * @throws Exception
-    */
-   public void testFileDelete() throws Exception
-   {
-      File tmpRoot = File.createTempFile("vfs", ".root");
-      VFS vfs = VFS.getVFS(tmpRoot.toURL());
-
-      // non-existent directory - exists() not
-      tmpRoot.delete();
-      assertFalse(tmpRoot + ".exits() == false", vfs.getRoot().exists());
-
-      // existing directory - exists(), delete()
-      tmpRoot.mkdir();
-      assertTrue(tmpRoot + ".exits()", vfs.getRoot().exists());
-      assertTrue(tmpRoot + ".delete()", vfs.getRoot().delete());
-      tmpRoot.mkdir();
-
-      // non-empty directory - delete()
-      File tmp = new File(tmpRoot, "testFileDelete.jar");
-      assertTrue(tmp.mkdir());
-      File tmp2 = File.createTempFile("testFileDelete2", ".jar", tmp);
-      assertTrue(tmp2.exists());
-      VirtualFile tmpDeletable = VFS.getRoot(tmp.toURI());
-      assertTrue(tmpRoot + ".delete() == false", tmpDeletable.delete());
-
-      // create child to vfs
-      assertTrue(tmp.mkdir());
-      // children() exist
-      List<VirtualFile> children = vfs.getChildren();
-      assertTrue(tmpRoot + ".getChildren().size() == 1", children.size() == 1);
-
-      // specific child exists(), delete(), exists() not
-      VirtualFile tmpVF = vfs.getChild(tmp.getName());
-      assertTrue(tmp + ".exists()", tmpVF.exists());
-      assertTrue(tmp + ".delete()", tmpVF.delete());
-      assertFalse(tmp + ".exists() == false", tmpVF.exists());
-
-      // children() don't exist
-      children = vfs.getChildren();
-      assertTrue(tmpRoot + ".getChildren().size() == 0", children.size() == 0);
-
-      // getChild() returns null
-      tmpVF = vfs.getChild(tmp.getName());
-      assertNull(tmpRoot + ".getChild('" + tmp.getName() + "') == null", tmpVF);
-
-      // directory delete()
-      assertTrue(tmpRoot + ".delete()", vfs.getRoot().delete());
-   }
-
-   /**
-    * Test for <em>caseSensitive=true</em>
-    *
-    * If this test passes on unixes, it doesn't mean much, because there it should pass without
-    * case sensitivity turned on as well.
-    *
-    * If it passes on windows, it means the functionality works as expected.
-    *
-    * @throws Exception for any error
-    */
-   public void testCaseSensitive() throws Exception
-   {
-      URL rootURL = getResource("/vfs");
-
-      FileSystemContext ctx = new FileSystemContext(new URL(rootURL.toString() + "?caseSensitive=true"));
-      VirtualFileHandler root = ctx.getRoot();
-
-      String path = "context/file/simple/child";
-      VirtualFileHandler child = root.getChild(path);
-      assertTrue("getChild('" + path + "')", child != null);
-
-      path = "context/file/simple/CHILD";
-      child = root.getChild(path);
-      assertTrue("getChild('" + path + "')", child == null);
-
-      path = "context/jar/archive.jar";
-      child = root.getChild(path);
-      assertTrue("getChild('" + path + "')", child != null);
-
-      path = "context/JAR/archive.jar";
-      child = root.getChild(path);
-      assertTrue("getChild('" + path + "')", child == null);
-
-      path = "context/jar/archive.JAR";
-      child = root.getChild(path);
-      assertTrue("getChild('" + path + "')", child == null);
-
-      path = "context/jar/archive.jar/child";
-      child = root.getChild(path);
-      assertTrue("getChild('" + path + "')", child != null);
-
-      path = "context/jar/archive.jar/CHILD";
-      child = root.getChild(path);
-      assertTrue("getChild('" + path + "')", child == null);
-   }
-}

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/FileVFSUnitTestCase.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,1699 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * 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.test.virtual.test;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipInputStream;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.jboss.test.virtual.support.ClassPathIterator;
+import org.jboss.test.virtual.support.ClassPathIterator.ClassPathEntry;
+import org.jboss.test.virtual.support.MetaDataMatchFilter;
+import org.jboss.virtual.MemoryFileFactory;
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VFSUtils;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.VisitorAttributes;
+import org.jboss.virtual.plugins.context.file.FileSystemContext;
+import org.jboss.virtual.plugins.context.jar.NestedJarFromStream;
+import org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter;
+import org.jboss.virtual.spi.LinkInfo;
+import org.jboss.virtual.spi.VFSContext;
+import org.jboss.virtual.spi.VFSContextFactory;
+import org.jboss.virtual.spi.VFSContextFactoryLocator;
+import org.jboss.virtual.spi.VirtualFileHandler;
+
+/**
+ * Tests of the VFS implementation
+ * 
+ * @author Scott.Stark at jboss.org
+ * @author adrian at jboss.org
+ * @version $Revision: 55523 $
+ */
+public class FileVFSUnitTestCase extends AbstractVFSTest
+{
+   public FileVFSUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   protected FileVFSUnitTestCase(String name, boolean forceCopy)
+   {
+      super(name, forceCopy);
+   }
+
+   public static Test suite()
+   {
+      return new TestSuite(FileVFSUnitTestCase.class);
+   }
+
+   /**
+    * Test that a VFSContextFactory can be created from the testcase CodeSource url
+    * @throws Exception
+    */
+   public void testVFSContextFactory()
+      throws Exception
+   {
+      URL root = getClass().getProtectionDomain().getCodeSource().getLocation();
+      VFSContextFactory factory = VFSContextFactoryLocator.getFactory(root);
+      assertTrue("VFSContextFactory(CodeSource.Location) != null", factory != null);
+   }
+
+   /**
+    * Test that one can go from a file uri to VirtualFile and obtain the
+    * same VirtualFile using VirtualFile vfsfile uri
+    * @throws Exception
+    */
+   public void testVFSFileURIFactory()
+      throws Exception
+   {
+      URL rootURL = getClass().getProtectionDomain().getCodeSource().getLocation();
+      VFS rootVFS0 = VFS.getVFS(rootURL.toURI());
+      VirtualFile root0 = rootVFS0.getRoot();
+      VFS rootVFS1 = VFS.getVFS(root0.toURI());
+      VirtualFile root1 = rootVFS1.getRoot();
+      assertEquals(root0, root1);
+   }
+
+   /**
+    * Test that NestedJarFromStream can provide access to nested jar content
+    * @throws Exception
+    */
+   public void testNestedJarFromStream()
+      throws Exception
+   {
+      URL outer = getResource("/vfs/test/outer.jar");
+      String path = outer.getPath();
+      File outerJar = new File(path);
+      assertTrue(outerJar.getAbsolutePath()+" exists", outerJar.exists());
+      JarFile jf = new JarFile(outerJar);
+
+      URL rootURL = outerJar.getParentFile().toURL();
+      VFSContextFactory factory = VFSContextFactoryLocator.getFactory(rootURL);
+      VFSContext context = factory.getVFS(rootURL);
+
+      JarEntry jar1 = jf.getJarEntry("jar1.jar");
+      URL jar1URL = new URL(outerJar.toURL(), "jar1.jar");
+      VFSContextFactory pf1 = VFSContextFactoryLocator.getFactory(jar1URL);
+      VFSContext parent1 = pf1.getVFS(jar1URL);
+
+      ZipInputStream jis1 = new ZipInputStream(jf.getInputStream(jar1));
+      NestedJarFromStream njfs = new NestedJarFromStream(context, parent1.getRoot(), jis1, jar1URL, jf, jar1, "jar1.jar");
+      VirtualFileHandler e1 = njfs.getChild("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
+      assertNotNull(e1);
+      log.info("org/jboss/test/vfs/support/CommonClass.class: "+e1);
+      VirtualFileHandler mfe1 = njfs.getChild("META-INF/MANIFEST.MF");
+      assertNotNull("jar1!/META-INF/MANIFEST.MF", mfe1);
+      InputStream mfIS = mfe1.openStream();
+      Manifest mf = new Manifest(mfIS);
+      Attributes mainAttrs = mf.getMainAttributes();
+      String title1 = mainAttrs.getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals("jar1", title1);
+      mfIS.close();
+      njfs.close();
+
+      JarEntry jar2 = jf.getJarEntry("jar2.jar");
+      URL jar2URL = new URL(outerJar.toURL(), "jar2.jar");
+      VFSContextFactory pf2 = VFSContextFactoryLocator.getFactory(jar2URL);
+      VFSContext parent2 = pf2.getVFS(jar2URL);
+
+      ZipInputStream jis2 = new ZipInputStream(jf.getInputStream(jar2));
+      NestedJarFromStream njfs2 = new NestedJarFromStream(context, parent2.getRoot(), jis2, jar2URL, jf, jar2, "jar2.jar");
+      VirtualFileHandler e2 = njfs2.getChild("org/jboss/test/vfs/support/jar2/ClassInJar2.class");
+      assertNotNull(e2);
+      log.info("org/jboss/test/vfs/support/CommonClass.class: "+e2);
+      VirtualFileHandler mfe2 = njfs2.getChild("META-INF/MANIFEST.MF");
+      assertNotNull("jar2!/META-INF/MANIFEST.MF", mfe2);
+      InputStream mf2IS = mfe2.openStream();
+      Manifest mf2 = new Manifest(mf2IS);
+      Attributes mainAttrs2 = mf2.getMainAttributes();
+      String title2 = mainAttrs2.getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals("jar2", title2);
+      mf2IS.close();
+      njfs2.close();
+   }
+
+   /**
+    * Test reading the contents of nested jar entries.
+    * @throws Exception
+    */
+   public void testInnerJarFile()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile outerjar = vfs.findChild("outer.jar");
+      assertTrue("outer.jar != null", outerjar != null);
+      VirtualFile jar1 = outerjar.findChild("jar1.jar");
+      assertTrue("outer.jar/jar1.jar != null", jar1 != null);
+      VirtualFile jar2 = outerjar.findChild("jar2.jar");
+      assertTrue("outer.jar/jar2.jar != null", jar2 != null);
+
+      VirtualFile jar1MF = jar1.findChild("META-INF/MANIFEST.MF");
+      assertNotNull("jar1!/META-INF/MANIFEST.MF", jar1MF);
+      InputStream mfIS = jar1MF.openStream();
+      Manifest mf1 = new Manifest(mfIS);
+      Attributes mainAttrs1 = mf1.getMainAttributes();
+      String title1 = mainAttrs1.getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals("jar1", title1);
+      jar1MF.close();
+
+      VirtualFile jar2MF = jar2.findChild("META-INF/MANIFEST.MF");
+      assertNotNull("jar2!/META-INF/MANIFEST.MF", jar2MF);
+      InputStream mfIS2 = jar2MF.openStream();
+      Manifest mf2 = new Manifest(mfIS2);
+      Attributes mainAttrs2 = mf2.getMainAttributes();
+      String title2 = mainAttrs2.getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals("jar2", title2);
+      jar2MF.close();
+   }
+
+   /**
+    * Basic tests of accessing resources in a jar
+    * @throws Exception
+    */
+   public void testFindResource()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile jar = vfs.findChild("outer.jar");
+      assertTrue("outer.jar != null", jar != null);
+
+      /*
+      ArrayList<String> searchCtx = new ArrayList<String>();
+      searchCtx.add("outer.jar");
+      VirtualFile metaInf = vfs.resolveFile("META-INF/MANIFEST.MF", searchCtx);
+      */
+      VirtualFile metaInf = jar.findChild("META-INF/MANIFEST.MF");
+      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
+      InputStream mfIS = metaInf.openStream();
+      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
+      Manifest mf = new Manifest(mfIS);
+      Attributes mainAttrs = mf.getMainAttributes();
+      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
+      assertEquals("1.0.0.GA", version);
+      mfIS.close();
+   }
+
+   /**
+    * Basic tests of accessing resources in a jar
+    * @throws Exception
+    */
+   public void testFindResourceUsingURLStream()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile jar = vfs.findChild("outer.jar");
+      assertTrue("outer.jar != null", jar != null);
+
+      /*
+      ArrayList<String> searchCtx = new ArrayList<String>();
+      searchCtx.add("outer.jar");
+      VirtualFile metaInf = vfs.resolveFile("META-INF/MANIFEST.MF", searchCtx);
+      */
+      VirtualFile metaInf = jar.findChild("META-INF/MANIFEST.MF");
+      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
+      InputStream mfIS = metaInf.toURL().openStream();
+      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
+      Manifest mf = new Manifest(mfIS);
+      Attributes mainAttrs = mf.getMainAttributes();
+      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
+      assertEquals("1.0.0.GA", version);
+      mfIS.close();
+
+      String urlString = metaInf.toURL().toString();
+      URL mfURL = new URL(urlString);
+      mfIS = mfURL.openStream();
+      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
+      mf = new Manifest(mfIS);
+      mainAttrs = mf.getMainAttributes();
+      version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
+      assertEquals("1.0.0.GA", version);
+      mfIS.close();
+   }
+
+   /**
+    * Basic tests of accessing resources in a jar that does not
+    * have parent directory entries.
+    * @throws Exception
+    */
+   public void testFindResourceInFilesOnlyJar()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile jar = vfs.findChild("jar1-filesonly.jar");
+      assertTrue("jar1-filesonly.jar != null", jar != null);
+
+      VirtualFile metaInf = jar.findChild("META-INF/MANIFEST.MF");
+      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
+      InputStream mfIS = metaInf.toURL().openStream();
+      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
+      Manifest mf = new Manifest(mfIS);
+      Attributes mainAttrs = mf.getMainAttributes();
+      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
+      assertEquals("1.0.0.GA", version);
+      String title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals("jar1-filesonly", title);
+      mfIS.close();
+
+      String urlString = metaInf.toURL().toString();
+      URL mfURL = new URL(urlString);
+      mfIS = mfURL.openStream();
+      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
+      mf = new Manifest(mfIS);
+      mainAttrs = mf.getMainAttributes();
+      version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
+      assertEquals("1.0.0.GA", version);
+      title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals("jar1-filesonly", title);
+      mfIS.close();
+   }
+
+   /**
+    * Basic tests of accessing resources in a war that does not
+    * have parent directory entries.
+    * @throws Exception
+    */
+   public void testFindResourceInFilesOnlyWar()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      VirtualFile war2 = vfs.findChild("WarDeployApp_web.war");
+      assertTrue("WarDeployApp_web.war != null", war2 != null);
+
+      VirtualFile classes2 = war2.findChild("WEB-INF/classes");
+      assertTrue("WEB-INF/classes != null", classes2 != null);
+      assertTrue("WEB-INF/classes is not a leaf", classes2.isLeaf()==false);
+      classes2 = war2.findChild("WEB-INF/classes");
+      assertTrue("WEB-INF/classes != null", classes2 != null);
+      assertTrue("WEB-INF/classes is not a leaf", classes2.isLeaf()==false);
+
+      VirtualFile HelloJavaBean = classes2.findChild("com/sun/ts/tests/webservices/deploy/warDeploy/HelloJavaBean.class");
+      assertTrue("HelloJavaBean.class != null", HelloJavaBean != null);
+      assertTrue("HelloJavaBean.class is a leaf", HelloJavaBean.isLeaf());
+
+      VirtualFile war = vfs.findChild("filesonly.war");
+      assertTrue("filesonly.war != null", war != null);
+
+      VirtualFile classes = war.findChild("WEB-INF/classes");
+      assertTrue("WEB-INF/classes != null", classes != null);
+      assertTrue("WEB-INF/classes is not a leaf", classes.isLeaf()==false);
+
+      VirtualFile jar1 = war.findChild("WEB-INF/lib/jar1.jar");
+      assertTrue("WEB-INF/lib/jar1.jar != null", jar1 != null);
+      assertTrue("WEB-INF/lib/jar1.jar is not a leaf", jar1.isLeaf()==false);
+      VirtualFile ClassInJar1 = jar1.findChild("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
+      assertTrue("ClassInJar1.class != null", ClassInJar1 != null);
+      assertTrue("ClassInJar1.class is a leaf", ClassInJar1.isLeaf());
+
+      VirtualFile metaInf = war.findChild("META-INF/MANIFEST.MF");
+      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
+      InputStream mfIS = metaInf.toURL().openStream();
+      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
+      Manifest mf = new Manifest(mfIS);
+      Attributes mainAttrs = mf.getMainAttributes();
+      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
+      assertEquals("1.0.0.GA", version);
+      String title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals("filesonly-war", title);
+      mfIS.close();
+
+      war.findChild("WEB-INF/classes");
+      assertTrue("WEB-INF/classes != null", classes != null);
+      assertTrue("WEB-INF/classes is not a leaf", classes.isLeaf()==false);
+   }
+
+   /**
+    * Validate iterating over a vfs url from a files only war.
+    * 
+    * @throws Exception
+    */
+   public void testFindClassesInFilesOnlyWar()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      VirtualFile war = vfs.findChild("filesonly.war");
+      assertTrue("filesonly.war != null", war != null);
+
+      VirtualFile classes = war.findChild("WEB-INF/classes");
+      assertTrue("WEB-INF/classes != null", classes != null);
+      HashSet<String> names = new HashSet<String>();
+      ClassPathIterator iter = new ClassPathIterator(classes.toURL());
+      ClassPathEntry entry = null;
+      while( (entry = iter.getNextEntry()) != null )
+      {
+         names.add(entry.name);
+      }
+      log.debug(names);
+      assertTrue("org/jboss/test/vfs/support/jar1", names.contains("org/jboss/test/vfs/support/jar1"));
+      assertTrue("ClassInJar1.class", names.contains("org/jboss/test/vfs/support/jar1/ClassInJar1.class"));
+      assertTrue("ClassInJar1$InnerClass.class", names.contains("org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class"));
+   }
+
+   public void testFindResourceUnpackedJar()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile jar = vfs.findChild("unpacked-outer.jar");
+      assertTrue("unpacked-outer.jar != null", jar != null);
+
+      /**
+      ArrayList<String> searchCtx = new ArrayList<String>();
+      searchCtx.add("unpacked-outer.jar");
+      VirtualFile metaInf = vfs.resolveFile("META-INF/MANIFEST.MF", searchCtx);
+      */
+      VirtualFile metaInf = jar.findChild("META-INF/MANIFEST.MF");
+      assertTrue("META-INF/MANIFEST.MF != null", metaInf != null);
+      InputStream mfIS = metaInf.openStream();
+      assertTrue("META-INF/MANIFEST.MF.openStream != null", mfIS != null);
+      Manifest mf = new Manifest(mfIS);
+      Attributes mainAttrs = mf.getMainAttributes();
+      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_VERSION);
+      assertEquals("1.0.0.GA", version);
+      mfIS.close();
+   }
+
+   /**
+    * Test simple file resolution without search contexts
+    * @throws Exception
+    */
+   public void testResolveFile()
+      throws Exception
+   {
+      log.info("+++ testResolveFile, cwd="+(new File(".").getCanonicalPath()));
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      // Check resolving the root file
+      VirtualFile root = vfs.findChild("");
+      assertEquals("root name", "test", root.getName());
+      assertEquals("root path", "", root.getPathName());
+      assertFalse("root isDirectory", root.isLeaf());
+
+      // Find the outer.jar
+      VirtualFile outerJar = vfs.findChild("outer.jar");
+      assertNotNull("outer.jar", outerJar);
+      assertEquals("outer.jar name", "outer.jar", outerJar.getName());
+      assertEquals("outer.jar path", "outer.jar", outerJar.getPathName());
+      
+      VirtualFile outerJarMF = vfs.findChild("outer.jar/META-INF/MANIFEST.MF");
+      assertNotNull("outer.jar/META-INF/MANIFEST.MF", outerJarMF);
+
+      // Test a non-canonical path
+      rootURL = getResource("/vfs/sundry/../test");
+      // Check resolving the root file
+      root = vfs.findChild("");
+      assertEquals("root name", "test", root.getName());
+      assertEquals("root path", "", root.getPathName());
+      assertFalse("root isDirectory", root.isLeaf());
+   }
+
+   /**
+    * Validate resolving a .class file given a set of search contexts in the
+    * vfs that make up a classpath.
+    * 
+    * @throws Exception
+    */
+   public void testResolveClassFileInClassPath()
+      throws Exception
+   {
+      log.info("+++ testResolveFile, cwd="+(new File(".").getCanonicalPath()));
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      
+      // Find ClassInJar1.class
+      VirtualFile vf = vfs.findChild("jar1.jar");
+      VirtualFile c1 = vf.findChild("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
+      assertNotNull("ClassInJar1.class VF", c1);
+      log.debug("Found ClassInJar1.class: "+c1);
+
+      // Find ClassInJar1$InnerClass.class
+      VirtualFile c1i = vf.findChild("org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
+      assertNotNull("ClassInJar1$InnerClass.class VF", c1i);
+      log.debug("Found ClassInJar1$InnerClass.class: "+c1i);
+
+      // Find ClassInJar2.class
+      vf = vfs.findChild("jar2.jar");
+      VirtualFile c2 = vf.findChild("org/jboss/test/vfs/support/jar2/ClassInJar2.class");
+      assertNotNull("ClassInJar2.class VF", c2);
+      log.debug("Found ClassInJar2.class: "+c2);
+   }
+
+   public void testResolveFileInUnpackedJar()
+      throws Exception
+   {
+      log.info("+++ testResolveFileInUnpackedJar, cwd="+(new File(".").getCanonicalPath()));
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      // Check resolving the root file
+      VirtualFile root = vfs.findChild("");
+      assertEquals("root name", "test", root.getName());
+      assertEquals("root path", "", root.getPathName());
+      assertFalse("root isDirectory", root.isLeaf());
+
+      // Find the outer.jar
+      VirtualFile outerJar = vfs.findChild("unpacked-outer.jar");
+      assertNotNull("unpacked-outer.jar", outerJar);
+      assertEquals("unpacked-outer.jar name", "unpacked-outer.jar", outerJar.getName());
+      assertEquals("unpacked-outer.jar path", "unpacked-outer.jar", outerJar.getPathName());
+      
+      VirtualFile outerJarMF = vfs.findChild("unpacked-outer.jar/META-INF/MANIFEST.MF");
+      assertNotNull("unpacked-outer.jar/META-INF/MANIFEST.MF", outerJarMF);
+
+      // Check resolving the root file
+      root = vfs.findChild("");
+      assertEquals("root name", "test", root.getName());
+      assertEquals("root path", "", root.getPathName());
+      assertFalse("root isDirectory", root.isLeaf());
+   }
+
+   public void testFileNotFoundInUnpackedJar()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      // Find the outer.jar
+      VirtualFile outerJar = vfs.findChild("unpacked-outer.jar");
+      assertNotNull("unpacked-outer.jar", outerJar);
+      assertNull(outerJar.getChild("WEB-INF"));
+   }
+
+   public void testNestedNestedParent() throws Exception
+   {
+      // TODO
+   }
+
+   public void testCopyNestedStream() throws Exception
+   {
+      // TODO
+   }
+
+/*
+   public void testNoCopyNestedStream()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/seam/jboss-seam-booking.ear");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      VirtualFile clazz = vfs.getChild("lib/commons-beanutils.jar/org/apache/commons/beanutils/BeanComparator.class");
+      assertNotNull(clazz);
+      URL url = clazz.toURL();
+      InputStream is = url.openStream();
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      byte[] tmp = new byte[1024];
+      int read = 0;
+      while ( (read = is.read(tmp)) >= 0 )
+         baos.write(tmp, 0, read);
+      byte[] bytes = baos.toByteArray();
+      int size = bytes.length;
+      System.out.println("size = " + size);
+   }
+*/
+
+   /**
+    * Test file resolution with nested jars
+    * @throws Exception
+    */
+   public void testInnerJar()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile inner = vfs.findChild("outer.jar/jar1.jar");
+      log.info("IsFile: "+inner.isLeaf());
+      log.info(inner.getLastModified());
+      List<VirtualFile> contents = inner.getChildren();
+      // META-INF/*, org/jboss/test/vfs/support/jar1/* at least
+      assertTrue("jar1.jar children.length("+contents.size()+") >= 2", contents.size() >= 2);
+      for(VirtualFile vf : contents)
+      {
+         log.info("  "+vf.getName());
+      }
+      VirtualFile vf = vfs.findChild("outer.jar/jar1.jar");
+      VirtualFile jar1MF = vf.findChild("META-INF/MANIFEST.MF");
+      InputStream mfIS = jar1MF.openStream();
+      Manifest mf = new Manifest(mfIS);
+      Attributes mainAttrs = mf.getMainAttributes();
+      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1", version);
+      mfIS.close();
+   }
+
+   public void testInnerJarUsingURLStream()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile inner = vfs.findChild("outer.jar/jar1.jar");
+      log.info("IsFile: "+inner.isLeaf());
+      log.info(inner.getLastModified());
+      List<VirtualFile> contents = inner.getChildren();
+      // META-INF/*, org/jboss/test/vfs/support/jar1/* at least
+      assertTrue("jar1.jar children.length("+contents.size()+") >= 2", contents.size() >= 2);
+      for(VirtualFile vf : contents)
+      {
+         log.info("  "+vf.getName());
+      }
+      VirtualFile vf = vfs.findChild("outer.jar/jar1.jar");
+      VirtualFile jar1MF = vf.findChild("META-INF/MANIFEST.MF");
+      InputStream mfIS = jar1MF.toURL().openStream();
+      Manifest mf = new Manifest(mfIS);
+      Attributes mainAttrs = mf.getMainAttributes();
+      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1", version);
+      mfIS.close();
+   }
+
+   /**
+    * Test a scan of the outer.jar vfs to locate all .class files
+    * @throws Exception
+    */
+   public void testClassScan()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test/outer.jar");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      HashSet<String> expectedClasses = new HashSet<String>();
+      expectedClasses.add("jar1.jar/org/jboss/test/vfs/support/jar1/ClassInJar1.class");
+      expectedClasses.add("jar1.jar/org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
+      expectedClasses.add("jar1-filesonly.jar/org/jboss/test/vfs/support/jar1/ClassInJar1.class");
+      expectedClasses.add("jar1-filesonly.jar/org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
+      expectedClasses.add("jar2.jar/org/jboss/test/vfs/support/jar2/ClassInJar2.class");
+      expectedClasses.add("org/jboss/test/vfs/support/CommonClass.class");
+      super.enableTrace("org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter");
+      SuffixMatchFilter classVisitor = new SuffixMatchFilter(".class", VisitorAttributes.RECURSE);
+      List<VirtualFile> classes = vfs.getChildren(classVisitor);
+      int count = 0;
+      for (VirtualFile cf : classes)
+      {
+         String path = cf.getPathName();
+         if( path.endsWith(".class") )
+         {
+            assertTrue(path, expectedClasses.contains(path));
+            count ++;
+         }
+      }
+      assertEquals("There were 6 classes", 6, count);
+   }
+
+   /**
+    * Test a scan of the unpacked-outer.jar vfs to locate all .class files
+    * @throws Exception
+    */
+   public void testClassScanUnpacked()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test/unpacked-outer.jar");
+      VFS vfs = VFS.getVFS(rootURL);
+   
+      HashSet<String> expectedClasses = new HashSet<String>();
+      expectedClasses.add("jar1.jar/org/jboss/test/vfs/support/jar1/ClassInJar1.class");
+      expectedClasses.add("jar1.jar/org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
+      expectedClasses.add("jar2.jar/org/jboss/test/vfs/support/jar2/ClassInJar2.class");
+      // FIXME: .class files are not being copied from the resources directory
+      expectedClasses.add("org/jboss/test/vfs/support/CommonClass.class");
+      super.enableTrace("org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter");
+      SuffixMatchFilter classVisitor = new SuffixMatchFilter(".class", VisitorAttributes.RECURSE);
+      List<VirtualFile> classes = vfs.getChildren(classVisitor);
+      int count = 0;
+      for (VirtualFile cf : classes)
+      {
+         String path = cf.getPathName();
+         if( path.endsWith(".class") )
+         {
+            assertTrue(path, expectedClasses.contains(path));
+            count ++;
+         }
+      }
+      assertEquals("There were 4 classes", 4, count);
+   }
+
+   /**
+    * Test a scan of the jar1-filesonly.jar vfs to locate all .class files
+    * @throws Exception
+    */
+   public void testClassScanFilesonly()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test/jar1-filesonly.jar");
+      VFS vfs = VFS.getVFS(rootURL);
+   
+      HashSet<String> expectedClasses = new HashSet<String>();
+      expectedClasses.add("org/jboss/test/vfs/support/jar1/ClassInJar1.class");
+      expectedClasses.add("org/jboss/test/vfs/support/jar1/ClassInJar1$InnerClass.class");
+      super.enableTrace("org.jboss.virtual.plugins.vfs.helpers.SuffixMatchFilter");
+      SuffixMatchFilter classVisitor = new SuffixMatchFilter(".class", VisitorAttributes.RECURSE);
+      List<VirtualFile> classes = vfs.getChildren(classVisitor);
+      int count = 0;
+      for (VirtualFile cf : classes)
+      {
+         String path = cf.getPathName();
+         if( path.endsWith(".class") )
+         {
+            assertTrue(path, expectedClasses.contains(path));
+            count ++;
+         }
+      }
+      assertEquals("There were 2 classes", 2, count);
+
+      // Make sure we can walk path-wise to the class
+      VirtualFile parent = vfs.getRoot();
+      String className = "org/jboss/test/vfs/support/jar1/ClassInJar1.class";
+      VirtualFile classInJar1 = vfs.findChild(className);
+      String[] paths = className.split("/");
+      StringBuilder vfsPath = new StringBuilder();
+      for(String path : paths)
+      {
+         vfsPath.append(path);
+         VirtualFile vf = parent.findChild(path);
+         if( path.equals("ClassInJar1.class") )
+            assertEquals("ClassInJar1.class", classInJar1, vf);
+         else
+         {
+            assertEquals("vfsPath", vfsPath.toString(), vf.getPathName());
+            // why should this be equal?
+            // assertEquals("lastModified", classInJar1.getLastModified(), vf.getLastModified());
+            assertTrue("lastModified", classInJar1.getLastModified() <= vf.getLastModified());
+         }
+         vfsPath.append('/');
+         parent = vf;
+      }
+   }
+
+   /**
+    * Test access of directories in a jar that only stores files
+    * @throws Exception
+    */
+   public void testFilesOnlyJar()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      VirtualFile jar = vfs.findChild("jar1-filesonly.jar");
+      VirtualFile metadataLocation = jar.findChild("META-INF");
+      assertNotNull(metadataLocation);
+      VirtualFile mfFile = metadataLocation.findChild("MANIFEST.MF");
+      assertNotNull(mfFile);
+      InputStream is = mfFile.openStream();
+      Manifest mf = new Manifest(is);
+      mfFile.close();
+      String title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1-filesonly", title);
+
+      // Retry starting from the jar root
+      mfFile = jar.findChild("META-INF/MANIFEST.MF");
+      is = mfFile.openStream();
+      mf = new Manifest(is);
+      mfFile.close();
+      title = mf.getMainAttributes().getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1-filesonly", title);
+   }
+
+   /**
+    * Test the serialization of VirtualFiles
+    * @throws Exception
+    */
+   public void testVFSerialization()
+      throws Exception
+   {
+      File tmpRoot = File.createTempFile("vfs", ".root");
+      tmpRoot.delete();
+      tmpRoot.mkdir();
+      tmpRoot.deleteOnExit();
+      File tmp = new File(tmpRoot, "vfs.ser");
+      tmp.createNewFile();
+      tmp.deleteOnExit();
+      log.info("+++ testVFSerialization, tmp="+tmp.getCanonicalPath());
+      URL rootURL = tmpRoot.toURL();
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile tmpVF = vfs.findChild("vfs.ser");
+      FileOutputStream fos = new FileOutputStream(tmp);
+      ObjectOutputStream oos = new ObjectOutputStream(fos);
+      oos.writeObject(tmpVF);
+      oos.close();
+
+      // Check the tmpVF attributes against the tmp file
+      long lastModified = tmp.lastModified();
+      long size = tmp.length();
+      String name = tmp.getName();
+      String vfsPath = tmp.getPath();
+      vfsPath = vfsPath.substring(tmpRoot.getPath().length()+1);
+      URL url = new URL("vfs" + tmp.toURL());
+      log.debug("name: "+name);
+      log.debug("vfsPath: "+vfsPath);
+      log.debug("url: "+url);
+      log.debug("lastModified: "+lastModified);
+      log.debug("size: "+size);
+      assertEquals("name", name, tmpVF.getName());
+      assertEquals("pathName", vfsPath, tmpVF.getPathName());
+      assertEquals("lastModified", lastModified, tmpVF.getLastModified());
+      assertEquals("size", size, tmpVF.getSize());
+      assertEquals("url", url, tmpVF.toURL());
+      assertEquals("isLeaf", true, tmpVF.isLeaf());
+      assertEquals("isHidden", false, tmpVF.isHidden());
+
+      // Read in the VF from the serialized file
+      FileInputStream fis = new FileInputStream(tmp);
+      ObjectInputStream ois = new ObjectInputStream(fis);
+      VirtualFile tmpVF2 = (VirtualFile) ois.readObject();
+      ois.close();
+      // Validated the deserialized attribtes against the tmp file
+      assertEquals("name", name, tmpVF2.getName());
+      assertEquals("pathName", vfsPath, tmpVF2.getPathName());
+      assertEquals("lastModified", lastModified, tmpVF2.getLastModified());
+      assertEquals("size", size, tmpVF2.getSize());
+      assertEquals("url", url, tmpVF2.toURL());
+      assertEquals("isLeaf", true, tmpVF2.isLeaf());
+      assertEquals("isHidden", false, tmpVF2.isHidden());
+   }
+
+   /**
+    * Test the serialization of VirtualFiles representing a jar
+    * @throws Exception
+    */
+   public void testVFJarSerialization()
+      throws Exception
+   {
+      File tmpRoot = File.createTempFile("vfs", ".root");
+      tmpRoot.delete();
+      tmpRoot.mkdir();
+      tmpRoot.deleteOnExit();
+      // Create a test jar containing a txt file
+      File tmpJar = new File(tmpRoot, "tst.jar");
+      tmpJar.createNewFile();
+      tmpJar.deleteOnExit();
+      FileOutputStream fos = new FileOutputStream(tmpJar);
+      JarOutputStream jos = new JarOutputStream(fos);
+      // Write a text file to include in a test jar
+      JarEntry txtEntry = new JarEntry("tst.txt");
+      jos.putNextEntry(txtEntry);
+      txtEntry.setSize("testVFJarSerialization".length());
+      txtEntry.setTime(System.currentTimeMillis());
+      jos.write("testVFJarSerialization".getBytes());
+      jos.close();
+      log.info("+++ testVFJarSerialization, tmp="+tmpJar.getCanonicalPath());
+
+      URI rootURI = tmpRoot.toURI();
+      VFS vfs = VFS.getVFS(rootURI);
+      File vfsSer = new File(tmpRoot, "vfs.ser");
+      vfsSer.createNewFile();
+      vfsSer.deleteOnExit();
+
+      VirtualFile tmpVF = vfs.findChild("tst.jar");
+      // Validate the vf jar against the tmp file attributes
+      long lastModified = tmpJar.lastModified();
+      long size = tmpJar.length();
+      String name = tmpJar.getName();
+      String vfsPath = tmpJar.getPath();
+      vfsPath = vfsPath.substring(tmpRoot.getPath().length()+1);
+      URL url = new URL("vfs" + tmpJar.toURL());
+      //url = JarUtils.createJarURL(url);
+      log.debug("name: "+name);
+      log.debug("vfsPath: "+vfsPath);
+      log.debug("url: "+url);
+      log.debug("lastModified: "+lastModified);
+      log.debug("size: "+size);
+      assertEquals("name", name, tmpVF.getName());
+      assertEquals("pathName", vfsPath, tmpVF.getPathName());
+      assertEquals("lastModified", lastModified, tmpVF.getLastModified());
+      assertEquals("size", size, tmpVF.getSize());
+      assertEquals("url", url.getPath(), tmpVF.toURL().getPath());
+      // TODO: these should pass
+      //assertEquals("isFile", true, tmpVF.isFile());
+      //assertEquals("isDirectory", false, tmpVF.isDirectory());
+      assertEquals("isHidden", false, tmpVF.isHidden());
+      // Write out the vfs jar file
+      fos = new FileOutputStream(vfsSer);
+      ObjectOutputStream oos = new ObjectOutputStream(fos);
+      oos.writeObject(tmpVF);
+      oos.close();
+
+      // Read in the VF from the serialized file
+      FileInputStream fis = new FileInputStream(vfsSer);
+      ObjectInputStream ois = new ObjectInputStream(fis);
+      VirtualFile tmpVF2 = (VirtualFile) ois.readObject();
+      ois.close();
+      // Validate the vf jar against the tmp file attributes
+      assertEquals("name", name, tmpVF2.getName());
+      assertEquals("pathName", vfsPath, tmpVF2.getPathName());
+      assertEquals("lastModified", lastModified, tmpVF2.getLastModified());
+      assertEquals("size", size, tmpVF2.getSize());
+      assertEquals("url", url.getPath(), tmpVF2.toURL().getPath());
+      // TODO: these should pass
+      //assertEquals("isFile", true, tmpVF2.isFile());
+      //assertEquals("isDirectory", false, tmpVF2.isDirectory());
+      assertEquals("isHidden", false, tmpVF2.isHidden());
+   }
+
+   /**
+    * Test the serialization of VirtualFiles representing a jar
+    * @throws Exception
+    */
+   public void testVFNestedJarSerialization()
+      throws Exception
+   {
+      // this expects to be run with a working dir of the container root
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile inner = vfs.findChild("outer.jar/jar1.jar");
+
+      File vfsSer = File.createTempFile("testVFNestedJarSerialization", ".ser");
+      vfsSer.deleteOnExit();
+      // Write out the vfs inner jar file
+      FileOutputStream fos = new FileOutputStream(vfsSer);
+      ObjectOutputStream oos = new ObjectOutputStream(fos);
+      oos.writeObject(inner);
+      oos.close();
+      
+      // Read in the VF from the serialized file
+      FileInputStream fis = new FileInputStream(vfsSer);
+      ObjectInputStream ois = new ObjectInputStream(fis);
+      inner = (VirtualFile) ois.readObject();
+      ois.close();
+      List<VirtualFile> contents = inner.getChildren();
+      // META-INF/*, org/jboss/test/vfs/support/jar1/* at least
+      // TODO - fix this once no_copy serialization is working
+      int size = isForceCopyEnabled(inner) ? 2 : 0;
+      assertTrue("jar1.jar children.length("+contents.size()+") is not " + size, contents.size() >= size);
+      for(VirtualFile vf : contents)
+      {
+         log.info("  "+vf.getName());
+      }
+      VirtualFile vf = vfs.findChild("outer.jar/jar1.jar");
+/*
+      VirtualFile jar1MF = vf.findChild("META-INF/MANIFEST.MF");
+      InputStream mfIS = jar1MF.openStream();
+      Manifest mf = new Manifest(mfIS);
+      Attributes mainAttrs = mf.getMainAttributes();
+      String version = mainAttrs.getValue(Attributes.Name.SPECIFICATION_TITLE);
+      assertEquals(Attributes.Name.SPECIFICATION_TITLE.toString(), "jar1", version);
+      mfIS.close();
+*/
+   }
+
+   /**
+    * Test parsing of a vfs link properties file. It contains test.classes.url
+    * and test.lib.url system property references that are configured to
+    * point to the CodeSource location of this class and /vfs/sundry/jar/
+    * respectively.
+    * 
+    * @throws Exception
+    */
+   public void testVfsLinkProperties()
+      throws Exception
+   {
+      URL linkURL = super.getResource("/vfs/links/test-link.war.vfslink.properties");
+      assertNotNull("vfs/links/test-link.war.vfslink.properties", linkURL);
+      // Find resources to use as the WEB-INF/{classes,lib} link targets
+      URL classesURL = getClass().getProtectionDomain().getCodeSource().getLocation();
+      assertNotNull("classesURL", classesURL);
+      System.setProperty("test.classes.url", classesURL.toString());
+      URL libURL = super.getResource("/vfs/sundry/jar");
+      assertNotNull("libURL", libURL);      
+      System.setProperty("test.lib.url", libURL.toString());
+
+      assertTrue("isLink", VFSUtils.isLink(linkURL.getPath()));
+      Properties props = new Properties();
+      InputStream linkIS = linkURL.openStream();
+      List<LinkInfo> infos = VFSUtils.readLinkInfo(linkIS, linkURL.getPath(), props);
+      assertEquals("LinkInfo count", 2, infos.size());
+      LinkInfo classesInfo = null;
+      LinkInfo libInfo = null;
+      for(LinkInfo info :infos)
+      {
+         if( info.getName().equals("WEB-INF/classes") )
+            classesInfo = info;
+         else if(info.getName().equals("WEB-INF/lib") )
+            libInfo = info;
+      }
+      assertNotNull("classesInfo", classesInfo);
+      assertEquals("classesInfo.target", classesURL.toURI(), classesInfo.getLinkTarget());
+      assertNotNull("libInfo", libInfo);
+      assertEquals("libInfo.target", libURL.toURI(), libInfo.getLinkTarget());
+   }
+
+   /**
+    * Test the test-link.war link
+    * @throws Exception
+    */
+   public void testWarLink()
+      throws Exception
+   {
+      // Find resources to use as the WEB-INF/{classes,lib} link targets
+      URL classesURL = getClass().getProtectionDomain().getCodeSource().getLocation();
+      assertNotNull("classesURL", classesURL);
+      System.setProperty("test.classes.url", classesURL.toString());
+      URL libURL = super.getResource("/vfs/sundry/jar");
+      assertNotNull("libURL", libURL);      
+      System.setProperty("test.lib.url", libURL.toString());
+
+      // Root the vfs at the link file parent directory
+      URL linkURL = super.getResource("/vfs/links/test-link.war.vfslink.properties");
+      File linkFile = new File(linkURL.toURI());
+      File vfsRoot = linkFile.getParentFile();
+      assertNotNull("vfs/links/test-link.war.vfslink.properties", linkURL);
+      VFS vfs = VFS.getVFS(vfsRoot.toURI());
+
+      // We should find the test-link.war the link represents
+      VirtualFile war = vfs.findChild("test-link.war");
+      assertNotNull("war", war);
+
+      // Validate the WEB-INF/classes child link
+      VirtualFile classes = war.findChild("WEB-INF/classes");
+      String classesName = classes.getName();
+      String classesPathName = classes.getPathName();
+      boolean classesIsDirectory = classes.isLeaf() == false;
+      assertEquals("classes.name", "classes", classesName);
+      assertEquals("classes.pathName", "test-link.war/WEB-INF/classes", classesPathName);
+      assertEquals("classes.isDirectory", true, classesIsDirectory);
+      // Should be able to find this class since classes points to out codesource
+      VirtualFile thisClass = classes.findChild("org/jboss/test/virtual/test/FileVFSUnitTestCase.class");
+      assertEquals("FileVFSUnitTestCase.class", thisClass.getName());
+
+      // Validate the WEB-INF/lib child link
+      VirtualFile lib = war.findChild("WEB-INF/lib");
+      String libName = lib.getName();
+      String libPathName = lib.getPathName();
+      boolean libIsDirectory = lib.isLeaf() == false;
+      assertEquals("lib.name", "lib", libName);
+      assertEquals("lib.pathName", "test-link.war/WEB-INF/lib", libPathName);
+      assertEquals("lib.isDirectory", true, libIsDirectory);
+      // Should be able to find archive.jar under lib
+      VirtualFile archiveJar = lib.findChild("archive.jar");
+      assertEquals("archive.jar", archiveJar.getName());
+   }
+
+   /**
+    * Test configuration change detection on test-link.war link
+    * @throws Exception
+    */
+   public void testWarLinkUpdate()
+      throws Exception
+   {
+      // Setup the system properties used in test-link.war.vfslink.properties 
+      URL classesURL = getClass().getProtectionDomain().getCodeSource().getLocation();
+      assertNotNull("classesURL", classesURL);
+      System.setProperty("test.classes.url", classesURL.toString());
+      URL libURL = super.getResource("/vfs/sundry/jar");
+      assertNotNull("libURL", libURL);
+      System.setProperty("test.lib.url", libURL.toString());
+
+      // Root the vfs at the link file parent directory
+      URL linkURL = super.getResource("/vfs/links/test-link.war.vfslink.properties");
+      File linkFile = new File(linkURL.toURI());
+      assertNotNull("vfs/links/test-link.war.vfslink.properties", linkURL);
+
+      // Setup VFS root in a temp directory
+      File root = File.createTempFile("jboss-vfs-testWarLinkUpdate", ".tmp");
+      root.delete();
+      root.mkdir();
+      log.info("Using root: "+root);
+
+      // There should be no test-link.war under the new tmp root
+      VFS vfs = VFS.getVFS(root.toURI());
+      VirtualFile link = vfs.getChild("test-link.war");
+      assertNull("test-link.war", link);
+
+      // Add the link properties, now test-link.war should exist
+      File propsFile = new File(root, "test-link.war.vfslink.properties");
+      VFSUtils.copyStreamAndClose(new FileInputStream(linkFile), new FileOutputStream(propsFile));
+      link = vfs.getChild("test-link.war");
+      assertNotNull("test-link.war", link);
+
+      List<VirtualFile> children = link.getChildren();
+      assertEquals("test-link.war has 1 child", 1, children.size());
+      assertEquals("WEB-INF has 2 children", 2, children.get(0).getChildren().size());
+
+      // Sleep 1sec+ to allow timestamp changes in files to be > 1000ms, JBVFS-59
+      Thread.sleep(1005);
+
+      // modify properties file - add more children
+      URL dynamicClassRoot = new URL("vfsmemory", ".vfslink-test", "");
+      MemoryFileFactory.createRoot(dynamicClassRoot);
+
+      ByteArrayOutputStream baos = new ByteArrayOutputStream();
+      PrintWriter webOut = new PrintWriter(new OutputStreamWriter(baos, "UTF-8"));
+      webOut.println("<?xml version=\"1.0\" ?>");
+      webOut.println("<web-app xmlns=\"http://java.sun.com/xml/ns/javaee\"\n" +
+         "         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
+         "         xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd\"\n" +
+         "         version=\"2.5\">");
+      webOut.println("</web-app>");
+      webOut.close();
+
+      MemoryFileFactory.putFile(dynamicClassRoot, baos.toByteArray());
+
+      PrintWriter out = new PrintWriter(new OutputStreamWriter(new FileOutputStream(propsFile, true)));
+      out.println("vfs.link.name.2=WEB-INF/web.xml");
+      out.println("vfs.link.target.2=" + dynamicClassRoot.toExternalForm());
+      out.close();
+
+      Properties linkProps = new Properties();
+      InputStream propsIn = new FileInputStream(propsFile);
+      linkProps.load(propsIn);
+      assertEquals(1+3*2, linkProps.size());
+      assertEquals("vfs.link.name.0", "WEB-INF/classes", linkProps.getProperty("vfs.link.name.0"));
+      assertEquals("vfs.link.name.1", "WEB-INF/lib", linkProps.getProperty("vfs.link.name.1"));
+      assertEquals("vfs.link.name.2", "WEB-INF/web.xml", linkProps.getProperty("vfs.link.name.2"));
+      assertEquals("vfs.link.target.2", dynamicClassRoot.toExternalForm(), linkProps.getProperty("vfs.link.target.2"));
+      propsIn.close();
+
+      // You need to get a new reference to LinkHandler - to get up-to-date configuration
+      children = link.getChildren();
+      assertEquals("test-link.war has 1 child", 1, children.size());
+      log.info("WEB-INF children after update: "+children.get(0).getChildren());
+      assertEquals("WEB-INF has 3 children", 3, children.get(0).getChildren().size());
+
+      // Sleep 1sec+ to allow timestamp changes in files to be > 1000ms, JBVFS-59
+      Thread.sleep(1005);
+      // modify properties file - remove all but first
+      BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(propsFile)));
+      baos = new ByteArrayOutputStream();
+      out = new PrintWriter(new OutputStreamWriter(baos));
+      String line = in.readLine();
+      while(line != null)
+      {
+         if (line.indexOf(".0=") != -1)
+            out.println(line);
+         line = in.readLine();
+      }
+      out.close();
+      in.close();
+
+      FileOutputStream fos = new FileOutputStream(propsFile);
+      fos.write(baos.toByteArray());
+      fos.close();
+
+      children = link.getChildren();
+      assertEquals("test-link.war has 1 child", 1, children.size());
+      assertEquals("WEB-INF has 1 child", 1, children.get(0).getChildren().size());
+
+      // Sleep 1sec+ to allow timestamp changes in files to be > 1000ms, JBVFS-59
+      Thread.sleep(1005);
+      // modify properties file - remove all
+      fos = new FileOutputStream(propsFile);
+      fos.write(' ');
+      fos.close();
+
+      assertNotNull(link.getName() + " not null", link);
+      assertTrue(link.getName() + " exists()", link.exists());
+
+      children = link.getChildren();
+      assertTrue("Wrong number of children", children.size() == 0);
+
+      // remove properties file
+      assertTrue(propsFile.getName() + " delete()", propsFile.delete());
+
+      assertFalse(link.getName() + " exists() == false", link.exists());
+      VirtualFile oldLink = link;
+      link = vfs.getChild("test-link.war");
+      assertNull(oldLink.getName() + " is null", link);
+
+      children = vfs.getChildren();
+      assertTrue("Wrong number of children", children.size() == 0);
+
+      // put back .vfslink.properties
+      VFSUtils.copyStreamAndClose(new FileInputStream(linkFile), new FileOutputStream(propsFile));
+
+      assertTrue(oldLink.getName() + " exists()", oldLink.exists());
+      link = vfs.getChild("test-link.war");
+      assertNotNull("test-link.war", link);
+
+      children = link.getChildren();
+      assertTrue("Wrong number of children", children.size() == 1);
+      assertTrue("Wrong number of WEB-INF link children", children.get(0).getChildren().size() == 2);
+   }
+
+  /**
+    * Test that the URL of a VFS corresponding to a directory ends in '/' so that
+    * URLs created relative to it are under the directory. This requires that
+    * build-test.xml artifacts exist.
+    * 
+    * @throws Exception
+    */
+   public void testDirURLs() throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      VirtualFile outerJar = vfs.findChild("unpacked-outer.jar");
+      URL outerURL = outerJar.toURL();
+      log.debug("outerURL: "+outerURL);
+      assertTrue(outerURL+" ends in '/'", outerURL.getPath().endsWith("/"));
+      // Validate that jar1 is under unpacked-outer.jar
+      URL jar1URL = new URL(outerURL, "jar1.jar");
+      log.debug("jar1URL: "+jar1URL+", path="+jar1URL.getPath());
+      assertTrue("jar1URL path ends in unpacked-outer.jar/jar1.jar!/",
+            jar1URL.getPath().endsWith("unpacked-outer.jar/jar1.jar"));
+      VirtualFile jar1 = outerJar.findChild("jar1.jar");
+      assertEquals(jar1URL.getPath(), jar1.toURL().getPath());
+
+      VirtualFile packedJar = vfs.findChild("jar1.jar");
+      jar1URL = packedJar.findChild("org/jboss/test/vfs/support").toURL();
+      assertTrue("Jar directory entry URLs must end in /: " + jar1URL.toString(), jar1URL.toString().endsWith("/"));
+   }
+
+   /**
+    * Test that the URI of a VFS corresponding to a directory ends in '/' so that
+    * URIs created relative to it are under the directory. This requires that
+    * build-test.xml artifacts exist.
+    * 
+    * @throws Exception
+    */
+   public void testDirURIs() throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+
+      VirtualFile outerJar = vfs.findChild("unpacked-outer.jar");
+      URI outerURI = outerJar.toURI();
+      log.debug("outerURI: "+outerURI);
+      assertTrue(outerURI+" ends in '/'", outerURI.getPath().endsWith("/"));
+      // Validate that jar1 is under unpacked-outer.jar
+      URI jar1URI = new URI(outerURI+"jar1.jar");
+      log.debug("jar1URI: "+jar1URI+", path="+jar1URI.getPath());
+      assertTrue("jar1URI path ends in unpacked-outer.jar/jar1.jar!/",
+            jar1URI.getPath().endsWith("unpacked-outer.jar/jar1.jar"));
+      VirtualFile jar1 = outerJar.findChild("jar1.jar");
+      assertEquals(jar1URI.getPath(), jar1.toURI().getPath());
+
+      VirtualFile packedJar = vfs.findChild("jar1.jar");
+      jar1URI = packedJar.findChild("org/jboss/test/vfs/support").toURI();
+      assertTrue("Jar directory entry URLs must end in /: " + jar1URI.toString(),
+            jar1URI.toString().endsWith("/"));
+   }
+
+   /**
+    * Test copying a jar
+    * 
+    * @throws Exception
+    */
+   public void testCopyJar()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile jar = vfs.findChild("outer.jar");
+      assertTrue("outer.jar != null", jar != null);
+      File tmpJar = File.createTempFile("testCopyJar", ".jar");
+      tmpJar.deleteOnExit();
+
+      try
+      {
+         InputStream is = jar.openStream();
+         FileOutputStream fos = new FileOutputStream(tmpJar);
+         byte[] buffer = new byte[1024];
+         int read;
+         while( (read = is.read(buffer)) > 0 )
+         {
+            fos.write(buffer, 0, read);
+         }
+         fos.close();
+         log.debug("outer.jar size is: "+jar.getSize());
+         log.debug(tmpJar.getAbsolutePath()+" size is: "+tmpJar.length());
+         assertTrue("outer.jar > 0", jar.getSize() > 0);
+         assertEquals("copy jar size", jar.getSize(), tmpJar.length());
+         jar.close();
+      }
+      finally
+      {
+         try
+         {
+            tmpJar.delete();
+         }
+         catch(Exception ignore)
+         {
+         }
+      }
+   }
+
+   /**
+    * Test copying a jar that is nested in another jar.
+    * 
+    * @throws Exception
+    */
+   public void testCopyInnerJar()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile outerjar = vfs.findChild("outer.jar");
+      assertTrue("outer.jar != null", outerjar != null);
+      VirtualFile jar = outerjar.findChild("jar1.jar");
+      assertTrue("outer.jar/jar1.jar != null", jar != null);
+
+      File tmpJar = File.createTempFile("testCopyInnerJar", ".jar");
+      tmpJar.deleteOnExit();
+
+      try
+      {
+         InputStream is = jar.openStream();
+         FileOutputStream fos = new FileOutputStream(tmpJar);
+         byte[] buffer = new byte[1024];
+         int read;
+         while( (read = is.read(buffer)) > 0 )
+         {
+            fos.write(buffer, 0, read);
+         }
+         fos.close();
+         log.debug("outer.jar/jar1.jar size is: "+jar.getSize());
+         log.debug(tmpJar.getAbsolutePath()+" size is: "+tmpJar.length());
+         assertTrue("outer.jar > 0", jar.getSize() > 0);
+         assertEquals("copy jar size", jar.getSize(), tmpJar.length());
+         jar.close();
+      }
+      finally
+      {
+         try
+         {
+            tmpJar.delete();
+         }
+         catch(Exception ignore)
+         {
+         }
+      }
+   }
+
+   /**
+    * Test that the outermf.jar manifest classpath is parsed
+    * correctly.
+    * 
+    * @throws Exception
+    */
+   public void testManifestClasspath()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile outerjar = vfs.findChild("outermf.jar");
+      assertNotNull("outermf.jar != null", outerjar);
+
+      ArrayList<VirtualFile> cp = new ArrayList<VirtualFile>();
+      VFSUtils.addManifestLocations(outerjar, cp);
+      // The p0.jar should be found in the classpath
+      assertEquals("cp size 2", 2, cp.size());
+      assertEquals("jar1.jar == cp[0]", "jar1.jar", cp.get(0).getName());
+      assertEquals("jar2.jar == cp[1]", "jar2.jar", cp.get(1).getName());
+   }
+   /**
+    * Test that an inner-inner jar that is extracted does not blowup
+    * the addManifestLocations routine.
+    * 
+    * @throws Exception
+    */
+   public void testInnerManifestClasspath()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile outerjar = vfs.getChild("withalong/rootprefix/outermf.jar");
+      assertNotNull(outerjar);
+      VirtualFile jar1 = outerjar.getChild("jar1.jar");
+      assertNotNull(jar1);
+      VirtualFile jar2 = outerjar.getChild("jar2.jar");
+      assertNotNull(jar2);
+      VirtualFile innerjar = outerjar.getChild("innermf.jar");
+      assertNotNull("innermf.jar != null", innerjar);
+   
+      ArrayList<VirtualFile> cp = new ArrayList<VirtualFile>();
+      VFSUtils.addManifestLocations(innerjar, cp);
+      assertEquals(2, cp.size());
+      VirtualFile cp0 = cp.get(0);
+      assertEquals(jar1, cp0);
+      VirtualFile cp1 = cp.get(1);
+      assertEquals(jar2, cp1);
+   }
+
+   /**
+    * Validate accessing an packed jar vf and its uri when the vfs path
+    * contains spaces
+    * @throws Exception
+    */
+   public void testJarWithSpacesInPath()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile tstjar = vfs.findChild("path with spaces/tst.jar");
+      assertNotNull("tstjar != null", tstjar);
+      URI uri = tstjar.toURI();
+      URI expectedURI = new URI("vfs"+rootURL.toString()+"/path%20with%20spaces/tst.jar");
+      assertEquals(uri.getPath(), expectedURI.getPath());
+
+      InputStream is = uri.toURL().openStream();
+      is.close();
+
+      tstjar = vfs.findChild("path with spaces/tst%20nospace.jar");
+      assertNotNull("tstjar != null", tstjar);
+      uri = tstjar.toURI();
+      expectedURI = new URI("vfs"+rootURL.toString()+"/path%20with%20spaces/tst%2520nospace.jar");
+      assertEquals(uri.getPath(), expectedURI.getPath());
+
+      is = uri.toURL().openStream();
+      is.close();
+   }
+
+   public static void main(String[] args) throws Exception
+   {
+      File file = new File("C:\\Documents and Settings");
+      System.out.println(file.toURI());
+      System.out.println(file.toURL().getHost());
+      URI uri = new URI("file", null, "/Document and Settings", null);
+      System.out.println(uri);
+   }
+
+   /**
+    * Validate accessing an unpacked jar vf and its uri when the vfs path
+    * contains spaces
+    * @throws Exception
+    */
+   public void testUnpackedJarWithSpacesInPath()
+      throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile tstjar = vfs.findChild("path with spaces/unpacked-tst.jar");
+      assertNotNull("tstjar != null", tstjar);
+      URI uri = tstjar.toURI();
+      URI expectedURI = new URI("vfs" + rootURL.toString()+"/path%20with%20spaces/unpacked-tst.jar/");
+      assertEquals(uri, expectedURI);
+   }
+
+   /**
+    * Tests that we can find the META-INF/some-data.xml in an unpacked deployment
+    * 
+    * @throws Exception for any error
+    */
+   public void testGetMetaDataUnpackedJar() throws Exception
+   {
+      testGetMetaDataFromJar("unpacked-with-metadata.jar");
+   }
+   
+   /**
+    * Tests that we can find the META-INF/some-data.xml in a packed deployment
+    * 
+    * @throws Exception for any error
+    */
+   public void testGetMetaDataPackedJar() throws Exception
+   {
+      testGetMetaDataFromJar("with-metadata.jar");
+   }
+   
+   private void testGetMetaDataFromJar(String name) throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      
+      VirtualFile jar = vfs.findChild(name);
+      assertNotNull(jar);
+      VirtualFile metadataLocation = jar.findChild("META-INF");
+      assertNotNull(metadataLocation);
+
+      VirtualFile metadataByName = metadataLocation.findChild("some-data.xml");
+      assertNotNull(metadataByName);
+      
+      //This is the same code as is called by AbstractDeploymentContext.getMetaDataFiles(String name, String suffix). 
+      //The MetaDataMatchFilter is a copy of the one used there
+      List<VirtualFile> metaDataList = metadataLocation.getChildren(new MetaDataMatchFilter(null, "-data.xml"));
+      assertNotNull(metaDataList);
+      assertEquals("Wrong size", 1, metaDataList.size());
+   }
+
+   /**
+    * Validate that a URLClassLoader.findReource/getResourceAsStream calls for non-existing absolute
+    * resources that should fail as expected with null results. Related to JBMICROCONT-139.
+    * 
+    * @throws Exception
+    */
+   public void testURLClassLoaderFindResourceFailure() throws Exception
+   {
+      URL rootURL = getResource("/vfs/test");
+      VFS vfs = VFS.getVFS(rootURL);
+      URL[] cp = {vfs.getRoot().toURL()};
+      URLClassLoader ucl = new URLClassLoader(cp);
+      // Search for a non-existent resource
+      URL qp = ucl.findResource("nosuch-quartz.props");
+      assertNull("findResource(nosuch-quartz.props)", qp);
+      InputStream is = ucl.getResourceAsStream("nosuch-quartz.props");
+      assertNull("getResourceAsStream(nosuch-quartz.props)", is);
+   }
+
+   /**
+    * Test VirtualFile.exists for vfsfile based urls.
+    * 
+    * @throws Exception
+    */
+   public void testFileExists()
+      throws Exception
+   {
+      File tmpRoot = File.createTempFile("vfs", ".root");
+      tmpRoot.delete();
+      tmpRoot.mkdir();
+      File tmp = File.createTempFile("testFileExists", null, tmpRoot);
+      log.info("+++ testFileExists, tmp="+tmp.getCanonicalPath());
+
+      URL rootURL = tmpRoot.toURL();
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile tmpVF = vfs.findChild(tmp.getName());
+      assertTrue(tmpVF.getPathName()+".exists()", tmpVF.exists());
+      assertTrue("tmp.delete()", tmpVF.delete());
+      assertFalse(tmpVF.getPathName()+".exists()", tmpVF.exists());
+      assertTrue(tmpRoot+".delete()", tmpRoot.delete());
+   }
+
+   /**
+    * Test VirtualFile.exists for vfsfile based urls for a directory.
+    * 
+    * @throws Exception
+    */
+   public void testDirFileExists()
+      throws Exception
+   {
+      File tmpRoot = File.createTempFile("vfs", ".root");
+      tmpRoot.delete();
+      tmpRoot.mkdir();
+      File tmp = File.createTempFile("testFileExists", null, tmpRoot);
+      assertTrue(tmp+".delete()", tmp.delete());
+      assertTrue(tmp+".mkdir()", tmp.mkdir());
+      log.info("+++ testDirFileExists, tmp="+tmp.getCanonicalPath());
+
+      URL rootURL = tmpRoot.toURL();
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile tmpVF = vfs.findChild(tmp.getName());
+      assertTrue(tmpVF.getPathName()+".exists()", tmpVF.exists());
+      assertFalse(tmpVF.getPathName()+".isLeaf()", tmpVF.isLeaf());
+      assertTrue(tmp+".delete()", tmp.delete());
+      assertFalse(tmpVF.getPathName()+".exists()", tmpVF.exists());
+      assertTrue(tmpRoot+".delete()", tmpRoot.delete());
+   }
+
+   /**
+    * Test VirtualFile.exists for vfsjar based urls.
+    * 
+    * @throws Exception
+    */
+   public void testJarExists()
+      throws Exception
+   {
+      File tmpRoot = File.createTempFile("vfs", ".root");
+      tmpRoot.delete();
+      tmpRoot.mkdir();
+      File tmpJar = File.createTempFile("testJarExists", ".jar", tmpRoot);
+      log.info("+++ testJarExists, tmpJar="+tmpJar.getCanonicalPath());
+      Manifest mf = new Manifest();
+      mf.getMainAttributes().putValue("Created-By", "FileVFSUnitTestCase.testJarExists");
+      FileOutputStream fos = new FileOutputStream(tmpJar);
+      JarOutputStream jos = new JarOutputStream(fos, mf);
+      jos.setComment("testJarExists");
+      jos.setLevel(0);
+      jos.close();
+
+      URL rootURL = tmpRoot.toURL();
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile tmpVF = vfs.findChild(tmpJar.getName());
+      assertTrue(tmpVF.getPathName()+".exists()", tmpVF.exists());
+      assertTrue(tmpVF.getPathName()+".size() > 0", tmpVF.getSize() > 0);
+      assertTrue("tmp.delete()", tmpVF.delete());
+      assertFalse(tmpVF.getPathName()+".exists()", tmpVF.exists());
+      assertTrue(tmpRoot+".delete()", tmpRoot.delete());
+   }
+
+   /**
+    * Test VirtualFile.exists for vfsjar based urls for a directory.
+    * 
+    * @throws Exception
+    */
+   public void testDirJarExists()
+      throws Exception
+   {
+      File tmpRoot = File.createTempFile("vfs", ".root");
+      tmpRoot.delete();
+      tmpRoot.mkdir();
+      File tmp = File.createTempFile("testDirJarExists", ".jar", tmpRoot);
+      assertTrue(tmp+".delete()", tmp.delete());
+      assertTrue(tmp+".mkdir()", tmp.mkdir());
+      log.info("+++ testDirJarExists, tmp="+tmp.getCanonicalPath());
+
+      URL rootURL = tmpRoot.toURL();
+      VFS vfs = VFS.getVFS(rootURL);
+      VirtualFile tmpVF = vfs.findChild(tmp.getName());
+      log.info(tmpVF);
+      assertTrue(tmpVF.getPathName()+".exists()", tmpVF.exists());
+      assertFalse(tmpVF.getPathName()+".isLeaf()", tmpVF.isLeaf());
+      assertTrue(tmp+".delete()", tmp.delete());
+      assertFalse(tmpVF.getPathName()+".exists()", tmpVF.exists());
+      assertTrue(tmpRoot+".delete()", tmpRoot.delete());
+   }
+
+   /**
+    * Test VirtualFile.delete() for file based urls
+    *
+    * @throws Exception
+    */
+   public void testFileDelete() throws Exception
+   {
+      File tmpRoot = File.createTempFile("vfs", ".root");
+      VFS vfs = VFS.getVFS(tmpRoot.toURL());
+
+      // non-existent directory - exists() not
+      tmpRoot.delete();
+      assertFalse(tmpRoot + ".exits() == false", vfs.getRoot().exists());
+
+      // existing directory - exists(), delete()
+      tmpRoot.mkdir();
+      assertTrue(tmpRoot + ".exits()", vfs.getRoot().exists());
+      assertTrue(tmpRoot + ".delete()", vfs.getRoot().delete());
+      tmpRoot.mkdir();
+
+      // non-empty directory - delete()
+      File tmp = new File(tmpRoot, "testFileDelete.jar");
+      assertTrue(tmp.mkdir());
+      File tmp2 = File.createTempFile("testFileDelete2", ".jar", tmp);
+      assertTrue(tmp2.exists());
+      VirtualFile tmpDeletable = VFS.getRoot(tmp.toURI());
+      assertTrue(tmpRoot + ".delete() == false", tmpDeletable.delete());
+
+      // create child to vfs
+      assertTrue(tmp.mkdir());
+      // children() exist
+      List<VirtualFile> children = vfs.getChildren();
+      assertTrue(tmpRoot + ".getChildren().size() == 1", children.size() == 1);
+
+      // specific child exists(), delete(), exists() not
+      VirtualFile tmpVF = vfs.getChild(tmp.getName());
+      assertTrue(tmp + ".exists()", tmpVF.exists());
+      assertTrue(tmp + ".delete()", tmpVF.delete());
+      assertFalse(tmp + ".exists() == false", tmpVF.exists());
+
+      // children() don't exist
+      children = vfs.getChildren();
+      assertTrue(tmpRoot + ".getChildren().size() == 0", children.size() == 0);
+
+      // getChild() returns null
+      tmpVF = vfs.getChild(tmp.getName());
+      assertNull(tmpRoot + ".getChild('" + tmp.getName() + "') == null", tmpVF);
+
+      // directory delete()
+      assertTrue(tmpRoot + ".delete()", vfs.getRoot().delete());
+   }
+
+   /**
+    * Test for <em>caseSensitive=true</em>
+    *
+    * If this test passes on unixes, it doesn't mean much, because there it should pass without
+    * case sensitivity turned on as well.
+    *
+    * If it passes on windows, it means the functionality works as expected.
+    *
+    * @throws Exception for any error
+    */
+   public void testCaseSensitive() throws Exception
+   {
+      URL rootURL = getResource("/vfs");
+
+      FileSystemContext ctx = new FileSystemContext(new URL(rootURL.toString() + "?caseSensitive=true"));
+      VirtualFileHandler root = ctx.getRoot();
+
+      String path = "context/file/simple/child";
+      VirtualFileHandler child = root.getChild(path);
+      assertTrue("getChild('" + path + "')", child != null);
+
+      path = "context/file/simple/CHILD";
+      child = root.getChild(path);
+      assertTrue("getChild('" + path + "')", child == null);
+
+      path = "context/jar/archive.jar";
+      child = root.getChild(path);
+      assertTrue("getChild('" + path + "')", child != null);
+
+      path = "context/JAR/archive.jar";
+      child = root.getChild(path);
+      assertTrue("getChild('" + path + "')", child == null);
+
+      path = "context/jar/archive.JAR";
+      child = root.getChild(path);
+      assertTrue("getChild('" + path + "')", child == null);
+
+      path = "context/jar/archive.jar/child";
+      child = root.getChild(path);
+      assertTrue("getChild('" + path + "')", child != null);
+
+      path = "context/jar/archive.jar/CHILD";
+      child = root.getChild(path);
+      assertTrue("getChild('" + path + "')", child == null);
+   }
+}

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/LRUCacheTestCase.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/LRUCacheTestCase.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/LRUCacheTestCase.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/LRUCacheTestCase.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,49 @@
+/*
+* 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.test.virtual.test;
+
+import junit.framework.Test;
+import org.jboss.virtual.plugins.cache.LRUVFSCache;
+import org.jboss.virtual.spi.cache.VFSCache;
+
+/**
+ * LRU VFSCache Test.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public class LRUCacheTestCase extends CachePolicyVFSCacheTest
+{
+   public LRUCacheTestCase(String name)
+   {
+      super(name);
+   }
+
+   public static Test suite()
+   {
+      return suite(LRUCacheTestCase.class);
+   }
+
+   protected VFSCache createCache()
+   {
+      return new LRUVFSCache(2, 10);
+   }
+}
\ No newline at end of file

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/MapVFSCacheTest.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/MapVFSCacheTest.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/MapVFSCacheTest.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/MapVFSCacheTest.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,43 @@
+/*
+* 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.test.virtual.test;
+
+import org.jboss.virtual.spi.VFSContext;
+
+/**
+ * Map VFSCache Test.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public abstract class MapVFSCacheTest extends VFSCacheTest
+{
+   public MapVFSCacheTest(String name)
+   {
+      super(name);
+   }
+
+   protected void testCachedContexts(Iterable<VFSContext> iter)
+   {
+      VFSContext context = iter.iterator().next();
+      assertNotNull(context);
+   }
+}
\ No newline at end of file

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/SoftRefCacheTestCase.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/SoftRefCacheTestCase.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/SoftRefCacheTestCase.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/SoftRefCacheTestCase.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,49 @@
+/*
+* 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.test.virtual.test;
+
+import org.jboss.virtual.plugins.cache.SoftRefVFSCache;
+import org.jboss.virtual.spi.cache.VFSCache;
+import junit.framework.Test;
+
+/**
+ * SoftRef VFSCache Test.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public class SoftRefCacheTestCase extends MapVFSCacheTest
+{
+   public SoftRefCacheTestCase(String name)
+   {
+      super(name);
+   }
+
+   public static Test suite()
+   {
+      return suite(SoftRefCacheTestCase.class);
+   }
+
+   protected VFSCache createCache()
+   {
+      return new SoftRefVFSCache();
+   }
+}
\ No newline at end of file

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/TimedCacheTestCase.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/TimedCacheTestCase.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/TimedCacheTestCase.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/TimedCacheTestCase.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,49 @@
+/*
+* 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.test.virtual.test;
+
+import org.jboss.virtual.plugins.cache.TimedVFSCache;
+import org.jboss.virtual.spi.cache.VFSCache;
+import junit.framework.Test;
+
+/**
+ * Timed VFSCache Test.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public class TimedCacheTestCase extends CachePolicyVFSCacheTest
+{
+   public TimedCacheTestCase(String name)
+   {
+      super(name);
+   }
+
+   public static Test suite()
+   {
+      return suite(TimedCacheTestCase.class);
+   }
+
+   protected VFSCache createCache()
+   {
+      return new TimedVFSCache(60);
+   }
+}
\ No newline at end of file

Deleted: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java
===================================================================
--- projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java	2008-10-20 08:32:12 UTC (rev 79734)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -1,92 +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.test.virtual.test;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-import junit.textui.TestRunner;
-import org.jboss.virtual.VFS;
-
-/**
- * VFS All Test Suite.
- * 
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author <a href="ales.justin at jboss.com">Ales Justin</a>
- * @version $Revision: 46146 $
- */
-public class VFSAllTestSuite extends TestSuite
-{
-   public static void main(String[] args)
-   {
-      TestRunner.run(suite());
-   }
-
-   public static Test suite()
-   {
-      VFS.init();
-      TestSuite suite = new TestSuite("VFS Tests default");
-
-      // vfs / spi
-      suite.addTest(VFSUnitTestCase.suite());
-      suite.addTest(VirtualFileUnitTestCase.suite());
-      // url
-      suite.addTest(URLResolutionUnitTestCase.suite());
-      suite.addTest(URLExistsUnitTestCase.suite());
-      suite.addTest(URLConnectionUnitTestCase.suite());
-      // files
-      suite.addTest(FileVFSUnitTestCase.suite());
-      suite.addTest(CopyFileVFSUnitTestCase.suite());
-      suite.addTest(FileVFSContextUnitTestCase.suite());
-      suite.addTest(FileVirtualFileHandlerUnitTestCase.suite());
-      // jars
-      suite.addTest(JARCacheUnitTestCase.suite());
-      suite.addTest(CopyJARCacheUnitTestCase.suite());
-      suite.addTest(JARVFSContextUnitTestCase.suite());
-      suite.addTest(JARVirtualFileHandlerUnitTestCase.suite());
-      suite.addTest(JARSerializationUnitTestCase.suite());
-      suite.addTest(CopyJARSerializationUnitTestCase.suite());
-      suite.addTest(JAREntryTestCase.suite());
-      suite.addTest(CopyJAREntryTestCase.suite());
-      suite.addTest(ZipEntryHandlerUnitTestCase.suite());
-      suite.addTest(ZipEntryVFSContextUnitTestCase.suite());
-      // contexts
-      suite.addTest(AssembledContextTestCase.suite());
-      suite.addTest(MemoryTestCase.suite());
-      suite.addTest(SundryVFSUnitTestCase.suite());
-      // options / policy / path
-      suite.addTest(PathQueryTestCase.suite());
-      suite.addTest(PathTokensTestCase.suite());
-      // unpack
-      suite.addTest(UnpackTestCase.suite());
-      suite.addTest(ExplodeTestCase.suite());
-      suite.addTest(TempTestCase.suite());
-      // visitor
-      suite.addTest(VisitorUnitTestCase.suite());
-      // utils
-      suite.addTest(VFSUtilTestCase.suite());
-      // custom
-      suite.addTest(CustomTestCase.suite());
-      suite.addTest(VFSResourceTestCase.suite());
-
-      return suite;
-   }
-}

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSAllTestSuite.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,97 @@
+/*
+* 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.test.virtual.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+import org.jboss.virtual.VFS;
+
+/**
+ * VFS All Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ * @version $Revision: 46146 $
+ */
+public class VFSAllTestSuite extends TestSuite
+{
+   public static void main(String[] args)
+   {
+      TestRunner.run(suite());
+   }
+
+   public static Test suite()
+   {
+      VFS.init();
+      TestSuite suite = new TestSuite("VFS Tests default");
+
+      // vfs / spi
+      suite.addTest(VFSUnitTestCase.suite());
+      suite.addTest(VirtualFileUnitTestCase.suite());
+      // url
+      suite.addTest(URLResolutionUnitTestCase.suite());
+      suite.addTest(URLExistsUnitTestCase.suite());
+      suite.addTest(URLConnectionUnitTestCase.suite());
+      // files
+      suite.addTest(FileVFSUnitTestCase.suite());
+      suite.addTest(CopyFileVFSUnitTestCase.suite());
+      suite.addTest(FileVFSContextUnitTestCase.suite());
+      suite.addTest(FileVirtualFileHandlerUnitTestCase.suite());
+      // jars
+      suite.addTest(JARCacheUnitTestCase.suite());
+      suite.addTest(CopyJARCacheUnitTestCase.suite());
+      suite.addTest(JARVFSContextUnitTestCase.suite());
+      suite.addTest(JARVirtualFileHandlerUnitTestCase.suite());
+      suite.addTest(JARSerializationUnitTestCase.suite());
+      suite.addTest(CopyJARSerializationUnitTestCase.suite());
+      suite.addTest(JAREntryTestCase.suite());
+      suite.addTest(CopyJAREntryTestCase.suite());
+      suite.addTest(ZipEntryHandlerUnitTestCase.suite());
+      suite.addTest(ZipEntryVFSContextUnitTestCase.suite());
+      // contexts
+      suite.addTest(AssembledContextTestCase.suite());
+      suite.addTest(MemoryTestCase.suite());
+      suite.addTest(SundryVFSUnitTestCase.suite());
+      // options / policy / path
+      suite.addTest(PathQueryTestCase.suite());
+      suite.addTest(PathTokensTestCase.suite());
+      // unpack
+      suite.addTest(UnpackTestCase.suite());
+      suite.addTest(ExplodeTestCase.suite());
+      suite.addTest(TempTestCase.suite());
+      // visitor
+      suite.addTest(VisitorUnitTestCase.suite());
+      // utils
+      suite.addTest(VFSUtilTestCase.suite());
+      // custom
+      suite.addTest(CustomTestCase.suite());
+      suite.addTest(VFSResourceTestCase.suite());
+      // cache
+      suite.addTest(LRUCacheTestCase.suite());
+      suite.addTest(TimedCacheTestCase.suite());
+      suite.addTest(SoftRefCacheTestCase.suite());
+      suite.addTest(WeakRefCacheTestCase.suite());
+
+      return suite;
+   }
+}

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSCacheTest.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/VFSCacheTest.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSCacheTest.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/VFSCacheTest.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,166 @@
+/*
+* 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.test.virtual.test;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URL;
+
+import org.jboss.virtual.VFS;
+import org.jboss.virtual.VirtualFile;
+import org.jboss.virtual.spi.cache.VFSCache;
+import org.jboss.virtual.spi.cache.VFSCacheFactory;
+import org.jboss.virtual.spi.cache.CacheStatistics;
+import org.jboss.virtual.spi.VFSContext;
+
+/**
+ * VFSCache Test.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public abstract class VFSCacheTest extends AbstractVFSTest
+{
+   public VFSCacheTest(String name)
+   {
+      super(name);
+   }
+
+   protected abstract VFSCache createCache();
+
+   @SuppressWarnings("deprecation")
+   public void testCache() throws Exception
+   {
+      URL url = getResource("/vfs/test/nested");
+
+      VFSCache cache = createCache();
+      cache.start();
+      try
+      {
+         VFSCacheFactory.setInstance(cache);
+         try
+         {
+            VirtualFile root = VFS.getRoot(url);
+
+            VirtualFile file = root.findChild("/nested.jar/META-INF/empty.txt");
+            URL fileURL = file.toURL();
+            VirtualFile nested = root.findChild("/nested.jar/complex.jar/subfolder/subsubfolder/subsubchild");
+            URL nestedURL = nested.toURL();
+
+            assertEquals(file, cache.getFile(fileURL));
+            assertEquals(nested, cache.getFile(nestedURL));
+
+            VFSCacheFactory.setInstance(null);
+            VFSCache wrapper = new WrapperVFSCache(cache);
+            VFSCacheFactory.setInstance(wrapper);
+
+            assertEquals(file, wrapper.getFile(fileURL));
+            assertEquals(nested, wrapper.getFile(nestedURL));
+         }
+         finally
+         {
+            VFSCacheFactory.setInstance(null);
+         }
+      }
+      finally
+      {
+         cache.stop();
+      }
+   }
+
+   protected abstract void testCachedContexts(Iterable<VFSContext> iter);
+
+   public void testCacheStatistics() throws Exception
+   {
+      URL url = getResource("/vfs/test/nested");
+
+      VFSCache cache = createCache();
+      cache.start();
+      try
+      {
+         if (cache instanceof CacheStatistics)
+         {
+            CacheStatistics statistics = CacheStatistics.class.cast(cache);
+            VFSCacheFactory.setInstance(cache);
+            try
+            {
+               VirtualFile root = VFS.getRoot(url);
+               assertNotNull(root);
+
+               Iterable<VFSContext> iter = statistics.getCachedContexts();
+               testCachedContexts(iter);
+
+               assertEquals(1, statistics.size());
+               assertTrue(statistics.lastInsert() != 0);
+            }
+            finally
+            {
+               VFSCacheFactory.setInstance(null);
+            }
+         }
+      }
+      finally
+      {
+         cache.stop();
+      }
+   }
+
+   private class WrapperVFSCache implements VFSCache
+   {
+      private VFSCache delegate;
+
+      private WrapperVFSCache(VFSCache delegate)
+      {
+         this.delegate = delegate;
+      }
+
+      public VirtualFile getFile(URI uri) throws IOException
+      {
+         return delegate.getFile(uri);
+      }
+
+      public VirtualFile getFile(URL url) throws IOException
+      {
+         return delegate.getFile(url);
+      }
+
+      public void putContext(VFSContext context)
+      {
+         throw new IllegalArgumentException("Context should already be there: " + context);
+      }
+
+      public void removeContext(VFSContext context)
+      {
+      }
+
+      public void start() throws Exception
+      {
+      }
+
+      public void stop()
+      {
+      }
+
+      public void flush()
+      {
+      }
+   }
+}
\ No newline at end of file

Copied: projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/WeakRefCacheTestCase.java (from rev 80461, projects/vfs/branches/Branch_2_0/src/test/java/org/jboss/test/virtual/test/WeakRefCacheTestCase.java)
===================================================================
--- projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/WeakRefCacheTestCase.java	                        (rev 0)
+++ projects/vfs/tags/2.0.0.CR2/src/test/java/org/jboss/test/virtual/test/WeakRefCacheTestCase.java	2008-11-04 10:24:27 UTC (rev 80463)
@@ -0,0 +1,49 @@
+/*
+* 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.test.virtual.test;
+
+import org.jboss.virtual.plugins.cache.WeakRefVFSCache;
+import org.jboss.virtual.spi.cache.VFSCache;
+import junit.framework.Test;
+
+/**
+ * SoftRef VFSCache Test.
+ *
+ * @author <a href="ales.justin at jboss.com">Ales Justin</a>
+ */
+public class WeakRefCacheTestCase extends MapVFSCacheTest
+{
+   public WeakRefCacheTestCase(String name)
+   {
+      super(name);
+   }
+
+   public static Test suite()
+   {
+      return suite(WeakRefCacheTestCase.class);
+   }
+
+   protected VFSCache createCache()
+   {
+      return new WeakRefVFSCache();
+   }
+}
\ No newline at end of file




More information about the jboss-cvs-commits mailing list