changeset 352:6306f07e76bc

zipfs demo Contributed-by: Rajendra Gutupalli and Jaya Hangal
author alanb
date Tue, 24 Jun 2008 18:30:03 +0100
parents cc7d3c1f8a8b
children 5996f2328c7c
files make/mkdemo/Makefile make/mkdemo/nio/Makefile make/mkdemo/nio/ZipFileSystem/Makefile src/share/demo/nio/ZipFileSystem/META-INF/services/java.nio.file.spi.FileSystemProvider src/share/demo/nio/ZipFileSystem/README.txt src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/JarEntryInfo.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/JarFileAttributeView.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/JarFileAttributes.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipEntryInfo.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileAttributeView.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileAttributes.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileBasicAttributeView.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileBasicAttributes.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileEntry.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFilePath.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileStore.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileStream.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystem.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystemProvider.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipHeaderConstants.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipPathParser.java src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipUtils.java test/demo/nio/ZipFileSystem/Sanity.java test/demo/nio/ZipFileSystem/sanity.sh
diffstat 24 files changed, 3707 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/make/mkdemo/Makefile	Tue Jun 24 18:11:44 2008 +0100
+++ b/make/mkdemo/Makefile	Tue Jun 24 18:30:03 2008 +0100
@@ -31,7 +31,7 @@
 PRODUCT = demos
 include $(BUILDDIR)/common/Defs.gmk
 
-SUBDIRS = applets jfc jvmti management jni scripting jpda
+SUBDIRS = applets jfc jvmti management jni scripting jpda nio
 
 all build:: nbproject
 	$(SUBDIRS-loop)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mkdemo/nio/Makefile	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,37 @@
+#
+# Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code 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 General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+#
+# Makefile for building the NIO demo(s)
+#
+
+BUILDDIR = ../..
+PRODUCT = demos
+include $(BUILDDIR)/common/Defs.gmk
+
+SUBDIRS = ZipFileSystem
+
+all build clean clobber::
+	$(SUBDIRS-loop)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/make/mkdemo/nio/ZipFileSystem/Makefile	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,40 @@
+#
+# Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Sun designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Sun in the LICENSE file that accompanied this code.
+#
+# This code 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 General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+BUILDDIR = ../../..
+PRODUCT = demo/nio
+DEMONAME = ZipFileSystem
+include $(BUILDDIR)/common/Defs.gmk
+
+DEMO_ROOT       = $(SHARE_SRC)/demo/nio/$(DEMONAME)
+DEMO_TOPFILES   = ./README.txt
+DEMO_MAINCLASS  = $(DEMONAME)
+DEMO_DESTDIR    = $(DEMODIR)/nio/$(DEMONAME)
+
+#
+# Demo jar building rules.
+#
+include $(BUILDDIR)/common/Demo.gmk
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/META-INF/services/java.nio.file.spi.FileSystemProvider	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,1 @@
+com.sun.nio.zipfs.ZipFileSystemProvider
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/README.txt	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,29 @@
+ZipFileSystem is a file system provider that treats the contents of a zip or
+JAR file as a read-only file system.
+
+To deploy the provider you must copy ZipFileSystem.jar into your extensions
+directory or else add <JDK_HOME>/demo/nio/ZipFileSystem/ZipFileSystem.jar
+to your class path.
+
+The factory methods defined by the java.nio.file.FileSystems class can be
+used to create a FileSystem, eg:
+
+   // use file type detection
+   Map<String,?> env = Collections.emptyMap();
+   Path jarfile = Path.get("foo.jar");
+   FileSystem fs = FileSystems.newFileSystem(jarfile, env);
+
+-or
+
+   // locate file system by URI
+   Map<String,?> env = Collections.emptyMap();
+   URI uri = URI.create("zip:///mydir/foo.jar");
+   FileSystem fs = FileSystems.newFileSystem(uri, env);
+
+Once a FileSystem is created then classes in the java.nio.file package
+can be used to access files in the zip/JAR file, eg:
+
+   Path mf = fs.getPath("/META-INF/MANIFEST.MF");
+   InputStream in = mf.newInputStream();
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/JarEntryInfo.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.util.Map;
+import java.util.Set;
+
+public class JarEntryInfo extends ZipEntryInfo {
+    JarEntryInfo(ZipEntryInfo entry){
+        super(entry);
+    }
+
+    Set<Map.Entry<Object, Object>> entryAttributs;
+    Set<Map.Entry<Object, Object>> manifestMainAttrs;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/JarFileAttributeView.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.attribute.*;
+import java.nio.file.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+
+public class JarFileAttributeView extends
+        ZipFileBasicAttributeView {
+
+    /** Creates a new instance of ZipFileAttributeView */
+    public JarFileAttributeView() {
+    }
+
+    @Override
+    public JarFileAttributes readAttributes()
+                throws IOException {
+        return new JarFileAttributes(super.getBinding());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/JarFileAttributes.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.concurrent.*;
+import java.io.*;
+import java.util.Map;
+import java.util.Set;
+
+public class JarFileAttributes extends ZipFileBasicAttributes {
+
+    /** Creates a new instance of ZipFileAttributes */
+    public JarFileAttributes(FileRef file)
+            throws IOException {
+        super(file);
+
+    }
+
+    public Set<Map.Entry<Object, Object>> getManifestAttributes() {
+        return ((JarEntryInfo) ze).manifestMainAttrs;
+    }
+
+    public Set<Map.Entry<Object, Object>> getEntryAttributes() {
+        return ((JarEntryInfo) ze).entryAttributs;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipEntryInfo.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+public class ZipEntryInfo {
+
+    byte[] filename;
+    int compSize;
+    int size;
+    byte[] comment;
+    long crc;
+    byte[] extraField;
+    int method;
+    int extAttrs;
+    long createTime = -1;
+    boolean isDirectory;
+    boolean isOtherFile;
+    boolean isRegularFile;
+    boolean isArchiveFile;
+    long lastAccessTime = -1;
+    long lastModifiedTime;
+    long streamOffset;
+    int versionMadeBy;
+    ZipEntryInfo(ZipEntryInfo entry){
+        this.filename = entry.filename;
+        this.compSize = entry.compSize;
+        this.size = entry.size;
+        this.comment = entry.comment;
+        this.crc = entry.crc;
+        this.extraField = entry.extraField;
+        this.method = entry.method;
+        this.extAttrs = entry.extAttrs;
+        this.createTime = entry.createTime;
+        this.isDirectory = entry.isDirectory;
+        this.isOtherFile = entry.isOtherFile;
+        this.isRegularFile = entry.isRegularFile;
+        this.isArchiveFile = entry.isArchiveFile;
+        this.lastAccessTime = entry.lastAccessTime;
+        this.lastModifiedTime = entry.lastModifiedTime;
+        this.streamOffset = entry.streamOffset;
+        this.versionMadeBy = entry.versionMadeBy;
+
+    }
+    ZipEntryInfo(){
+        super();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileAttributeView.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.attribute.*;
+import java.nio.file.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+
+
+public class ZipFileAttributeView extends
+        ZipFileBasicAttributeView {
+
+    /** Creates a new instance of ZipFileAttributeView */
+    public ZipFileAttributeView() {
+    }
+
+    @Override
+    public ZipFileAttributes readAttributes()
+                throws IOException {
+        return new ZipFileAttributes(super.getBinding());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileAttributes.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.concurrent.*;
+import java.io.*;
+
+public class ZipFileAttributes extends ZipFileBasicAttributes {
+
+    /** Creates a new instance of ZipFileAttributes */
+    private String[] version = {"FAT file system (DOS, OS/2, NT)", "Amiga", "VMS (VAX or Alpha AXP)", "Unix", "VM/CMS", "Atari", "HPFS file system (OS/2, NT 3.x)",
+        "Macintosh", "Z-System", "CP/M", "TOPS-20", "NTFS file system (NT)", "SMS/QDOS", "Acorn RISC OS", "VFAT file system (Win95, NT)",
+        "MVS", "BeOS (BeBox or PowerMac)", "Tandem"
+    };
+
+    public ZipFileAttributes(FileRef file)
+            throws IOException {
+        super(file);
+    }
+
+
+    public byte[] comment() {
+        return ze.comment;
+    }
+
+    public int compressedSize() {
+        return ze.compSize;
+    }
+
+    public long crc() {
+        return ze.crc;
+    }
+
+    public byte[] extra() {
+        return ze.extraField;
+    }
+
+    public int method() {
+        return ze.method;
+    }
+
+    public byte[] name() {
+        return ze.filename;
+    }
+
+    public boolean isArchiveFile() {
+        return ze.isArchiveFile;
+    }
+
+    public String versionMadeBy() {
+        int ver = (ze.versionMadeBy >> 8);
+        if (ver >= 0 && ver < 17) {
+            return version[ver];
+        } else {
+            return "unused";
+        }
+    }
+
+    public int getExternalAttrs() {
+        return ze.extAttrs;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileBasicAttributeView.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.attribute.*;
+import java.nio.file.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+
+
+public class ZipFileBasicAttributeView implements
+        BasicFileAttributeView {
+    // encapsulates the object that we are bound too
+    private volatile FileRef binding;
+
+    /** Creates a new instance of ZipFileAttributeView */
+    public ZipFileBasicAttributeView() {
+    }
+
+    FileRef getBinding() {
+        FileRef b = binding;
+
+        return b;
+    }
+
+    public BasicFileAttributeView bind(FileRef f) {
+        this.binding = f;
+        return this;
+    }
+
+    public BasicFileAttributeView bind(FileRef f, boolean followLinks) {
+        bind(f);
+        return this;
+    }
+
+    public BasicFileAttributes readAttributes()
+            throws IOException {
+        return new ZipFileBasicAttributes(getBinding());
+    }
+
+
+
+    public BasicFileAttributeView setTimes(Long lastModifiedTime, Long lastAccessTime, Long createTime, TimeUnit unit) throws IOException {
+        throw new ReadOnlyFileSystemException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileBasicAttributes.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.util.concurrent.*;
+import java.io.IOException;
+import java.util.Calendar;
+
+
+public class ZipFileBasicAttributes implements
+        BasicFileAttributes {
+
+    FileRef file;
+    ZipEntryInfo ze;
+
+    /** Creates a new instance of ZipFileAttributes */
+    public ZipFileBasicAttributes(FileRef file)
+            throws IOException {
+        this.file = file;
+        ensureOpen();
+        ze = ZipUtils.getEntry(file);
+    }
+
+    void ensureOpen() {
+        if (file instanceof ZipFilePath && !((ZipFilePath) file).getFileSystem().isOpen()) {
+            throw new ClosedFileSystemException();
+        }
+    }
+
+    @Override
+    public long creationTime() {
+        return ze.createTime;
+    }
+
+    public boolean isDirectory() {
+        return ze.isDirectory;
+    }
+
+    public boolean isLink() {
+        return false;
+    }
+
+    public boolean isOther() {
+        return ze.isOtherFile;
+    }
+
+    public boolean isRegularFile() {
+        return ze.isRegularFile;
+    }
+
+    public long lastAccessTime() {
+        return ze.lastAccessTime;
+    }
+
+    public long lastModifiedTime() {
+        long time = ze.lastModifiedTime;
+        Calendar cal = dosTimeToJavaTime(time);
+        return cal.getTimeInMillis();
+    }
+
+    private Calendar dosTimeToJavaTime(long time) {
+        Calendar cal = Calendar.getInstance();
+        cal.set((int) (((time >> 25) & 0x7f) + 1980),
+                (int) (((time >> 21) & 0x0f) - 1),
+                (int) ((time >> 16) & 0x1f),
+                (int) ((time >> 11) & 0x1f),
+                (int) ((time >> 5) & 0x3f),
+                (int) ((time << 1) & 0x3e));
+        return cal;
+    }
+
+    public int linkCount() {
+        return 0;
+    }
+
+    public TimeUnit resolution() {
+        return TimeUnit.MILLISECONDS;
+    }
+
+    public long size() {
+        return ze.size;
+    }
+
+    public boolean isSymbolicLink() {
+        return false;
+    }
+
+    public Object fileKey() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileEntry.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.sun.nio.zipfs;
+
+import java.nio.file.*;
+
+public class ZipFileEntry extends ZipFilePath
+        implements DirectoryEntry {
+
+    /*each entry of zip file is a zip */
+    public ZipFileEntry(ZipFileSystem fs, byte[] path) {
+        super(fs, path);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFilePath.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,1024 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.sun.nio.zipfs;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.file.*;
+import java.nio.file.DirectoryStream.Filter;
+import java.nio.file.WatchEvent.Type;
+import java.nio.file.attribute.Attribute;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.spi.*;
+import java.util.*;
+import java.nio.file.attribute.*;
+import java.net.URI;
+import java.nio.channels.FileChannel;
+import java.nio.file.attribute.Attributes;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.nio.file.spi.AbstractPath;
+
+/**
+ * Jar/Zip path implementation of Path
+ * We use "/" as the Zip File entry seperator.
+ * @author      Rajendra Gutupalli,Jaya Hangal
+ */
+public class ZipFilePath extends AbstractPath {
+
+    private ZipFileSystem fileSystem;
+    //zip file separator
+    public static final String separator = "/";
+    // path inside zip and it can contain nested zip/jar paths
+    private final byte[] path;
+    // array of offsets of components in path - created lazily
+    private volatile ArrayList<Integer> offsets;
+    // array of offsets of entry elements in the path
+    private volatile ArrayList<Integer> entryOffsets;
+    // resolved path for locating zip inside zip file
+    // resloved path does not contain ./ and .. components
+    private final byte[] pathForZip;
+    private final ReadLock readLock = new ReentrantReadWriteLock().readLock();
+    private ZipFilePath pathToZip;
+    private final byte[] pathForprint;
+
+    // package-private
+    ZipFilePath(ZipFileSystem fileSystem, byte[] pathInZip) {
+        this.fileSystem = fileSystem;
+        this.path = pathInZip;
+        this.pathForprint = pathInZip;
+        boolean isAbs = (path[0] == '/');
+        String toResolve = new String(path);
+        if (!isAbs) {
+            String defdir = fileSystem.getDefaultDir();
+            boolean endsWith = defdir.endsWith("/");
+            if (endsWith) {
+                toResolve = defdir + toResolve;
+            } else {
+                toResolve = defdir + "/" + toResolve;
+            }
+
+        }
+        pathForZip = ZipPathParser.resolve(toResolve).getBytes();
+    }
+    // if given path is resolved
+    ZipFilePath(ZipFileSystem fileSystem, byte[] pathInZip, byte[] pathForZip) {
+        this.fileSystem = fileSystem;
+        this.path = pathForZip;
+        this.pathForZip = pathForZip;
+        this.pathForprint = pathInZip; //given path
+    }
+
+    public boolean isNestedZip() {
+        Pattern pattern = Pattern.compile("\\.(?i)(zip|jar)");
+        Matcher matcher = null;
+        for (int i = 0; i < getNameCount(); i++) {
+            String entry = getName(i).toString();
+            matcher = pattern.matcher(entry);
+            if (matcher.find()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public boolean isArchiveFile() {
+        Path name = getName();
+        if (name == null) {
+            return false;
+        }
+        String fileName = name.toString().toLowerCase();
+        return (fileName.endsWith(".zip") || fileName.endsWith(".jar"));
+    }
+
+    /**
+     * A path represents directory if it ends with '/'.
+     * The normalize method does not remove the trailing '/'
+     */
+    public boolean isDirectory() {
+        try {
+            begin();
+            try {
+                ZipFilePath resolved = getResolvedPathForZip();
+                return Attributes.readBasicFileAttributes(resolved, false).isDirectory();
+            } catch (IOException e) {
+                return false;
+            }
+        } finally {
+            end();
+        }
+    }
+
+    static int nextSeparator(byte[] path, int index) {
+
+        int length = path.length;
+
+        while (index < length && path[index] != '/') {
+            index++;
+        }
+        return index;
+    }
+
+    final void begin() {
+        readLock.lock();
+        if (!fileSystem.isOpen()) {
+            throw new ClosedFileSystemException();
+        }
+    }
+
+    final void end() {
+        readLock.unlock();
+    }
+
+    static int nextNonSeparator(byte[] path, int index) {
+
+        int length = path.length;
+        while (index < length && path[index] == '/') {
+            index++;
+        }
+        return index;
+    }
+
+    // create offset list if not already created
+    private void initOffsets() {
+        if (offsets == null) {
+            ArrayList<Integer> list = new ArrayList<Integer>();
+            int pathLen = path.length;
+            int index = nextNonSeparator(path, 0) - 1;
+
+            int root = index;
+
+            while ((index = nextSeparator(path, index + 1)) < pathLen && (index + 1 != pathLen)) {
+                list.add(index + 1); // puls 1 for file separator
+            }
+
+            if (root + 1 < index) { // begin index
+                list.add(0, root + 1);
+            }
+
+            offsets = list;
+        }
+
+    }
+
+    private void initEntryOffsets() {
+        if (entryOffsets == null) {
+
+            ArrayList<Integer> list1 = new ArrayList<Integer>();
+            int count = getNameCount();
+            Pattern pattern = Pattern.compile("\\.(?i)(zip|jar)");
+            Matcher matcher = null;
+            int i = 0;
+            int off = 0;
+            while (i < (count - 1)) {
+                String name = getName(i).toString();
+                matcher = pattern.matcher(name);
+                if (matcher.find()) {
+                    off = offsets.get(i + 1);
+                    list1.add(off);
+                }
+                i++;
+
+            }
+            if (count > 0) {
+                int firstNonSeparatorIndex = nextNonSeparator(path, 0);
+                list1.add(0, firstNonSeparatorIndex);
+            }
+            entryOffsets = list1;
+
+        }
+    }
+
+    @Override
+    public ZipFilePath getRoot() {
+        if (this.isAbsolute()) {
+            return new ZipFilePath(this.fileSystem, new byte[]{path[0]});
+        } else {
+            return null;
+        }
+    }
+
+    @Override
+    public Path getName() {
+        initOffsets();
+        if (offsets.size() == 0) {
+            return null;
+        }
+        String result = subString(offsets.get(offsets.size() - 1), path.length);
+        result = (result.endsWith("/")) ? result.substring(0, result.length() - 1) : result;
+        return new ZipFilePath(this.fileSystem, result.getBytes());
+
+    }
+
+    public ZipFilePath getEntryName() {
+        initEntryOffsets();
+        if (entryOffsets.size() == 0) {
+            return null;
+        }
+        String result = subString(entryOffsets.get(entryOffsets.size() - 1), path.length);
+        result = (result.endsWith("/")) ? result.substring(0, result.length() - 1) : result;
+        return new ZipFilePath(this.fileSystem, result.getBytes());
+
+    }
+
+    ZipFileEntry getPathAsEntry() {
+        return new ZipFileEntry(fileSystem, path);
+    }
+
+    @Override
+    public ZipFilePath getParent() {
+        int count = getNameCount();
+        if (count == 0 || count == 1) {
+            return null;
+        }
+        int position = offsets.get(count - 1);
+        String parent = subString(0, position - 1);
+        return new ZipFilePath(this.fileSystem, parent.getBytes());
+
+    }
+
+    public ZipFilePath getParentEntry() {
+        int entryCount = getEntryNameCount();
+        if (entryCount == 0 || entryCount == 1) {
+            return null;
+        }
+        int position = entryOffsets.get(entryCount - 1);
+        String parent = subString(0, position - 1);
+        byte[] parentBytes = parent.getBytes();
+        ZipFilePath path1 = new ZipFilePath(this.fileSystem, parentBytes);
+        return path1;
+    }
+
+    @Override
+    public int getNameCount() {
+
+        initOffsets();
+        return offsets.size();
+    }
+
+    public int getEntryNameCount() {
+
+        initEntryOffsets();
+        return entryOffsets.size();
+    }
+
+    @Override
+    public ZipFilePath getName(int index) {
+
+
+        initOffsets();
+        if (index < 0 || index >= offsets.size()) {
+            throw new IllegalArgumentException();
+        }
+        if (index == offsets.size() - 1) {
+            String s = subString(offsets.get(index), path.length);
+            s = (s.endsWith("/")) ? s.substring(0, s.length() - 1) : s;
+            return new ZipFilePath(this.fileSystem, s.getBytes());
+        }
+        byte[] pathInBytes = subString(offsets.get(index), offsets.get(index + 1) - 1).getBytes();
+        return new ZipFilePath(this.fileSystem, pathInBytes);
+    }
+
+    public ZipFilePath getEntryName(int index) {
+
+        initEntryOffsets();
+        if (index < 0 || index >= entryOffsets.size()) {
+            throw new IllegalArgumentException();
+        }
+        if (index == entryOffsets.size() - 1) {
+            String s = subString(entryOffsets.get(index), path.length);
+            s = (s.endsWith("/")) ? s.substring(0, s.length() - 1) : s;
+            return new ZipFilePath(this.fileSystem, s.getBytes());
+        }
+        byte[] pathInBytes = subString(entryOffsets.get(index), entryOffsets.get(index + 1) - 1).getBytes();
+        return new ZipFilePath(this.fileSystem, pathInBytes);
+    }
+
+    String subString(int beginIndex, int endIndex) {
+        int length = endIndex - beginIndex;
+        byte[] arr = new byte[length];
+        System.arraycopy(path, beginIndex, arr, 0, length);
+        return new String(arr);
+    }
+
+    @Override
+    public ZipFilePath subpath(int beginIndex, int endIndex) {
+
+        initOffsets();
+        if (beginIndex < 0) {
+            throw new IllegalArgumentException();
+        }
+        if (beginIndex >= (1 + offsets.size())) {
+            throw new IllegalArgumentException();
+        }
+        if (endIndex > (1 + offsets.size())) {
+            throw new IllegalArgumentException();
+        }
+        if (beginIndex >= endIndex) {
+            throw new IllegalArgumentException();
+        }
+
+        int elements = endIndex - beginIndex;
+        String result = null;
+        StringBuffer result1 = new StringBuffer("");
+        int index = beginIndex;
+        for (; elements-- != 0;) {
+            if (endIndex == offsets.size() && elements == 0) {
+                result1.append(subString(offsets.get(index), path.length));
+                break;
+            }
+            result1.append(subString(offsets.get(index), offsets.get(++index)));
+        }
+        result = result1.toString();
+        result = (result.endsWith("/")) ? result.substring(0, result.length() - 1) : result;
+        return new ZipFilePath(fileSystem, result.getBytes());
+    }
+
+    public ZipFilePath subEntryPath(int beginIndex, int endIndex) {
+
+        initEntryOffsets();
+        if (beginIndex < 0) {
+            throw new IllegalArgumentException();
+        }
+        if (beginIndex >= (1 + entryOffsets.size())) {
+            throw new IllegalArgumentException();
+        }
+        if (endIndex > (1 + entryOffsets.size())) {
+            throw new IllegalArgumentException();
+        }
+        if (beginIndex >= endIndex) {
+            throw new IllegalArgumentException();
+        }
+
+        int elements = endIndex - beginIndex;
+        String result = null;
+        StringBuffer result1 = new StringBuffer("");
+        int index = beginIndex;
+
+        for (; elements-- != 0;) {
+            if (endIndex == entryOffsets.size() && elements == 0) {
+                result1.append(subString(entryOffsets.get(index), path.length));
+                break;
+            }
+            result1.append(subString(entryOffsets.get(index), entryOffsets.get(++index)));
+        }
+        result = result1.toString();
+        result = (result.endsWith("/")) ? result.substring(0, result.length() - 1) : result;
+        return new ZipFilePath(fileSystem, result.getBytes());
+    }
+
+    @Override
+    public ZipFilePath toRealPath(boolean resolveLinks) throws IOException {
+        ZipFilePath realPath = new ZipFilePath(this.fileSystem, pathForZip);
+        realPath.checkAccess(Access.EXISTS);
+        return realPath;
+    }
+
+    @Override
+    public ZipFilePath toAbsolutePath() {
+        if (isAbsolute()) {
+            return this;
+        } else {
+            //add / bofore the existing path
+            byte[] defaultdir = fileSystem.getDefaultDir().getBytes();
+            int defaultlen = defaultdir.length;
+            boolean endsWith = (defaultdir[defaultlen - 1] == '/');
+            byte[] t = null;
+            if (endsWith) {
+                t = new byte[defaultlen + path.length];
+            } else {
+                t = new byte[defaultlen + 1 + path.length];
+            }
+
+            System.arraycopy(defaultdir, 0, t, 0, defaultlen);
+            if (!endsWith) {
+                t[defaultlen++] = '/';
+            }
+            System.arraycopy(path, 0, t, defaultlen, path.length);
+            return new ZipFilePath(this.fileSystem, t);
+        }
+
+    }
+
+    @Override
+    public URI toUri() {
+
+        String fullPath = fileSystem.getZipFileSystemFile();
+        if (File.separatorChar == '\\') {
+            fullPath = "/" + fullPath.replace("\\", "/"); // if Windows replace all separators by '/'
+        }
+        boolean endsWithSlash = (path[path.length - 1] == '/');  //
+        byte[] t = this.path;
+        if (!endsWithSlash) {
+            if (this.isArchiveFile() || this.isDirectory()) {
+                t = new byte[path.length + 1];
+                System.arraycopy(path, 0, t, 0, path.length);
+                t[t.length - 1] = '/';
+            }
+        }
+        String pathStr = new String(t);
+        if (!isAbsolute()) {
+            String defaultdir = fileSystem.getDefaultDir();
+            if (defaultdir.endsWith("/")) {
+                pathStr = defaultdir + pathStr;
+            } else {
+                pathStr = defaultdir + "/" + pathStr;
+            }
+        }
+        try {
+            return new URI("zip", "", fullPath, pathStr);
+        } catch (Exception ex) {
+            throw new AssertionError(ex);
+        }
+    }
+    // package private
+    URI toUri0() {
+        try {
+            String fullPath = fileSystem.getZipFileSystemFile();
+            if (File.separatorChar == '\\') {
+                fullPath = "/" + fullPath.replace("\\", "/"); // if Windows replace all separators by '/'
+            }
+            boolean endsWithSlash = (path.length > 1 && path[path.length - 1] == '/');  //0 for root
+            byte[] t = this.path;
+            if (!endsWithSlash && this.isArchiveFile()) {
+                t = new byte[path.length + 1];
+                System.arraycopy(path, 0, t, 0, path.length);
+                t[t.length - 1] = '/';
+            }
+            String pathStr = new String(t);
+            if (!isAbsolute()) {
+                String defaultdir = fileSystem.getDefaultDir();
+                if (defaultdir.endsWith("/")) {
+                    pathStr = defaultdir + pathStr;
+                } else {
+                    pathStr = defaultdir + "/" + pathStr;
+                }
+            }
+            return new URI("zip", "", fullPath, pathStr);
+        } catch (Exception ex) {
+            throw new AssertionError(ex);
+        }
+    }
+
+    @Override
+    public Path relativize(Path other) {
+        if (other == null) {
+            throw new NullPointerException();
+        }
+        if (!(other instanceof ZipFilePath)) {
+            throw new ProviderMismatchException();
+        }
+        ZipFilePath other1 = (ZipFilePath) other;
+        if (other1.equals(this)) {
+            return null;
+        }
+        if (this.isAbsolute() != other1.isAbsolute()) {
+            return other1;
+        }
+
+        int i = 0;
+        int ti = this.getNameCount();
+        int oi = other1.getNameCount();
+
+        for (; i < ti && i < oi; i++) {
+            if (!this.getName(i).equals(other1.getName(i))) {
+                break;
+            }
+        }
+        int nc = ti - i;
+        byte[] arr = new byte[nc * 3];
+        for (int j = 0; j < arr.length; j += 3) {
+            arr[j] = arr[j + 1] = '.';
+            arr[j + 2] = '/';
+        }
+        //contruct final path
+        ZipFilePath subPath = null;
+        int subpathlen = 0;
+        if (i < oi) {
+            subPath = other1.subpath(i, oi);
+            subpathlen = subPath.path.length;
+        }
+        byte[] result = new byte[arr.length + subpathlen];
+        if (nc > 0) {
+            System.arraycopy(arr, 0, result, 0, arr.length - 1);
+        }
+        if (subpathlen > 0) {
+            if (arr.length > 0) {
+                result[arr.length - 1] = '/';
+            }
+            System.arraycopy(subPath.path, 0, result, arr.length, subpathlen);
+        }
+        return new ZipFilePath(this.fileSystem, result);
+    }
+
+    //@Override
+    public ZipFileSystem getFileSystem() {
+        return fileSystem;
+    }
+
+    @Override
+    public boolean isAbsolute() {
+        return (this.path[0] == '/');
+    }
+
+    public ZipFilePath resolve(Path other) {
+        // zip/jar path are always absolute
+        if (other == null) {
+            throw new NullPointerException();
+        }
+        if (!(other instanceof ZipFilePath)) {
+            throw new ProviderMismatchException();
+        }
+        ZipFilePath other1 = (ZipFilePath) other;
+        if (other1.isAbsolute()) {
+            return other1;
+        }
+        byte[] resolved = null;
+        if (this.path[path.length - 1] == '/') {
+            resolved = new byte[path.length + other1.path.length];
+            System.arraycopy(path, 0, resolved, 0, path.length);
+            System.arraycopy(other1.path, 0, resolved, path.length, other1.path.length);
+        } else {
+            resolved = new byte[path.length + 1 + other1.path.length];
+            System.arraycopy(path, 0, resolved, 0, path.length);
+            resolved[path.length] = '/';
+            System.arraycopy(other1.path, 0, resolved, path.length + 1, other1.path.length);
+        }
+        return new ZipFilePath(this.fileSystem, resolved);
+    }
+
+    @Override
+    public ZipFilePath resolve(String other) {
+        return resolve(getFileSystem().getPath(other));
+    }
+
+    @Override
+    public boolean startsWith(Path other) {
+
+        ZipFilePath other1 = null;
+        if (other == null) {
+            throw new NullPointerException();
+        }
+        if (other instanceof ZipFilePath) {
+            other1 = (ZipFilePath) other;
+        }
+
+        int otherCount = other1.getNameCount();
+        if (getNameCount() < otherCount) {
+            return false;
+        }
+
+        for (int i = 0; i < otherCount; i++) {
+            if (other1.getName(i).equals(getName(i))) {
+                continue;
+            } else {
+                return false;
+            }
+        }
+        return true;
+
+    }
+
+    @Override
+    public boolean endsWith(Path other) {
+        ZipFilePath other1 = null;
+        if (other == null) {
+            throw new NullPointerException();
+        }
+        if (other instanceof ZipFilePath) {
+            other1 = (ZipFilePath) other;
+        }
+        int i = other1.getNameCount();
+        int j = getNameCount();
+
+        if (j < i) {
+            return false;
+        }
+
+        for (--i, --j; i >= 0; i--, j--) {
+            if (other1.getName(i).equals(getName(j))) {
+                continue;
+            } else {
+                return false;
+            }
+        }
+        return true;
+
+    }
+
+    public FileSystemProvider provider() {
+        return fileSystem.provider();
+    }
+
+    @Override
+    public String toString() {
+        return new String(pathForprint);
+    }
+
+    @Override
+    public int hashCode() {
+        int hashCode = 0;
+        int i = 0;
+
+        while (i < path.length) {
+            byte v = path[i];
+            hashCode = hashCode * 31 + (v);
+            i++;
+        }
+        return hashCode;
+
+    }
+
+    @Override
+    public boolean equals(Object ob) {
+        if ((ob != null) && (ob instanceof ZipFilePath)) {
+            return compareTo((Path) ob) == 0;
+        }
+        return false;
+    }
+
+    @Override
+    public int compareTo(Path other) {
+
+        ZipFilePath otherPath = (ZipFilePath) other;
+        //int c = zipPath.compareTo(otherPath.zipPath);
+
+        int len1 = path.length;
+        int len2 = otherPath.path.length;
+
+        int n = Math.min(len1, len2);
+        byte v1[] = path;
+        byte v2[] = otherPath.path;
+
+        int k = 0;
+        while (k < n) {
+            int c1 = v1[k];
+            int c2 = v2[k];
+            if (c1 != c2) {
+
+                return c1 - c2;
+            }
+            k++;
+        }
+        return len1 - len2;
+    }
+
+    @Override
+    public Path createSymbolicLink(
+            Path target, Attribute<?>... attrs) throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    public Path createLink(
+            Path existing) throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    public Path readSymbolicLink() throws IOException {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+
+    @Override
+    public Path createDirectory(
+            Attribute<?>... attrs) throws IOException {
+        throw new ReadOnlyFileSystemException();
+    }
+
+    ZipFilePath getResolvedPathForZip() {
+        if (pathToZip == null) {
+            pathToZip = new ZipFilePath(fileSystem, path, pathForZip);
+        }
+        return pathToZip;
+    }
+
+    @Override
+    public InputStream newInputStream() throws IOException {
+        try {
+            begin();
+            ZipFilePath realPath = getResolvedPathForZip();
+            if (realPath.getNameCount() == 0) {
+                throw new IOException("entry missing in the path");
+            } else {
+                String zf = getZipFile();
+                ZipFile zfile = new ZipFile(zf);
+                String entryStr = realPath.getEntryName(realPath.getEntryNameCount() - 1).toString();
+                ZipEntry entry = zfile.getEntry(entryStr);
+                if (entry == null) {
+                    zfile.close();
+                    throw new IOException("entry not found" + entryStr);
+                }
+                InputStream is = zfile.getInputStream(entry);
+                fileSystem.addCloseableObjects(is);
+                return is;
+            }
+        } finally {
+            end();
+        }
+
+    }
+
+    @Override
+    public OutputStream newOutputStream(
+            Set<? extends OpenOption> options, Attribute<?>... attrs) throws IOException {
+        throw new ReadOnlyFileSystemException();
+    }
+
+    @Override
+    public DirectoryStream newDirectoryStream(
+            Filter filter) throws IOException {
+        try {
+            begin();
+            return new ZipFileStream(getResolvedPathForZip(), filter);
+        } finally {
+            end();
+        }
+    }
+
+
+
+    @Override
+    public void delete(boolean failIfNotExists) throws IOException {
+        throw new ReadOnlyFileSystemException();
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileAttributeView> V newFileAttributeView(Class<V> type, boolean followLinks) {
+        FileAttributeView result = fileSystem.newFileAttributeView(type);
+        if (result == null) {
+            return null;
+        }
+
+        try {
+            return (V) result.bind(this, followLinks);
+        } catch (UnsupportedOperationException x) {
+            assert !followLinks;
+            return null;
+        }
+    }
+
+    @Override
+    public FileStore getFileStore() throws IOException {
+        try {
+            begin();
+            if (isAbsolute()) {
+                return ZipFileStore.create(getRoot());
+            } else {
+                return ZipFileStore.create(getResolvedPathForZip().getRoot());
+            }
+        } finally {
+            end();
+        }
+    }
+
+    @Override
+    public boolean isSameFile(FileRef other) throws IOException {
+
+        if ((other != null) && (other instanceof ZipFilePath)) {
+
+            // check both file systems are same.
+
+            ZipFilePath other1 = (ZipFilePath) other;
+            String fileSystem1 = this.getFileSystem().getZipFileSystemFile();
+            String fileSystem2 = other1.getFileSystem().getZipFileSystemFile();
+            boolean isSameFileSystem = fileSystem1.equals(fileSystem2);
+            if (!isSameFileSystem) {
+                return false;
+            }
+
+            // if file systems are same then do they exist
+            // finally compare the paths
+            // compare the real paths
+            ZipFilePath thisZip = this.toRealPath(false);
+            ZipFilePath otherZip = other1.toRealPath(false);
+            return (thisZip.startsWith(otherZip) && thisZip.endsWith(otherZip));
+        }
+        return false;
+
+    }
+
+    public WatchKey register(
+            WatchService watcher, Set<? extends Type> events) throws IOException {
+        if (events == null) {
+            throw new NullPointerException();
+        }
+        if (watcher == null) {
+            throw new NullPointerException();
+        } else {
+            throw new ProviderMismatchException();
+        }
+    }
+
+    @Override
+    public Iterator<Path> iterator() {
+        return new Iterator<Path>() {
+
+            private int i = 0;
+
+            @Override
+            public boolean hasNext() {
+                return (i < getNameCount());
+            }
+
+            @Override
+            public Path next() {
+                if (i < getNameCount()) {
+                    Path result = getName(i);
+                    i++;
+
+                    return result;
+                } else {
+                    throw new NoSuchElementException();
+                }
+
+            }
+
+            @Override
+            public void remove() {
+                throw new ReadOnlyFileSystemException();
+            }
+        };
+    }
+
+    @Override
+    public SeekableByteChannel newSeekableByteChannel(
+            Set<? extends OpenOption> options, Attribute<?>... attrs) throws IOException {
+
+        // check for options of null type and option is an intance of StandardOpenOption
+
+        for (OpenOption option : options) {
+            if (option == null) {
+                throw new NullPointerException();
+            }
+            if (!(option instanceof StandardOpenOption)) {
+                throw new IllegalArgumentException();
+            }
+        }
+        boolean openedForWriteOrAppend = options.contains(StandardOpenOption.WRITE) ||
+                options.contains(StandardOpenOption.APPEND);
+        if (openedForWriteOrAppend) {
+            throw new ReadOnlyFileSystemException();
+        }
+        boolean openedForRead = options.contains(StandardOpenOption.READ);
+        openedForRead = openedForRead || true; // if not opened for read then set openedForRed to true;
+
+        if (!openedForRead) {
+            throw new IllegalArgumentException("not opened for Read"); //this is never thrown
+        }
+        try {
+            begin();
+            ZipFilePath realPath = getResolvedPathForZip();
+            if (realPath.getNameCount() == 0) { //Need to Remove null check
+                throw new IOException("entry Not Found");
+            } else {
+                String zf = getZipFile();
+                ZipFile zfile = new ZipFile(zf);
+                String entryStr = realPath.getEntryName(realPath.getEntryNameCount() - 1).toString();
+                ZipEntry entry = zfile.getEntry(entryStr);
+                if (entry == null) {
+                    throw new IOException("entry not found" + entryStr);
+                }
+
+                InputStream in = zfile.getInputStream(entry);
+                Path pathtoZip = Path.get(ZipUtils.readFileInZip(in));
+                zfile.close();
+                SeekableByteChannel sbc = FileChannel.open(pathtoZip, options);
+                fileSystem.addCloseableObjects(sbc);
+                return sbc;
+            }
+        } finally {
+            end();
+        }
+
+    }
+
+    private String getZipFile() throws IOException {
+
+        String pathtoZip = null;
+        ZipFilePath realPath = getResolvedPathForZip();
+        int entryCount = realPath.getEntryNameCount();
+        if (realPath.isNestedZip()) {
+            if (realPath.isArchiveFile() && entryCount == 1) {
+                pathtoZip = this.fileSystem.getZipFileSystemFile();
+            } else {
+                pathtoZip = ZipUtils.extractNestedZip(realPath.getParentEntry()).toString();
+            }
+        } else {
+            pathtoZip = this.fileSystem.getZipFileSystemFile();
+        }
+
+        return pathtoZip;
+    }
+
+    @Override
+    public void checkAccess(Access requested) throws IOException {
+
+        if (requested == null) {
+            throw new NullPointerException();
+        }
+        try {
+            begin();
+            ZipFilePath resolvedZipPath = getResolvedPathForZip();
+            int nameCount = resolvedZipPath.getNameCount();
+            if (nameCount == 0) {
+                throw new IOException("entry not found");
+            }
+            if (requested == Access.EXISTS) {
+                Map<FileRef, ZipEntryInfo> entries = null;
+                try {
+                    ZipUtils.getEntry(resolvedZipPath);
+                } catch (IOException e) {
+                    throw e;
+                }
+
+            }
+            if (requested == Access.READ) {
+                Map<FileRef, ZipEntryInfo> entries = null;
+                try {
+                    ZipEntryInfo ze = null;
+                    ze = ZipUtils.getEntry(resolvedZipPath);
+                    long attrs = ze.extAttrs;
+                    if (!((((attrs << 4) >> 24) & 0x10) == 0x10)) {
+                        throw new AccessDeniedException("read access denied for the file: " + this.toString());
+                    }
+                } catch (IOException e) {
+                    throw e;
+                }
+            }
+            if (requested == Access.WRITE) {
+                try {
+                    throw new AccessDeniedException("write access denied for the file: " + this.toString());
+                } catch (IOException e) {
+                    throw e;
+                }
+            }
+            if (requested == Access.EXECUTE) {
+                Map<FileRef, ZipEntryInfo> entries = null;
+                try {
+                    ZipEntryInfo ze = null;
+                    ze = ZipUtils.getEntry(resolvedZipPath);
+                    long attrs = ze.extAttrs;
+                    if (!((((attrs << 4) >> 24) & 0x04) == 0x04)) {
+                        throw new AccessDeniedException("execute access denied for the file: " + this.toString());
+                    }
+                } catch (IOException e) {
+                    throw e;
+                }
+            }
+        } finally {
+            end();
+        }
+    }
+
+    @Override
+    public Path collapse() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    protected void implCopyTo(Path target, CopyOption... options) throws IOException {
+        throw new ReadOnlyFileSystemException();
+    }
+
+    @Override
+    protected void implMoveTo(Path target, CopyOption... options) throws IOException {
+        throw new ReadOnlyFileSystemException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileStore.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.io.IOException;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.ProviderMismatchException;
+import java.nio.file.attribute.FileAttributeView;
+import java.nio.file.attribute.FileStoreAttributeView;
+import java.nio.file.attribute.FileStoreAttributeView;
+import java.nio.file.attribute.FileStoreSpaceAttributeView;
+import java.nio.file.attribute.FileStoreSpaceAttributes;
+import java.nio.file.attribute.Attributes;
+import java.nio.file.attribute.BasicFileAttributeView;
+import java.util.ArrayList;
+
+
+public class ZipFileStore extends FileStore {
+
+    private final ZipFilePath root;
+    private final String zipFileName;
+    private final String type = "zipfs";
+
+    ZipFileStore(ZipFilePath path) {
+        this.root = path;
+        zipFileName = path.getFileSystem().getZipFileSystemFile();
+    }
+
+    static FileStore create(ZipFilePath root) throws IOException {
+        return new ZipFileStore(root);
+    }
+
+    @Override
+    public String name() {
+        return zipFileName;
+    }
+
+    @Override
+    public String type() {
+        return type;
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return root.getFileSystem().isReadOnly();
+    }
+
+    @Override
+    public boolean supportsFileAttributeView(Class<? extends FileAttributeView> viewType) {
+        return (viewType == BasicFileAttributeView.class ||
+                viewType == ZipFileAttributeView.class ||
+                viewType == JarFileAttributeView.class);
+    }
+
+    @Override
+    public Iterable<Class<? extends FileStoreAttributeView>> getFileStoreAttributeViews() {
+        ArrayList<Class<? extends FileStoreAttributeView>> list = new ArrayList<Class<? extends FileStoreAttributeView>>();
+        list.add(ZipFileStoreAttributeView.class);
+        return list;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <V extends FileStoreAttributeView> V newFileStoreAttributeView(Class<V> viewType) {
+        if (viewType == FileStoreSpaceAttributeView.class) {
+            return (V) new ZipFileStoreAttributeView().bind(this);
+        }
+        return null;
+    }
+
+    private static class ZipFileStoreAttributeView implements FileStoreSpaceAttributeView {
+
+        ZipFileStore fileStore;
+
+        public FileStoreSpaceAttributeView bind(FileStore fs) {
+            if (fs != null && !(fs instanceof ZipFileStore)) {
+                throw new ProviderMismatchException();
+            }
+            fileStore = (ZipFileStore) fs;
+            return this;
+        }
+
+        public FileStoreSpaceAttributes readAttributes() throws IOException {
+            if (fileStore == null) {
+                throw new IllegalStateException();
+            }
+            // get the size of the zip file
+            String file = fileStore.name();
+            Path path = FileSystems.getDefault().getPath(file);
+            final long size = Attributes.readBasicFileAttributes(path, true).size();
+            return new FileStoreSpaceAttributes() {
+
+                public long totalSpace() {
+                    return size; // size of the zip/jar file
+                }
+
+                public long usableSpace() {
+                    return 0; // no usable space in zip/jar file
+                }
+
+                public long unallocatedSpace() {
+                    return 0; // no unallocated space in zip/jar file.
+                }
+            };
+
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileStream.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,166 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.sun.nio.zipfs;
+
+import java.nio.file.*;
+import java.nio.file.spi.*;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.Map;
+import java.io.IOException;
+import java.util.HashSet;
+
+public class ZipFileStream implements DirectoryStream {
+
+    private final ZipFilePath zipPath;
+    private final DirectoryStream.Filter filter;
+    private volatile boolean isOpen;
+    private final Object closeLock;
+    private Iterator<DirectoryEntry> iterator;
+
+    private class ZipFileEntryIterator implements
+            Iterator<DirectoryEntry> {
+
+        private boolean atEof;
+        private ZipFileEntry nextEntry;
+        private ZipFileEntry prevEntry;
+        private Iterator<ZipFileEntry> entryIterator;
+
+        ZipFileEntryIterator() throws IOException {
+            atEof = false;
+            Map<ZipFilePath, ZipEntryInfo> entries = null;
+            int nameCount = zipPath.getNameCount();
+            entries = ZipUtils.getEntries(zipPath);
+            Set<ZipFilePath> s = entries.keySet();
+            Set<ZipFileEntry> s1 = new HashSet<ZipFileEntry>();
+            for (ZipFilePath f : s) {
+
+                boolean b = f.startsWith(zipPath);
+                if ((nameCount + 1) > f.getNameCount() || !b) {
+                    continue;
+                }
+                ZipFilePath p = null;
+                p = zipPath.resolve(f.getName(nameCount));
+                ZipFileEntry entry = p.getPathAsEntry();
+                if (filter == null || filter.accept(entry)) {
+                    s1.add(entry);
+                }
+            }
+            if (s1.isEmpty()) {
+            // if there is no file keep quiet
+            }
+            entryIterator = s1.iterator();
+        }
+
+        @SuppressWarnings("unchecked")
+        private boolean accept(DirectoryEntry entry) {
+            return filter.accept(entry);
+        }
+
+        private ZipFileEntry readNextEntry() {
+            ZipFileEntry entry = null;
+            entry = entryIterator.next();
+            if ((filter == null) || accept(entry)) {
+                return entry;
+            }
+            return null;
+        }
+
+        public synchronized boolean hasNext() {
+            boolean isThereNext = entryIterator.hasNext();
+            if (!isThereNext) {
+                atEof = true;
+            }
+            return isThereNext;
+        }
+
+        public synchronized ZipFileEntry next() {
+            if (nextEntry == null) {
+                if (!atEof) {
+                    nextEntry = readNextEntry();
+                }
+                if (nextEntry == null) {
+                    atEof = true;
+                    throw new NoSuchElementException();
+                }
+            }
+            prevEntry = nextEntry;
+            nextEntry = null;
+            return prevEntry;
+        }
+
+        public void remove() {
+            UnsupportedOperationException e = new UnsupportedOperationException();
+            e.initCause(new ReadOnlyFileSystemException());
+            throw e;
+        }
+    }
+
+    @Override
+    public Iterator<DirectoryEntry> iterator() {
+        synchronized (this) {
+            if (iterator != null) {
+                throw new IllegalStateException();
+            }
+            try {
+                iterator = new ZipFileEntryIterator();
+            } catch (IOException e) {
+                IllegalStateException ie = new IllegalStateException();
+                ie.initCause(e);
+                throw ie;
+            }
+            return iterator;
+        }
+    }
+
+    public void close() throws IOException {
+    // no impl
+    }
+
+    /** Creates a new instance of ZipFileStream */
+    public ZipFileStream(ZipFilePath zipPath,
+            DirectoryStream.Filter filter)
+            throws IOException {
+
+        if (zipPath.getNameCount() != 0) { // if path is '/' no need for check existence
+            zipPath.checkAccess(Access.EXISTS);
+        }
+
+        if (!zipPath.isArchiveFile() && !zipPath.isDirectory()) {
+            throw new NotDirectoryException("Not a Directory " + zipPath.toString());
+        }
+        this.zipPath = zipPath;
+        this.filter = filter;
+        this.isOpen = true;
+        this.closeLock = new Object();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystem.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,339 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.sun.nio.zipfs;
+
+import java.io.Closeable;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.*;
+import java.io.IOException;
+import java.net.URI;
+import java.nio.file.DirectoryStream.Filter;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Set;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+
+public class ZipFileSystem extends FileSystem {
+
+    private final ZipFileSystemProvider provider;
+    //path upto first zip file
+    // for example in Win c:/foo/bar.zip/a/b/c - zipFile represents c:/foo/bar.zip
+    // this contains real path following the links (change it, if no need to follow links)
+    private final String zipFile;
+    private final String defaultdir;
+    private final ReadWriteLock closeLock = new ReentrantReadWriteLock();
+    private boolean open = true;
+    private Set<Closeable> closeableObjects = new HashSet<Closeable>();
+
+    ZipFileSystem(ZipFileSystemProvider provider,
+            FileRef fref) {
+
+        this(provider, fref.toString(), "/");
+
+    }
+
+    ZipFileSystem(ZipFileSystemProvider provider, String path, String defaultDir) {
+        this.provider = provider;
+        this.zipFile = path;
+        this.defaultdir = defaultDir;
+    }
+
+    @Override
+    public FileSystemProvider provider() {
+        return provider;
+    }
+
+    @Override
+    public String getSeparator() {
+        return "/";
+    }
+
+    @Override
+    public boolean isOpen() {
+        return open;
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return true;
+    }
+
+    @Override
+    public void close() throws IOException {
+        closeLock.writeLock().lock();
+        URI root = null;
+        try {
+            if (!open) {
+                return;
+            }
+            root = getPath("/").toUri();
+            open = false;
+        } finally {
+            closeLock.writeLock().unlock();
+        }
+        implClose(root);
+    }
+
+    final void begin() {
+        closeLock.readLock().lock();
+        if (!isOpen()) {
+            throw new ClosedFileSystemException();
+        }
+    }
+
+    final void end() {
+        closeLock.readLock().unlock();
+    }
+    // Free all cached Zip/Jar files
+    private void implClose(URI root) throws IOException {
+        ZipUtils.remove(root); // remove cached filesystem
+        provider.removeFileSystem(root);
+        Iterator<Closeable> itr = closeableObjects.iterator();
+        while (itr.hasNext()) {
+            try {
+                itr.next().close();
+                itr.remove();
+            } catch (IOException e) {
+                throw e;
+            }
+        }
+    }
+
+    boolean addCloseableObjects(Closeable obj) {
+        return closeableObjects.add(obj);
+    }
+
+    @Override
+    public Iterable<Path> getRootDirectories() {
+        try {
+            begin();
+            ArrayList<Path> pathArr = new ArrayList<Path>();
+            ZipFilePath root = new ZipFilePath(this, new byte[]{'/'});
+            pathArr.add(root);
+            return pathArr;
+        } finally {
+            end();
+        }
+
+    }
+
+    String getDefaultDir() {
+        return defaultdir;
+    }
+
+    String getZipFileSystemFile() {
+        return zipFile;
+    }
+
+    @Override
+    public ZipFilePath getPath(String path) {
+
+        if (path == null) {
+            throw new NullPointerException();
+        }
+        if (path.equals("")) {
+            throw new InvalidPathException(path, "path should not be empty");
+        }
+        try {
+            begin();
+            byte[] parsedPath = ZipPathParser.normalize(path).getBytes();
+            return new ZipFilePath(this, parsedPath);
+        } finally {
+            end();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public Iterable<Class<? extends FileAttributeView>> getFileAttributeViews() {
+        try {
+            begin();
+            ArrayList list = new ArrayList();
+            list.add(ZipFileBasicAttributeView.class);
+            list.add(ZipFileAttributeView.class);
+            list.add(JarFileAttributeView.class);
+            return list;
+        } finally {
+            end();
+        }
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public <A extends FileAttributeView> A newFileAttributeView(Class<A> viewType) {
+        Class<?> c = viewType;
+        if (c == BasicFileAttributeView.class) {
+            return (A) new ZipFileBasicAttributeView();
+        }
+        if (c == ZipFileAttributeView.class) {
+            return (A) new ZipFileAttributeView();
+        }
+        if (c == JarFileAttributeView.class) {
+            return (A) new JarFileAttributeView();
+        }
+        return null;
+    }
+
+    @Override
+    public WatchService newWatchService() {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public Iterable<FileStore> getFileStores() {
+        try {
+            begin();
+            Iterator<Path> iterator = this.getRootDirectories().iterator();
+            final ZipFileStoreIterator zipIterator = new ZipFileStoreIterator(iterator);
+            return new Iterable<FileStore>() {
+
+                public Iterator<FileStore> iterator() {
+                    return zipIterator;
+                }
+            };
+        } finally {
+            end();
+        }
+    }
+
+    private static class ZipFileStoreIterator implements Iterator<FileStore> {
+
+        private final Iterator<Path> roots;
+        private FileStore next;
+
+        ZipFileStoreIterator(Iterator<Path> root) {
+            roots = root;
+        }
+
+        private FileStore readNext() {
+            for (;;) {
+                if (!roots.hasNext()) {
+                    return null;
+                }
+                try {
+                    ZipFilePath root = (ZipFilePath) roots.next();
+                    FileStore fs = ZipFileStore.create(root);
+                    if (fs != null) {
+                        return fs;
+                    }
+                } catch (IOException e) {
+
+                }
+            }
+        }
+
+        @Override
+        public synchronized boolean hasNext() {
+            if (next != null) {
+                return true;
+            }
+            next = readNext();
+            return (next != null);
+
+        }
+
+        public synchronized FileStore next() {
+            if (next == null) {
+                next = readNext();
+            }
+            if (next == null) {
+                throw new NoSuchElementException();
+            } else {
+                FileStore result = next;
+                next = null;
+                return result;
+            }
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException("");
+        }
+    }
+
+    @Override
+    public String toString() {
+        return getZipFileSystemFile();
+    }
+
+    @Override
+    public NameMatcher getNameMatcher(String syntaxAndPattern) {
+        String syntax = "glob";
+        String expr = "";
+        Filter filter = null;
+
+        int pos = syntaxAndPattern.indexOf(':');
+        if (pos == -1) {
+            expr = syntaxAndPattern;
+        } else {
+            syntax = syntaxAndPattern.substring(0, pos++);
+            if (pos == syntaxAndPattern.length()) {
+                throw new PatternSyntaxException("Pattern is empty", syntaxAndPattern, pos);
+            }
+            expr = syntaxAndPattern.substring(pos);
+        }
+
+        if (syntax.equalsIgnoreCase("glob")) {
+            filter = DirectoryStreamFilters.newCaseSensitiveGlobFilter(expr);
+        } else {
+            if (!syntax.equalsIgnoreCase("regex")) {
+                throw new ProviderMismatchException("Syntax '" + syntax +
+                        "' not recognized");
+            }
+        }
+        final Filter filter1 = filter;
+        // return matcher
+        Pattern pattern = null;
+        if (filter1 == null) {
+            pattern = Pattern.compile(expr);
+        }
+        final Pattern pattern1 = pattern;
+        return new NameMatcher() {
+
+            @Override
+            public boolean match(Path name) {
+                if (filter1 != null) {
+                    if (!(name instanceof ZipFilePath)) {
+                        throw new ProviderMismatchException();
+                    }
+                    ZipFilePath path = (ZipFilePath)name;
+                    return filter1.accept(path.getPathAsEntry());
+                }
+                return pattern1.matcher(name.toString()).matches();
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipFileSystemProvider.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.sun.nio.zipfs;
+
+import java.nio.file.*;
+import java.nio.file.spi.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+
+import java.net.URI;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.nio.channels.FileChannel;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class ZipFileSystemProvider
+        extends FileSystemProvider {
+
+    private String scheme = "zip";
+    private Map<URI, ZipFileSystem> fileSystems = new HashMap<URI, ZipFileSystem>();
+
+    public ZipFileSystemProvider() {
+    }
+
+    @Override
+    public String getScheme() {
+        return scheme;
+    }
+
+    @Override
+    public FileSystem newFileSystem(URI uri, Map<String, ?> env)
+            throws IOException {
+        String scheme1 = uri.getScheme();
+        if ((scheme1 == null) || !scheme1.equalsIgnoreCase(scheme)) {
+            throw new IllegalArgumentException("URI scheme is not '" + scheme + "'");
+        }
+
+        URI uriPath = null;
+        try {
+            uriPath = new URI("file", uri.getHost(), uri.getPath(), null);
+        } catch (URISyntaxException e) {
+            throw new AssertionError(e); //never thrown
+        }
+        Path nativePath = null;
+        try {
+            nativePath = Path.get(uriPath); //making use of underlying URI path parsing
+        } catch (InvalidPathException e) {
+            throw e;
+        }
+        if (!checkZipFilePath(nativePath)) {
+            throw new InvalidPathException(nativePath.toString(), "file name does not contain zip/jar File");
+        }
+        nativePath.checkAccess(Access.EXISTS); // check the existance of the path before proceed
+
+        ZipFileSystem fileSystem = null;
+        // construct uri to find in cached file systems
+        try {
+            uriPath = new URI("zip", uri.getHost(), uri.getPath(), null);
+        } catch (URISyntaxException e) {
+            throw new AssertionError(e); //never thrown
+        }
+        String pathStr = nativePath.toAbsolutePath().toString(); // think whether to pass .toRealPath(true) to follow links
+
+        String defaultdir = null;
+        Object obj = null;
+        if (env != null) {
+            obj = env.get("default.dir");
+            if ((obj != null) && !(obj instanceof String)) {
+                throw new IllegalArgumentException();
+            }
+            defaultdir = (String) obj;
+        }
+        if (defaultdir == null) {
+            defaultdir = "/";
+        }
+        if (defaultdir.charAt(0) != '/') {
+            throw new IllegalArgumentException("default dir should be absolute");
+        }
+        if (!defaultdir.equals("/")) {
+            defaultdir = ZipPathParser.normalize(defaultdir);
+        }
+        fileSystem = new ZipFileSystem(this, pathStr, defaultdir);
+        fileSystems.put(uriPath, fileSystem);
+        return fileSystem;
+    }
+
+    @Override
+    public FileSystem newFileSystem(FileRef file,
+            Map<String, ?> env)
+            throws IOException {
+        ZipFileSystem fileSystem = null;
+        if (!((Path) file).toUri().getScheme().equalsIgnoreCase("file")) {
+            throw new UnsupportedOperationException();
+        }
+        if (!checkZipFilePath(file)) {
+            throw new UnsupportedOperationException();
+        }
+        try {
+            ((Path) file).checkAccess(Access.EXISTS);
+        } catch (IOException e) {
+            throw e;
+        }
+        String pathStr = ((Path) file).toAbsolutePath().toString(); //follow links
+        String defaultdir = null;
+        Object obj = null;
+        if (env != null) {
+            obj = env.get("default.dir");
+            if ((obj != null) && !(obj instanceof String)) {
+                throw new IllegalArgumentException();
+            }
+            defaultdir = (String) obj;
+        }
+        if (defaultdir == null) {
+            defaultdir = "/";
+        }
+        if (defaultdir.charAt(0) != '/') {
+            throw new IllegalArgumentException("default dir should be absolute");
+        }
+        if (!defaultdir.equals("/")) {
+            defaultdir = ZipPathParser.normalize(defaultdir);
+        }
+        fileSystem = new ZipFileSystem(this, pathStr, defaultdir);
+        return fileSystem;
+    }
+
+    boolean checkZipFilePath(FileRef file) {
+        // check file ends with zip file
+        Path path = ((Path) file);
+        if (path.getName() == null) {
+            return false;
+        }
+        String fileName = path.getName().toString().toLowerCase();
+        boolean b = (fileName.endsWith(".zip") || fileName.endsWith(".jar"));
+        return (b);
+    }
+
+    @Override
+    public ZipFilePath getPath(URI uri) {
+
+        String scheme1 = uri.getScheme();
+
+        if ((scheme1 == null) || !scheme1.equalsIgnoreCase(scheme)) {
+            throw new IllegalArgumentException("URI scheme is not '" + scheme + "'");
+        }
+        String fragment = uri.getFragment();
+        if (fragment == null) {
+            throw new IllegalArgumentException("uri " + uri + " does not contain path fragment ex. zip:///c:/test.zip#/DirA");
+        }
+        URI uripath = null;
+        try {
+            uripath = new URI(uri.getScheme(), uri.getHost(), uri.getPath(), null);
+        } catch (URISyntaxException e) {
+            throw new AssertionError(e);
+        }
+        ZipFileSystem fileSystem = fileSystems.get(uripath);
+        if (fileSystem == null) {
+            throw new FileSystemNotFoundException();
+        }
+        // if fragment is empty, the following method throws InvalidPathException.
+        ZipFilePath path = fileSystem.getPath(fragment);
+        return path;
+    }
+
+    @Override
+    public FileChannel newFileChannel(Path path,
+            Set<? extends OpenOption> options,
+            Attribute<?>... attrs)
+            throws IOException {
+        FileSystem defFileSystem = FileSystems.getDefault();
+        Path nativePath = defFileSystem.getPath(path.toString());
+        return defFileSystem.provider().newFileChannel(nativePath, options);
+    }
+
+    @Override
+    public FileSystem getFileSystem(URI uri) {
+        String scheme1 = uri.getScheme();
+        if (scheme1 == null || !scheme.equalsIgnoreCase(getScheme())) {
+            throw new IllegalArgumentException("URI scheme is not '" + getScheme() + "'");
+        }
+        //construct uri ignoring fragement in the given URI
+        URI uriPath = null;
+        try {
+            uriPath = new URI("zip", uri.getHost(), uri.getPath(), null);
+        } catch (URISyntaxException e) {
+            throw new AssertionError(e); //never thrown
+        }
+        ZipFileSystem fileSystem = fileSystems.get(uriPath);
+        if (fileSystem == null) {
+            throw new FileSystemNotFoundException();
+        }
+        return fileSystem;
+    }
+
+    void removeFileSystem(URI uri) {
+        //construct uri ignoring fragement in the given URI
+        URI uriPath = null;
+        try {
+            uriPath = new URI("zip", uri.getHost(), uri.getPath(), null);
+        } catch (URISyntaxException e) {
+            throw new AssertionError(e); //never thrown
+        }
+        fileSystems.remove(uriPath);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipHeaderConstants.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+public class ZipHeaderConstants {
+
+    public static final int LOCAL_FILE_HDR_SIG = 0x04034b50;
+    public static final int CENTRAL_FILE_HDR_SIG = 0x02014b50;
+    public static final int END_CENTRAL_HDR_SIG = 0x06054b50;
+
+    // All offsets are in bytes
+
+    // Local File Header offsets
+    public static final long COMP_METHOD_OFF = 8;
+    public static final long COMP_SIZE_OFF = 18;
+    public static final long UCOMP_SIZE_OFF = COMP_SIZE_OFF + 4;
+    public static final long FILE_NAME_LEN_OFF = UCOMP_SIZE_OFF + 4;
+    public static final long EXTRA_FLD_LEN_OFF = FILE_NAME_LEN_OFF + 2;
+    public static final long FILE_NAME_OFF =  EXTRA_FLD_LEN_OFF + 2;
+
+    // File Header of Central Directory Structure
+    public static final long C_VER_MADE_BY  = 4;
+    public static final long C_COMP_METHOD_OFF = COMP_METHOD_OFF + 2;
+    public static final long C_LAST_MOD_TIME_OFF = C_COMP_METHOD_OFF + 2;
+    public static final long C_LAST_MOD_DATE_OFF = C_LAST_MOD_TIME_OFF + 2;
+    public static final long C_CRC_OFF =  C_LAST_MOD_DATE_OFF + 2;
+    public static final long C_COMP_SIZE_OFF =  C_CRC_OFF + 4;
+    public static final long C_UCOMP_SIZE_OFF = C_COMP_SIZE_OFF + 4;
+    public static final long C_FILE_NAME_LEN_OFF = C_UCOMP_SIZE_OFF + 4;
+    public static final long C_EXTRA_FLD_LEN_OFF = C_FILE_NAME_LEN_OFF + 2;
+    public static final long C_COMMENT_LEN_OFF = C_EXTRA_FLD_LEN_OFF + 2;
+    public static final long C_DISK_NO_OFF = C_COMMENT_LEN_OFF + 2;
+    public static final long C_INT_ATTR_OFF = C_DISK_NO_OFF + 2;
+    public static final long C_EXT_ATTR_OFF = C_INT_ATTR_OFF + 2;
+    public static final long C_REL_OFF_LOCAL_HDR_OFF = C_EXT_ATTR_OFF + 4;
+    public static final long C_FILE_NAME_OFF =  C_REL_OFF_LOCAL_HDR_OFF + 4;
+
+    // End of Central directory Record
+    public static final int C_COMMENT_LEN_BLEN = 2;
+    public static final int C_EXT_ATTR_BLEN = 4;
+
+    public static final long C_TOTAL_ENTRIES_OFF =10;
+    public static final int C_DIR_START_OFF = 16;
+
+    public static final int C_END_RECORD_MIN_OFF = 19;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipPathParser.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.sun.nio.zipfs;
+
+import java.nio.file.InvalidPathException;
+import java.nio.file.Path;
+import java.util.LinkedList;
+import java.util.Stack;
+import java.util.regex.*;
+
+
+public class ZipPathParser {
+
+    public static final String invalidChars = "\":<>*?";
+
+    static class Result {
+
+        String zipFile;
+        byte[] pathInZip;
+
+        Result(String path, String pathInZip) {
+            this.zipFile = path;
+            this.pathInZip = pathInZip.getBytes();
+        }
+    }
+
+    static Result parse(String path) {
+
+        if (path == null) {
+            throw new NullPointerException();
+        }
+        if (path.equals("")) {
+            throw new InvalidPathException(path, "path should not be empty");
+        }
+        int prefixLen = getPrefixLen(path);
+
+        // We got the prefix length, and get all the components.
+        int off = findZipComponent(prefixLen, path);
+        if (off == -1) {
+            try {
+                Path.get(path); //if any invalid char includes in the
+            // path this statement throws IPE with specific position.
+            } catch (InvalidPathException e) {
+                throw new InvalidPathException("", e.getMessage()); //This reduces long stack trace
+            }
+            throw new InvalidPathException(path, "Archive Jar/Zip Not Found in the path");
+        }
+        String pathZip = path.substring(0, off);
+        Path pathUpToZip = Path.get(pathZip);
+        String nomalizedPathInZip = null;
+        if (off != path.length()) {
+            String pathInZip = path.substring(off, path.length());
+            nomalizedPathInZip = normalize(pathInZip);
+        } else {
+            nomalizedPathInZip = "/"; //Default path
+        }
+        return new Result(pathUpToZip.toString(), nomalizedPathInZip);
+    }
+    static char fileSepa = java.io.File.separatorChar;
+
+    static int getPrefixLen(String path) {
+
+        int pathLen = path.length();
+        if (pathLen == 0) {
+            return -1;
+        }
+        char ch0 = path.charAt(0);
+        if (pathLen > 0 && isSeparator(ch0)) {
+            if (pathLen > 1) {
+                char ch1 = path.charAt(1);
+                if (isSeparator(ch1) && fileSepa == '\\') {
+                    int off = 2;
+                    off = nextNonSeparator(path, off); //server comp begin index
+                    if (off == pathLen) {
+                        throw new InvalidPathException(path, "does not contain Server component");
+                    }
+                    off = nextSeparator(path, off); //server comp end index
+                    off = nextNonSeparator(path, off); //share comp begin index
+                    if (off == pathLen) {
+                        throw new InvalidPathException(path, "does not contain share");
+                    }
+                    off = nextSeparator(path, off); //share comp end index
+                    off = nextNonSeparator(path, off); // if any separators follows immediately
+                    return off; // comment the above line also works perfect.
+                }
+            }
+            int off = 1;
+            off = nextNonSeparator(path, off); // unix - all the preceding separators
+            return off; //you can comment the above line  incase you dont want
+        //prefix lenght upto first component of the path
+        } else if (pathLen > 1) {
+            if (fileSepa == '\\' && path.charAt(1) == ':') { // fileSepa check is needed
+                ch0 = Character.toUpperCase(ch0);            // as it is applicable only in Windows
+                if (ch0 >= 'A' && ch0 <= 'Z') {
+                    if (pathLen > 2 && isSeparator(path.charAt(2))) {
+                        int off = 2;
+                        off = nextNonSeparator(path, off); //if any separators follows after C:////
+                        return off;  //incase you comment the above line return 3
+                    } else {
+                        return 2;
+                    }
+                }
+                throw new InvalidPathException(path, "Invalid Prefix in Windows"); //Illegal Prefix in Windows
+            }
+            return 0; // path length >1 and No Prefix
+        }
+        return 0; //Path lenght=1 and it does not have any prefix
+    }
+
+    static int nextNonSeparator(String path, int off) {
+        int pathLen = path.length();
+        while ((off < pathLen) && isSeparator(path.charAt(off))) {
+            off++;
+        }
+        return off;
+    }
+
+    static int nextSeparator(String path, int off) {
+        int pathLen = path.length();
+        while ((off < pathLen) && !(isSeparator(path.charAt(off)))) {
+            off++;
+        }
+        return off;
+    }
+
+    static boolean isSeparator(char ch) {
+        if (fileSepa == '\\') {
+            return ((ch == '\\') || (ch == '/')); //in Windows file separator is \\ or /
+        } else {
+            return (ch == '/'); //in unix file separator is /
+        }
+    }
+
+    static LinkedList<String> getComponents(String path) {
+        LinkedList<String> compList = new LinkedList<String>();
+        if (path == null || path.equals("")) {
+            return compList;
+        }
+        int firstChar = path.charAt(0);
+        int prefix = (firstChar == '/') ? 1 : 0;
+        int compStartIndex = prefix; // prefix starts with componenent begin index
+        int compEndIndex = prefix;
+        int pathLen = path.length();
+
+        while (compEndIndex < pathLen) {
+            compStartIndex = nextNonSeparator(path, compEndIndex);
+            compEndIndex = nextSeparator(path, compStartIndex);
+            if (compStartIndex != compEndIndex) {
+                compList.add(path.substring(compStartIndex, compEndIndex));
+            }
+        }
+        return compList;
+
+    }
+
+    private static int findZipComponent(int prefixLen, String path) {
+        int compStartIndex = prefixLen; // prefix starts with componenent begin index
+        int compEndIndex = prefixLen;
+        int pathLen = path.length();
+
+        Pattern pattern = Pattern.compile("\\.(?i)(zip|jar)");
+        //".*\\.(?i)(\\Qzip\\E|\\Qjar\\E)[\\/]*"
+        Matcher matcher = null;
+        while (compEndIndex < pathLen) {
+            compStartIndex = nextNonSeparator(path, compEndIndex);
+            compEndIndex = nextSeparator(path, compStartIndex);
+            String pathComp = path.substring(compStartIndex, compEndIndex);
+            matcher = pattern.matcher(pathComp);
+            boolean b = matcher.find();
+            if (b) {
+                return compEndIndex;
+            }
+        }
+        return -1;
+    }
+
+    static String normalize(String pathInZip) {
+        int len = pathInZip.length();
+        char pathArr[] = new char[len];
+        pathInZip.getChars(0, len, pathArr, 0);
+
+        //Repleace all Separators \\ with Zip Separator /
+        //throws InavalidPathException in Windows and Unux if char is not valid
+        // in respective file systems.
+
+        for (int i = 0; i < len; i++) {
+            if (pathArr[i] == '\\') {
+                pathArr[i] = '/';
+            }
+            if (fileSepa == '\\') { //If Path is In Windows
+                if ((pathArr[i] < '\u0020') || (invalidChars.indexOf(pathArr[i]) != -1)) {
+                    throw new InvalidPathException(pathInZip, "Invalid char at " + i);
+                }
+                if ((i > 0) && (((pathArr[i] == '/') && (pathArr[i - 1] == ' ')) ||
+                        ((i == len - 1) && pathArr[i] == ' '))) {
+                    throw new InvalidPathException(pathInZip, "Trailing space at" + (i - 1));
+                }
+            } else if (fileSepa == '/') { //If path In In Unix
+                if (pathArr[i] == '\u0000') {
+                    throw new InvalidPathException(pathInZip, "Null char at" + i);
+                }
+            }
+        }
+
+        // Remove if any extra slashes
+        int size = len;
+        for (int i = 1; i < size; i++) {
+            if (pathArr[i] == '/' && pathArr[i - 1] == '/') {
+                System.arraycopy(pathArr, i, pathArr, i - 1, size - i);
+                size--;
+                i--;
+            }
+
+        }
+        return new String(pathArr).substring(0, size);
+
+
+    }
+
+    // Remove DotSlash(./) and resolve DotDot (..) components
+    static String resolve(String path) {
+
+        int len = path.length();
+        char pathArr[] = new char[len];
+        path.getChars(0, len, pathArr, 0);
+        //Remove ./ component ,Remove this if not necessary
+        char ch = pathArr[0];
+        int prefixPos = (ch == '/') ? 1 : 0;
+        int size = len;
+
+        for (int i = prefixPos + 1; i < size; i++) {
+            if ((pathArr[i] == '/' && pathArr[i - 1] == '.') &&
+                    (i == prefixPos + 1 || pathArr[i - 2] == '/')) {
+                System.arraycopy(pathArr, i + 1, pathArr, i - 1, size - (i + 1));
+                size -= 2;
+                i--;
+            }
+
+        }
+        //Remove final . if path has one. which is not needed for zip path
+        if ((size >= 2) && pathArr[size - 1] == '.' && pathArr[size - 2] == '/') {
+            System.arraycopy(pathArr, 0, pathArr, 0, size - 1);
+            size -= 1;
+        }
+
+        //Resolve ../ components
+        String pathStr = new String(pathArr, 0, size);
+        boolean prefix = pathStr.startsWith("/");
+        boolean endsWith = pathStr.endsWith("/");
+        LinkedList<String> compArr = getComponents(pathStr);
+        Stack<String> stack = new Stack<String>();
+        for (int i = 0; i < compArr.size(); i++) {
+            stack.push(compArr.get(i));
+            if (compArr.get(i).equals("..")) {
+                stack.pop();
+                if (i > 0 && stack.size() > 0) {
+                    stack.pop();
+                }
+            }
+        }
+        //Construct final path
+        StringBuffer resolved = (prefix) ? new StringBuffer("/") : new StringBuffer("");
+        for (String comp : stack) {
+            resolved.append(comp).append("/");
+
+        }
+
+        String resolvedPath = "";
+        if (!resolved.toString().equals("")) {
+            if (!endsWith && resolved.length() != 1) {
+                resolvedPath = resolved.substring(0, resolved.length() - 1);
+            } else {
+                resolvedPath = resolved.toString();
+            }
+        }
+        return (resolvedPath);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/demo/nio/ZipFileSystem/com/sun/nio/zipfs/ZipUtils.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,477 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *   - Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *
+ *   - Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ *   - Neither the name of Sun Microsystems nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.sun.nio.zipfs;
+
+import java.nio.file.*;
+import java.nio.channels.SeekableByteChannel;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import static com.sun.nio.zipfs.ZipHeaderConstants.*;
+import java.io.*;
+import java.net.URI;
+import java.nio.channels.FileChannel;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+import java.util.zip.*;
+
+/**
+ * This class implements static methods for reading the zip file contents
+ * It reads all the entries and caches them into a weak has map.
+ * Note that Zip reader may not work well for self extracting zips and
+ * other variants.
+ * This is a demo quality implementation, but can be enhanced easily.
+ */
+public class ZipUtils {
+
+    /**
+     * This map stores all the zip files that are extracted during the
+     * course of time when zip operations are performed on the zip file.
+     * The key for the map is the zip file reference.
+     * The zip file entries themselves are stored as map entries whose
+     * keys are zip file references to the entries.
+     */
+    public static Map<URI, Map<ZipFilePath, ZipEntryInfo>> cachedEntries =
+            new HashMap<URI, Map<ZipFilePath, ZipEntryInfo>>();
+    private static final boolean debug = true;
+    private static final FileSystem defFileSystem = FileSystems.getDefault();
+
+    static SeekableByteChannel open(FileRef fr) throws IOException {
+        Set<StandardOpenOption> options = new HashSet<StandardOpenOption>();
+        options.add(StandardOpenOption.READ);
+        return FileChannel.open((Path) fr, options);
+    }
+
+    private static ByteBuffer getHeaderField(
+            SeekableByteChannel ch, long offset, int nBytes)
+            throws IOException {
+        ByteBuffer buf = ByteBuffer.allocate(nBytes);
+        buf = buf.order(ByteOrder.LITTLE_ENDIAN);
+        ch.position(offset);
+        int read = ch.read(buf);
+        if (read <= 0) {
+            return null;
+        }
+        buf.flip();
+        return (buf);
+    }
+
+    private static int readInt(SeekableByteChannel ch, long offset)
+            throws IOException {
+        ByteBuffer buf = getHeaderField(ch, offset, 4);
+        return buf.getInt();
+    }
+
+    private static int readShort(SeekableByteChannel ch, long offset)
+            throws IOException {
+        ByteBuffer buf = getHeaderField(ch, offset, 2);
+        return buf.getShort();
+    }
+
+    private static byte[] readBytes(SeekableByteChannel ch, long offset, int len)
+            throws IOException {
+        ByteBuffer buf = getHeaderField(ch, offset, len);
+        return buf.array();
+    }
+
+    static long locateEndOfCentralDirRecord(
+            SeekableByteChannel ch, FileRef file)
+            throws IOException {
+
+        long fileLen = ch.size();
+        // read the file backwards 4 bytes at a time
+        long backOffset = fileLen - C_END_RECORD_MIN_OFF;
+        byte[] signature = new byte[]{0x06, 0x05, 0x4b, 0x50};
+        int matchedIndex = 0;
+        for (; (backOffset >= 0); backOffset--) {
+            ByteBuffer buf = getHeaderField(ch, backOffset, 1);
+            if (buf == null) {
+                break;
+            }
+            byte b;
+            if ((b = buf.get()) == signature[matchedIndex]) {
+                matchedIndex++;
+            } else {
+                matchedIndex = 0;
+            }
+            if (matchedIndex == 4) {
+                return backOffset; // this needs to be verified.
+            }
+        }
+        throw new IOException("Could not locate the central header");
+    }
+
+    /**
+     * logicalRef is the Logical file reference to the zip file.
+     * LogicalRef is of type: ZipFileRef
+     * <tt>file</tt> is the reference to the physical location of the file
+     * and is of type FileRef.
+     */
+    public static Map<ZipFilePath, ZipEntryInfo> fillEntries(
+            ZipFilePath zipPath, FileRef file)
+            throws IOException {
+
+        SeekableByteChannel ch = open(file);
+        ZipFileSystem m = zipPath.getFileSystem();
+        FileSystem fs = null;
+        Map<ZipFilePath, ZipEntryInfo> entries =
+                new HashMap<ZipFilePath, ZipEntryInfo>();
+
+        long endOfCentralDirOff = locateEndOfCentralDirRecord(ch, file);
+        int totalEntries = readShort(ch,
+                endOfCentralDirOff + C_TOTAL_ENTRIES_OFF);
+        long centralDirOff = readInt(ch,
+                endOfCentralDirOff + C_DIR_START_OFF);
+        Path fileName1 = zipPath.getName();
+        boolean isJar = false;
+        if (fileName1 != null) {
+            isJar = isJar(fileName1.toString());
+        } else {
+            isJar = isJar(zipPath.getFileSystem().getZipFileSystemFile());
+        }
+
+        for (int count = 0; count < totalEntries; count++) {
+            int sig;
+            if ((sig = readInt(ch, centralDirOff)) != CENTRAL_FILE_HDR_SIG) {
+                throw new IOException("Not the beginning of the central directory!");
+            }
+            ZipEntryInfo ze = new ZipEntryInfo();
+            JarEntryInfo jentry = null;
+            ze.versionMadeBy = readShort(ch, centralDirOff + C_VER_MADE_BY);
+            ze.method = readShort(ch, centralDirOff + C_COMP_METHOD_OFF);
+            ze.lastModifiedTime = readInt(ch, centralDirOff + C_LAST_MOD_TIME_OFF);
+            ze.crc = readInt(ch, centralDirOff + C_CRC_OFF);
+            ze.compSize = readInt(ch, centralDirOff + C_COMP_SIZE_OFF);
+            ze.size = readInt(ch, centralDirOff + C_UCOMP_SIZE_OFF);
+
+            int filenameLen = readShort(ch, centralDirOff + C_FILE_NAME_LEN_OFF);
+            int extraFieldLen = readShort(ch, centralDirOff + C_EXTRA_FLD_LEN_OFF);
+            int commentLen = readShort(ch, centralDirOff + C_COMMENT_LEN_OFF);
+
+            ze.extAttrs = readInt(ch, centralDirOff + C_EXT_ATTR_OFF);
+
+            // check which address the offset is relative to
+            ze.streamOffset = readInt(ch, centralDirOff + C_REL_OFF_LOCAL_HDR_OFF);
+            // the above line will give offset for the file name.
+
+            ze.filename = readBytes(ch, centralDirOff + C_FILE_NAME_OFF, filenameLen);
+            if (extraFieldLen > 0) {
+                ze.extraField = readBytes(ch, centralDirOff + C_FILE_NAME_OFF +
+                        filenameLen, extraFieldLen);
+            }
+            if (commentLen > 0) {
+                ze.comment = readBytes(ch, centralDirOff + C_FILE_NAME_OFF +
+                        filenameLen + extraFieldLen, commentLen);
+            }
+            centralDirOff = centralDirOff + C_FILE_NAME_OFF +
+                    filenameLen + extraFieldLen + commentLen;
+
+            ZipFilePath entryPath = null;
+            entryPath = zipPath.resolve(new String(ze.filename));
+
+            ze.isArchiveFile = entryPath.isArchiveFile();
+            ze.isDirectory = (entryPath.toString().endsWith("/") ? true : false);
+            ze.isRegularFile = !ze.isDirectory;
+            if (isJar) {
+                jentry = new JarEntryInfo(ze);
+                JarFile jarfile = new JarFile(file.toString());
+                Manifest manifest = jarfile.getManifest();
+                Attributes attrs = null;
+                if (manifest != null) {
+                    attrs = manifest.getMainAttributes();
+                }
+                if (attrs != null) {
+                    jentry.manifestMainAttrs = attrs.entrySet();
+                }
+                JarEntry jarentry = jarfile.getJarEntry(new String(ze.filename));
+                if (jarentry != null) {
+                    Attributes attributes = jarentry.getAttributes();
+                    if (attributes != null) {
+                        jentry.entryAttributs = attributes.entrySet();
+                    }
+                }
+            }
+            // cache the entry
+            if (!isJar) {
+                entries.put(entryPath, ze);
+            } else {
+                entries.put(entryPath, jentry);
+            }
+        }
+        ch.close();
+
+        //root entry
+
+        ZipEntryInfo rootentry = new ZipEntryInfo();
+        rootentry.isDirectory = true;
+        rootentry.isRegularFile = false;
+        JarEntryInfo jarRootEntry = null;
+        if (isJar) {
+            jarRootEntry = new JarEntryInfo(rootentry);
+        }
+        ZipFilePath root1 = zipPath.getRoot();
+        ZipFilePath root = (root1 == null) ? zipPath.toAbsolutePath().getRoot() : root1;
+        if (isJar) {
+            entries.put(root, jarRootEntry);
+        } else {
+            entries.put(root, rootentry);
+        }
+        return entries;
+    }
+
+    public static boolean isJar(String path) {
+        String lowerCase = path.toLowerCase();
+        return (lowerCase.endsWith(".jar"));
+
+    }
+
+    public static void extractZip(ZipFilePath f)
+            throws IOException {
+        Map<ZipFilePath, ZipEntryInfo> entries;
+        FileRef refToPhysicalZipFile = f;
+        if (f.isNestedZip()) {
+            refToPhysicalZipFile = extractNestedZip(f);
+        } else {
+            refToPhysicalZipFile = defFileSystem.getPath(f.getFileSystem().getZipFileSystemFile());//zp.zipPath;
+        }
+        entries = fillEntries(f, refToPhysicalZipFile);
+        cachedEntries.put(f.toUri0(), entries);
+    }
+
+    /**
+     *  getKey() returns path upto archive file if exists
+     *  otherwise path to Zip file in native filesytem
+     */
+    public static ZipFilePath getKey(ZipFilePath zp) {
+        int count = zp.getEntryNameCount();
+        if ((count == 0 || count == 1) && !zp.isArchiveFile()) { // / or /a/b/c
+            ZipFilePath root1 = zp.getRoot();
+            ZipFilePath root = (root1 == null) ? zp.toAbsolutePath().getRoot() : root1;
+            return root; //zp.zipPath;
+        }
+        if (count > 1 && !zp.isArchiveFile()) {  // /a.zip/e/f --> /a.zip
+            return zp.getParentEntry();
+        }
+        return zp; //no change /a.zip, /x/b.zip, /a.zip/b.zip, /a.zip/b.jar
+
+    }
+
+    /*
+     * Returns a map containing the all the entries of the given zip file
+     */
+    public static Map<ZipFilePath, ZipEntryInfo> getEntries(
+            ZipFilePath file)
+            throws IOException {
+
+        //getKey() returns path upto archive file if exists
+        //otherwise path to Zip file in native filesytem
+
+        ZipFilePath key = getKey(file);
+        Map<ZipFilePath, ZipEntryInfo> entries = cachedEntries.get(key.toUri0());
+        if (entries == null) {
+            extractZip(key);
+        }
+        entries = cachedEntries.get(key.toUri0());
+        if (entries == null) {
+
+            throw new IOException(
+                    "Zip entries for the file could not be found:" + key);
+        }
+        return entries;
+    }
+
+    /**
+     * Returns an entry refered by the given file reference
+     */
+    public static ZipEntryInfo getEntry(FileRef file1)
+            throws IOException {
+        Map<ZipFilePath, ZipEntryInfo> entries = null;
+        ZipEntryInfo ze = null;
+        ZipFilePath file = (ZipFilePath) file1;
+        int entryCount = file.getEntryNameCount();
+        if (file.isArchiveFile() && entryCount == 1) {
+            ZipFilePath root1 = file.getRoot();
+            ZipFilePath root = (root1 == null) ? (file.toAbsolutePath().getRoot()) : root1;
+            entries = ZipUtils.getEntries(root);
+            ze = getElement(entries, file);
+            ze.isDirectory = true; // Since it is Archive
+            ze.isRegularFile = false;
+        } else if (file.isArchiveFile() && entryCount > 1) {
+            ZipFilePath path = file.getParentEntry();
+            entries = ZipUtils.getEntries(path);
+            ze = getElement(entries, file);
+            ze.isDirectory = true; // Since it is Archive
+            ze.isArchiveFile = false;
+        } else {
+            entries = ZipUtils.getEntries(file);
+            ze = getElement(entries, file);
+        }
+        if (ze == null) {
+            throw new NoSuchFileException(
+                    "Zip file entry not found:" + file);
+        }
+        return ze;
+    }
+
+    static ZipEntryInfo getElement(Map<ZipFilePath, ZipEntryInfo> entries, ZipFilePath zfp)
+            throws IOException {
+
+        ZipEntryInfo zei = null;
+        zei = entries.get(zfp);
+        if (zei != null) {
+            if (zfp.getNameCount() == 0) { //zfp.equals(zfp.getRoot())
+                Path p = Path.get(zfp.getFileSystem().getZipFileSystemFile());
+                try {
+                    long time = java.nio.file.attribute.Attributes.readBasicFileAttributes(p, false).lastModifiedTime();
+                    zei.lastModifiedTime = javaTimeToDosTime(time);
+                } catch (IOException e) {
+                    throw e;
+                }
+            }
+            return zei;
+        }
+        for (ZipFilePath f : entries.keySet()) {
+            if (f.startsWith(zfp)) {
+                if (zfp.getNameCount() == f.getNameCount()) {
+                    zei = entries.get(f);
+                    return zei;
+                }
+            }
+        }
+        for (ZipFilePath f : entries.keySet()) {
+            if (f.startsWith(zfp)) {
+                if (zfp.getNameCount() < f.getNameCount()) {
+                    zei = new ZipEntryInfo(); //it is a path component in an entry,
+                    zei.isDirectory = true;   // jar/zip file won't contain any information
+                    zei.isRegularFile = false;  // about this dir component
+                    // Set directory as readable and executable
+                    zei.extAttrs = Integer.parseInt("-1111110101111111111111111111111", 2);
+                    boolean isJar = false;
+                    if (f.getEntryNameCount() > 1) {
+                        isJar = f.getParentEntry().getName().toString().toLowerCase().endsWith(".jar");
+                    } else {
+                        isJar = f.getFileSystem().getZipFileSystemFile().toLowerCase().endsWith(".jar");
+                    }
+                    if (isJar) {
+                        zei = new JarEntryInfo(zei);
+                    }
+                    return zei;
+                }
+            }
+        }
+        throw new NoSuchFileException("" + zfp); // no matching
+
+    }
+
+    private static long javaTimeToDosTime(long time) {
+        Calendar cal = Calendar.getInstance();
+        cal.setTimeInMillis(time);
+        int year = cal.get(Calendar.YEAR);
+        if (year < 1980) {
+            return ((1 << 21) | (1 << 16));
+        }
+        return ((year - 1980) << 25 | (cal.get(Calendar.MONTH) + 1) << 21 |
+                cal.get(Calendar.DAY_OF_MONTH) << 16 | cal.get(Calendar.HOUR_OF_DAY) << 11 | cal.get(Calendar.MINUTE) << 5 |
+                cal.get(Calendar.SECOND) >> 1);
+    }
+
+    static void remove(URI uri) {
+        cachedEntries.remove(uri);
+    }
+
+    /**
+     * Extract the nested zips in a given file reference
+     * by extracting the intermediate zip file contents to a temporary
+     * location of the Platform file system
+     */
+    static FileRef extractNestedZip(ZipFilePath f) throws IOException {
+
+
+        if (f.getEntryNameCount() == 0) {
+            return null;
+        }
+        String zipFile = f.getFileSystem().getZipFileSystemFile();
+        int end = f.getEntryNameCount();
+        ZipFile zfile = null;
+        for (int i = 0; i < end; i++) {
+            try {
+                String nestedZip = f.getEntryName(i).toString();
+                zfile = new ZipFile(zipFile);
+                ZipEntry entry = zfile.getEntry(nestedZip);
+                if (entry == null) {
+                    throw new IOException("Invalid Zip Entry:" + nestedZip);
+                }
+                zipFile = readFileInZip(zfile.getInputStream(entry));
+            } finally {
+                zfile.close();
+            }
+        }
+        FileSystem m = FileSystems.getDefault();
+        FileRef retrievedZip = m.getPath(zipFile);
+        return retrievedZip;
+    }
+
+    static String readFileInZip(InputStream entry) throws IOException {
+
+        File tmpFile = null;
+        try {
+            BufferedInputStream zipStream = new BufferedInputStream(
+                    entry);
+
+            // unzip the file contents to a temp directory
+            String prefix = "zipfs";
+            String suffix = String.valueOf((new Date()).getTime());
+            tmpFile = File.createTempFile(prefix, suffix);
+            FileOutputStream tmpOut = new FileOutputStream(tmpFile);
+            byte buf[] = new byte[1024];
+            int read;
+            int offset = 0;
+            while ((read = zipStream.read(buf)) > 0) {
+                tmpOut.write(buf, 0, read);
+                offset = offset + read;
+            }
+            zipStream.close();
+            tmpOut.close();
+            tmpFile.deleteOnExit();
+        } catch (IOException e) {
+            throw e;
+        }
+        return tmpFile.getAbsolutePath();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/demo/nio/ZipFileSystem/Sanity.java	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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 General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.file.spi.FileSystemProvider;
+import java.util.*;
+import java.net.URI;
+import java.io.IOException;
+
+/**
+ * Sanity check zip provider by running a few simple tests.
+ */
+
+public class Sanity {
+
+    public static void main(String[] args) throws Exception {
+        Path zipfile = Path.get(args[0]);
+
+        // Test: zip should should be returned in provider list
+        boolean found = false;
+        for (FileSystemProvider provider: FileSystemProvider.installedProviders()) {
+            if (provider.getScheme().equalsIgnoreCase("zip")) {
+                found = true;
+                break;
+            }
+        }
+        if (!found)
+            throw new RuntimeException("'zip' provider not installed");
+
+        // Test: FileSystems#newFileSystem(FileRef)
+        Map<String,?> env = new HashMap<String,Object>();
+        FileSystems.newFileSystem(zipfile, env, null).close();
+
+        // Test: FileSystems#newFileSystem(URI)
+        URI uri = URI.create("zip" + zipfile.toUri().toString().substring(4));
+        FileSystem fs = FileSystems.newFileSystem(uri, env, null);
+
+        // Test: exercise toUri method
+        String expected = uri.toString() + "#/foo";
+        String actual = fs.getPath("/foo").toUri().toString();
+        if (!actual.equals(expected)) {
+            throw new RuntimeException("toUri returned '" + actual +
+                "', expected '" + expected + "'");
+        }
+
+        // Test: exercise directory iterator and retrieval of basic attributes
+        Files.walkFileTree(fs.getPath("/"), new FileTreePrinter());
+
+        // Test: copy file from zip file to current (scratch) directory
+        Path source = fs.getPath("/META-INF/services/java.nio.file.spi.FileSystemProvider");
+        if (source.exists()) {
+            Path target = Path.get(source.getName().toString());
+            source.copyTo(target, StandardCopyOption.REPLACE_EXISTING);
+            try {
+                long s1 = Attributes.readBasicFileAttributes(source, true).size();
+                long s2 = Attributes.readBasicFileAttributes(target, true).size();
+                if (s2 != s1)
+                    throw new RuntimeException("target size != source size");
+            } finally {
+                target.delete(true);
+            }
+        }
+
+        // Test: FileStore
+        FileStore store = fs.getPath("/").getFileStore();
+        if (!store.supportsFileAttributeView(BasicFileAttributeView.class))
+            throw new RuntimeException("BasicFileAttributeView should be supported");
+
+        // Test: ClosedFileSystemException
+        fs.close();
+        if (fs.isOpen())
+            throw new RuntimeException("FileSystem should be closed");
+        try {
+            fs.getPath("/missing").checkAccess(Access.READ);
+        } catch (ClosedFileSystemException x) { }
+    }
+
+    // FileVisitor that pretty prints a file tree
+    static class FileTreePrinter implements FileVisitor {
+        private int indent = 0;
+
+        private void indent() {
+            StringBuilder sb = new StringBuilder(indent);
+            for (int i=0; i<indent; i++) sb.append(" ");
+            System.out.print(sb);
+        }
+
+        @Override
+        public FileVisitResult preVisitDirectory(FileRef dir, Path relPath) {
+            if (relPath != null) {
+                indent();
+                System.out.println(relPath.getName() + "/");
+                indent++;
+            }
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFile(FileRef file,
+                                         Path relPath,
+                                         BasicFileAttributes attrs)
+        {
+            indent();
+            System.out.print(relPath.getName());
+            if (attrs.isRegularFile())
+                System.out.format(" (%d)", attrs.size());
+            System.out.println();
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult postVisitDirectory(FileRef dir, Path relPath) {
+            if (relPath != null)
+                indent--;
+            return FileVisitResult.CONTINUE;
+        }
+
+        @Override
+        public FileVisitResult visitFileFailed(FileRef file,
+                                               Path relPath,
+                                               IOException exc)
+        {
+            throw new java.io.IOError(exc);
+        }
+
+        @Override
+        public FileVisitResult visitDirectoryFailed(FileRef dir,
+                                                    Path relPath,
+                                                    IOException exc)
+        {
+            throw new java.io.IOError(exc);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/demo/nio/ZipFileSystem/sanity.sh	Tue Jun 24 18:30:03 2008 +0100
@@ -0,0 +1,71 @@
+#
+# Copyright 2007-2008 Sun Microsystems, Inc.  All Rights Reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code 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 General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#
+
+# @test
+# @bug 4313887
+# @summary Sanity check ZipFileSystem demo
+# @build Sanity
+# @run shell sanity.sh
+
+if [ -z "${TESTJAVA}" ]; then
+    echo "Test must be run with jtreg"
+    exit 0
+fi
+
+ZIPFS="${TESTJAVA}/demo/nio/ZipFileSystem/ZipFileSystem.jar"
+if [ ! -r "${ZIPFS}" ]; then
+    echo "${ZIPFS} not found"
+    exit 0
+fi
+
+OS=`uname -s`
+case "$OS" in
+    Windows_* )
+        CLASSPATH="${TESTCLASSES};${ZIPFS}"
+        ;;
+    * )
+        CLASSPATH="${TESTCLASSES}:${ZIPFS}"
+        ;;
+esac
+export CLASSPATH
+
+failures=0
+
+go() {
+    echo ''
+    ${TESTJAVA}/bin/java $1 $2 $3 2>&1
+    if [ $? != 0 ]; then failures=`expr $failures + 1`; fi
+}
+
+# Run the tests
+
+go Sanity  "${ZIPFS}"
+
+#
+# Results
+#
+echo ''
+if [ $failures -gt 0 ];
+  then echo "$failures test(s) failed";
+  else echo "All test(s) passed"; fi
+exit $failures