/*
 * Copyright (c) 2009, 2021, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package jdk.nio.zipfs;

import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.Runtime.Version;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.channels.ReadableByteChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.channels.WritableByteChannel;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.file.spi.FileSystemProvider;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.*;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.jar.Attributes;
import java.util.jar.Manifest;
import java.util.regex.Pattern;
import java.util.zip.CRC32;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
import java.util.zip.ZipException;

import static java.lang.Boolean.TRUE;
import static java.nio.file.StandardCopyOption.COPY_ATTRIBUTES;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
import static java.nio.file.StandardOpenOption.APPEND;
import static java.nio.file.StandardOpenOption.CREATE;
import static java.nio.file.StandardOpenOption.CREATE_NEW;
import static java.nio.file.StandardOpenOption.READ;
import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING;
import static java.nio.file.StandardOpenOption.WRITE;
import static jdk.nio.zipfs.ZipConstants.*;
import static jdk.nio.zipfs.ZipUtils.*;

/**
 * A FileSystem built on a zip file
 *
 * @author Xueming Shen
 */
class ZipFileSystem extends FileSystem {
    // statics
    @SuppressWarnings("removal")
    private static final boolean isWindows = AccessController.doPrivileged(
        (PrivilegedAction<Boolean>)()->System.getProperty("os.name")
                                             .startsWith("Windows"));
    private static final byte[] ROOTPATH = new byte[] { '/' };
    private static final String PROPERTY_POSIX = "enablePosixFileAttributes";
    private static final String PROPERTY_DEFAULT_OWNER = "defaultOwner";
    private static final String PROPERTY_DEFAULT_GROUP = "defaultGroup";
    private static final String PROPERTY_DEFAULT_PERMISSIONS = "defaultPermissions";
    // Property used to specify the entry version to use for a multi-release JAR
    private static final String PROPERTY_RELEASE_VERSION = "releaseVersion";
    // Original property used to specify the entry version to use for a
    // multi-release JAR which is kept for backwards compatibility.
    private static final String PROPERTY_MULTI_RELEASE = "multi-release";

    private static final Set<PosixFilePermission> DEFAULT_PERMISSIONS =
        PosixFilePermissions.fromString("rwxrwxrwx");
    // Property used to specify the compression mode to use
    private static final String PROPERTY_COMPRESSION_METHOD = "compressionMethod";
    // Value specified for compressionMethod property to compress Zip entries
    private static final String COMPRESSION_METHOD_DEFLATED = "DEFLATED";
    // Value specified for compressionMethod property to not compress Zip entries
    private static final String COMPRESSION_METHOD_STORED = "STORED";

    private final ZipFileSystemProvider provider;
    private final Path zfpath;
    final ZipCoder zc;
    private final ZipPath rootdir;
    private boolean readOnly; // readonly file system, false by default

    // default time stamp for pseudo entries
    private final long zfsDefaultTimeStamp = System.currentTimeMillis();

    // configurable by env map
    private final boolean noExtt;        // see readExtra()
    private final boolean useTempFile;   // use a temp file for newOS, default
                                         // is to use BAOS for better performance
    private final boolean forceEnd64;
    private final int defaultCompressionMethod; // METHOD_STORED if "noCompression=true"
                                                // METHOD_DEFLATED otherwise

    // entryLookup is identity by default, will be overridden for multi-release jars
    private Function<byte[], byte[]> entryLookup = Function.identity();

    // POSIX support
    final boolean supportPosix;
    private final UserPrincipal defaultOwner;
    private final GroupPrincipal defaultGroup;
    private final Set<PosixFilePermission> defaultPermissions;

    private final Set<String> supportedFileAttributeViews;

    ZipFileSystem(ZipFileSystemProvider provider,
                  Path zfpath,
                  Map<String, ?> env) throws IOException
    {
        // default encoding for name/comment
        String nameEncoding = env.containsKey("encoding") ?
            (String)env.get("encoding") : "UTF-8";
        this.noExtt = "false".equals(env.get("zipinfo-time"));
        this.useTempFile  = isTrue(env, "useTempFile");
        this.forceEnd64 = isTrue(env, "forceZIP64End");
        this.defaultCompressionMethod = getDefaultCompressionMethod(env);
        this.supportPosix = isTrue(env, PROPERTY_POSIX);
        this.defaultOwner = initOwner(zfpath, env);
        this.defaultGroup = initGroup(zfpath, env);
        this.defaultPermissions = initPermissions(env);
        this.supportedFileAttributeViews = supportPosix ?
            Set.of("basic", "posix", "zip") : Set.of("basic", "zip");
        if (Files.notExists(zfpath)) {
            // create a new zip if it doesn't exist
            if (isTrue(env, "create")) {
                try (OutputStream os = Files.newOutputStream(zfpath, CREATE_NEW, WRITE)) {
                    new END().write(os, 0, forceEnd64);
                }
            } else {
                throw new NoSuchFileException(zfpath.toString());
            }
        }
        // sm and existence check
        zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ);
        @SuppressWarnings("removal")
        boolean writeable = AccessController.doPrivileged(
            (PrivilegedAction<Boolean>)()->Files.isWritable(zfpath));
        this.readOnly = !writeable;
        this.zc = ZipCoder.get(nameEncoding);
        this.rootdir = new ZipPath(this, new byte[]{'/'});
        this.ch = Files.newByteChannel(zfpath, READ);
        try {
            this.cen = initCEN();
        } catch (IOException x) {
            try {
                this.ch.close();
            } catch (IOException xx) {
                x.addSuppressed(xx);
            }
            throw x;
        }
        this.provider = provider;
        this.zfpath = zfpath;

        initializeReleaseVersion(env);
    }

    /**
     * Return the compression method to use (STORED or DEFLATED).  If the
     * property {@code commpressionMethod} is set use its value to determine
     * the compression method to use.  If the property is not set, then the
     * default compression is DEFLATED unless the property {@code noCompression}
     * is set which is supported for backwards compatibility.
     * @param env Zip FS map of properties
     * @return The Compression method to use
     */
    private int getDefaultCompressionMethod(Map<String, ?> env) {
        int result =
                isTrue(env, "noCompression") ? METHOD_STORED : METHOD_DEFLATED;
        if (env.containsKey(PROPERTY_COMPRESSION_METHOD)) {
            Object compressionMethod =  env.get(PROPERTY_COMPRESSION_METHOD);
            if (compressionMethod != null) {
                if (compressionMethod instanceof String) {
                    switch (((String) compressionMethod).toUpperCase()) {
                        case COMPRESSION_METHOD_STORED:
                            result = METHOD_STORED;
                            break;
                        case COMPRESSION_METHOD_DEFLATED:
                            result = METHOD_DEFLATED;
                            break;
                        default:
                            throw new IllegalArgumentException(String.format(
                                    "The value for the %s property must be %s or %s",
                                    PROPERTY_COMPRESSION_METHOD, COMPRESSION_METHOD_STORED,
                                    COMPRESSION_METHOD_DEFLATED));
                    }
                } else {
                    throw new IllegalArgumentException(String.format(
                            "The Object type for the %s property must be a String",
                            PROPERTY_COMPRESSION_METHOD));
                }
            } else {
                throw new IllegalArgumentException(String.format(
                        "The value for the %s property must be %s or %s",
                        PROPERTY_COMPRESSION_METHOD, COMPRESSION_METHOD_STORED,
                        COMPRESSION_METHOD_DEFLATED));
            }
        }
        return result;
    }

    // returns true if there is a name=true/"true" setting in env
    private static boolean isTrue(Map<String, ?> env, String name) {
        return "true".equals(env.get(name)) || TRUE.equals(env.get(name));
    }

    // Initialize the default owner for files inside the zip archive.
    // If not specified in env, it is the owner of the archive. If no owner can
    // be determined, we try to go with system property "user.name". If that's not
    // accessible, we return "<zipfs_default>".
    @SuppressWarnings("removal")
    private UserPrincipal initOwner(Path zfpath, Map<String, ?> env) throws IOException {
        Object o = env.get(PROPERTY_DEFAULT_OWNER);
        if (o == null) {
            try {
                PrivilegedExceptionAction<UserPrincipal> pa = ()->Files.getOwner(zfpath);
                return AccessController.doPrivileged(pa);
            } catch (UnsupportedOperationException | PrivilegedActionException e) {
                if (e instanceof UnsupportedOperationException ||
                    e.getCause() instanceof NoSuchFileException)
                {
                    PrivilegedAction<String> pa = ()->System.getProperty("user.name");
                    String userName = AccessController.doPrivileged(pa);
                    return ()->userName;
                } else {
                    throw new IOException(e);
                }
            }
        }
        if (o instanceof String) {
            if (((String)o).isEmpty()) {
                throw new IllegalArgumentException("Value for property " +
                        PROPERTY_DEFAULT_OWNER + " must not be empty.");
            }
            return ()->(String)o;
        }
        if (o instanceof UserPrincipal) {
            return (UserPrincipal)o;
        }
        throw new IllegalArgumentException("Value for property " +
                PROPERTY_DEFAULT_OWNER + " must be of type " + String.class +
            " or " + UserPrincipal.class);
    }

    // Initialize the default group for files inside the zip archive.
    // If not specified in env, we try to determine the group of the zip archive itself.
    // If this is not possible/unsupported, we will return a group principal going by
    // the same name as the default owner.
    @SuppressWarnings("removal")
    private GroupPrincipal initGroup(Path zfpath, Map<String, ?> env) throws IOException {
        Object o = env.get(PROPERTY_DEFAULT_GROUP);
        if (o == null) {
            try {
                PosixFileAttributeView zfpv = Files.getFileAttributeView(zfpath, PosixFileAttributeView.class);
                if (zfpv == null) {
                    return defaultOwner::getName;
                }
                PrivilegedExceptionAction<GroupPrincipal> pa = ()->zfpv.readAttributes().group();
                return AccessController.doPrivileged(pa);
            } catch (UnsupportedOperationException | PrivilegedActionException e) {
                if (e instanceof UnsupportedOperationException ||
                    e.getCause() instanceof NoSuchFileException)
                {
                    return defaultOwner::getName;
                } else {
                    throw new IOException(e);
                }
            }
        }
        if (o instanceof String) {
            if (((String)o).isEmpty()) {
                throw new IllegalArgumentException("Value for property " +
                        PROPERTY_DEFAULT_GROUP + " must not be empty.");
            }
            return ()->(String)o;
        }
        if (o instanceof GroupPrincipal) {
            return (GroupPrincipal)o;
        }
        throw new IllegalArgumentException("Value for property " +
                PROPERTY_DEFAULT_GROUP + " must be of type " + String.class +
            " or " + GroupPrincipal.class);
    }

    // Initialize the default permissions for files inside the zip archive.
    // If not specified in env, it will return 777.
    private Set<PosixFilePermission> initPermissions(Map<String, ?> env) {
        Object o = env.get(PROPERTY_DEFAULT_PERMISSIONS);
        if (o == null) {
            return DEFAULT_PERMISSIONS;
        }
        if (o instanceof String) {
            return PosixFilePermissions.fromString((String)o);
        }
        if (!(o instanceof Set)) {
            throw new IllegalArgumentException("Value for property " +
                PROPERTY_DEFAULT_PERMISSIONS + " must be of type " + String.class +
                " or " + Set.class);
        }
        Set<PosixFilePermission> perms = new HashSet<>();
        for (Object o2 : (Set<?>)o) {
            if (o2 instanceof PosixFilePermission) {
                perms.add((PosixFilePermission)o2);
            } else {
                throw new IllegalArgumentException(PROPERTY_DEFAULT_PERMISSIONS +
                    " must only contain objects of type " + PosixFilePermission.class);
            }
        }
        return perms;
    }

    @Override
    public FileSystemProvider provider() {
        return provider;
    }

    @Override
    public String getSeparator() {
        return "/";
    }

    @Override
    public boolean isOpen() {
        return isOpen;
    }

    @Override
    public boolean isReadOnly() {
        return readOnly;
    }

    private void checkWritable() {
        if (readOnly) {
            throw new ReadOnlyFileSystemException();
        }
    }

    void setReadOnly() {
        this.readOnly = true;
    }

    @Override
    public Iterable<Path> getRootDirectories() {
        return List.of(rootdir);
    }

    ZipPath getRootDir() {
        return rootdir;
    }

    @Override
    public ZipPath getPath(String first, String... more) {
        if (more.length == 0) {
            return new ZipPath(this, first);
        }
        StringBuilder sb = new StringBuilder();
        sb.append(first);
        for (String path : more) {
            if (path.length() > 0) {
                if (sb.length() > 0) {
                    sb.append('/');
                }
                sb.append(path);
            }
        }
        return new ZipPath(this, sb.toString());
    }

    @Override
    public UserPrincipalLookupService getUserPrincipalLookupService() {
        throw new UnsupportedOperationException();
    }

    @Override
    public WatchService newWatchService() {
        throw new UnsupportedOperationException();
    }

    FileStore getFileStore(ZipPath path) {
        return new ZipFileStore(path);
    }

    @Override
    public Iterable<FileStore> getFileStores() {
        return List.of(new ZipFileStore(rootdir));
    }

    @Override
    public Set<String> supportedFileAttributeViews() {
        return supportedFileAttributeViews;
    }

    @Override
    public String toString() {
        return zfpath.toString();
    }

    Path getZipFile() {
        return zfpath;
    }

    private static final String GLOB_SYNTAX = "glob";
    private static final String REGEX_SYNTAX = "regex";

    @Override
    public PathMatcher getPathMatcher(String syntaxAndInput) {
        int pos = syntaxAndInput.indexOf(':');
        if (pos <= 0 || pos == syntaxAndInput.length()) {
            throw new IllegalArgumentException();
        }
        String syntax = syntaxAndInput.substring(0, pos);
        String input = syntaxAndInput.substring(pos + 1);
        String expr;
        if (syntax.equalsIgnoreCase(GLOB_SYNTAX)) {
            expr = toRegexPattern(input);
        } else {
            if (syntax.equalsIgnoreCase(REGEX_SYNTAX)) {
                expr = input;
            } else {
                throw new UnsupportedOperationException("Syntax '" + syntax +
                    "' not recognized");
            }
        }
        // return matcher
        final Pattern pattern = Pattern.compile(expr);
        return (path)->pattern.matcher(path.toString()).matches();
    }

    @SuppressWarnings("removal")
    @Override
    public void close() throws IOException {
        beginWrite();
        try {
            if (!isOpen)
                return;
            isOpen = false;          // set closed
        } finally {
            endWrite();
        }
        if (!streams.isEmpty()) {    // unlock and close all remaining streams
            Set<InputStream> copy = new HashSet<>(streams);
            for (InputStream is : copy)
                is.close();
        }
        beginWrite();                // lock and sync
        try {
            AccessController.doPrivileged((PrivilegedExceptionAction<Void>)() -> {
                sync(); return null;
            });
            ch.close();              // close the ch just in case no update
                                     // and sync didn't close the ch
        } catch (PrivilegedActionException e) {
            throw (IOException)e.getException();
        } finally {
            endWrite();
        }

        synchronized (inflaters) {
            for (Inflater inf : inflaters)
                inf.end();
        }
        synchronized (deflaters) {
            for (Deflater def : deflaters)
                def.end();
        }

        beginWrite();                // lock and sync
        try {
            // Clear the map so that its keys & values can be garbage collected
            inodes = null;
        } finally {
            endWrite();
        }

        IOException ioe = null;
        synchronized (tmppaths) {
            for (Path p : tmppaths) {
                try {
                    AccessController.doPrivileged(
                        (PrivilegedExceptionAction<Boolean>)() -> Files.deleteIfExists(p));
                } catch (PrivilegedActionException e) {
                    IOException x = (IOException)e.getException();
                    if (ioe == null)
                        ioe = x;
                    else
                        ioe.addSuppressed(x);
                }
            }
        }
        provider.removeFileSystem(zfpath, this);
        if (ioe != null)
           throw ioe;
    }

    ZipFileAttributes getFileAttributes(byte[] path)
        throws IOException
    {
        beginRead();
        try {
            ensureOpen();
            IndexNode inode = getInode(path);
            if (inode == null) {
                return null;
            } else if (inode instanceof Entry) {
                return (Entry)inode;
            } else if (inode.pos == -1) {
                // pseudo directory, uses METHOD_STORED
                Entry e = supportPosix ?
                    new PosixEntry(inode.name, inode.isdir, METHOD_STORED) :
                    new Entry(inode.name, inode.isdir, METHOD_STORED);
                e.mtime = e.atime = e.ctime = zfsDefaultTimeStamp;
                return e;
            } else {
                return supportPosix ? new PosixEntry(this, inode) : new Entry(this, inode);
            }
        } finally {
            endRead();
        }
    }

    void checkAccess(byte[] path) throws IOException {
        beginRead();
        try {
            ensureOpen();
            // is it necessary to readCEN as a sanity check?
            if (getInode(path) == null) {
                throw new NoSuchFileException(toString());
            }

        } finally {
            endRead();
        }
    }

    void setTimes(byte[] path, FileTime mtime, FileTime atime, FileTime ctime)
        throws IOException
    {
        checkWritable();
        beginWrite();
        try {
            ensureOpen();
            Entry e = getEntry(path);    // ensureOpen checked
            if (e == null)
                throw new NoSuchFileException(getString(path));
            if (e.type == Entry.CEN)
                e.type = Entry.COPY;     // copy e
            if (mtime != null)
                e.mtime = mtime.toMillis();
            if (atime != null)
                e.atime = atime.toMillis();
            if (ctime != null)
                e.ctime = ctime.toMillis();
            update(e);
        } finally {
            endWrite();
        }
    }

    void setOwner(byte[] path, UserPrincipal owner) throws IOException {
        checkWritable();
        beginWrite();
        try {
            ensureOpen();
            Entry e = getEntry(path);    // ensureOpen checked
            if (e == null) {
                throw new NoSuchFileException(getString(path));
            }
            // as the owner information is not persistent, we don't need to
            // change e.type to Entry.COPY
            if (e instanceof PosixEntry) {
                ((PosixEntry)e).owner = owner;
                update(e);
            }
        } finally {
            endWrite();
        }
    }

    void setGroup(byte[] path, GroupPrincipal group) throws IOException {
        checkWritable();
        beginWrite();
        try {
            ensureOpen();
            Entry e = getEntry(path);    // ensureOpen checked
            if (e == null) {
                throw new NoSuchFileException(getString(path));
            }
            // as the group information is not persistent, we don't need to
            // change e.type to Entry.COPY
            if (e instanceof PosixEntry) {
                ((PosixEntry)e).group = group;
                update(e);
            }
        } finally {
            endWrite();
        }
    }

    void setPermissions(byte[] path, Set<PosixFilePermission> perms) throws IOException {
        checkWritable();
        beginWrite();
        try {
            ensureOpen();
            Entry e = getEntry(path);    // ensureOpen checked
            if (e == null) {
                throw new NoSuchFileException(getString(path));
            }
            if (e.type == Entry.CEN) {
                e.type = Entry.COPY;     // copy e
            }
            e.posixPerms = perms == null ? -1 : ZipUtils.permsToFlags(perms);
            update(e);
        } finally {
            endWrite();
        }
    }

    boolean exists(byte[] path) {
        beginRead();
        try {
            ensureOpen();
            return getInode(path) != null;
        } finally {
            endRead();
        }
    }

    boolean isDirectory(byte[] path) {
        beginRead();
        try {
            IndexNode n = getInode(path);
            return n != null && n.isDir();
        } finally {
            endRead();
        }
    }

    // returns the list of child paths of "path"
    Iterator<Path> iteratorOf(ZipPath dir,
                              DirectoryStream.Filter<? super Path> filter)
        throws IOException
    {
        beginWrite();    // iteration of inodes needs exclusive lock
        try {
            ensureOpen();
            byte[] path = dir.getResolvedPath();
            IndexNode inode = getInode(path);
            if (inode == null)
                throw new NotDirectoryException(getString(path));
            List<Path> list = new ArrayList<>();
            IndexNode child = inode.child;
            while (child != null) {
                // (1) Assume each path from the zip file itself is "normalized"
                // (2) IndexNode.name is absolute. see IndexNode(byte[],int,int)
                // (3) If parent "dir" is relative when ZipDirectoryStream
                //     is created, the returned child path needs to be relative
                //     as well.
                ZipPath childPath = new ZipPath(this, child.name, true);
                ZipPath childFileName = childPath.getFileName();
                ZipPath zpath = dir.resolve(childFileName);
                if (filter == null || filter.accept(zpath))
                    list.add(zpath);
                child = child.sibling;
            }
            return list.iterator();
        } finally {
            endWrite();
        }
    }

    void createDirectory(byte[] dir, FileAttribute<?>... attrs) throws IOException {
        checkWritable();
        beginWrite();
        try {
            ensureOpen();
            if (dir.length == 0 || exists(dir))  // root dir, or existing dir
                throw new FileAlreadyExistsException(getString(dir));
            checkParents(dir);
            Entry e = supportPosix ?
                new PosixEntry(dir, Entry.NEW, true, METHOD_STORED, attrs) :
                new Entry(dir, Entry.NEW, true, METHOD_STORED, attrs);
            update(e);
        } finally {
            endWrite();
        }
    }

    void copyFile(boolean deletesrc, byte[]src, byte[] dst, CopyOption... options)
        throws IOException
    {
        checkWritable();
        if (Arrays.equals(src, dst))
            return;    // do nothing, src and dst are the same

        beginWrite();
        try {
            ensureOpen();
            Entry eSrc = getEntry(src);  // ensureOpen checked

            if (eSrc == null)
                throw new NoSuchFileException(getString(src));
            if (eSrc.isDir()) {    // spec says to create dst dir
                createDirectory(dst);
                return;
            }
            boolean hasReplace = false;
            boolean hasCopyAttrs = false;
            for (CopyOption opt : options) {
                if (opt == REPLACE_EXISTING)
                    hasReplace = true;
                else if (opt == COPY_ATTRIBUTES)
                    hasCopyAttrs = true;
            }
            Entry eDst = getEntry(dst);
            if (eDst != null) {
                if (!hasReplace)
                    throw new FileAlreadyExistsException(getString(dst));
            } else {
                checkParents(dst);
            }
            // copy eSrc entry and change name
            Entry u = supportPosix ?
                new PosixEntry((PosixEntry)eSrc, Entry.COPY) :
                new Entry(eSrc, Entry.COPY);
            u.name(dst);
            if (eSrc.type == Entry.NEW || eSrc.type == Entry.FILECH) {
                u.type = eSrc.type;    // make it the same type
                if (deletesrc) {       // if it's a "rename", take the data
                    u.bytes = eSrc.bytes;
                    u.file = eSrc.file;
                } else {               // if it's not "rename", copy the data
                    if (eSrc.bytes != null)
                        u.bytes = Arrays.copyOf(eSrc.bytes, eSrc.bytes.length);
                    else if (eSrc.file != null) {
                        u.file = getTempPathForEntry(null);
                        Files.copy(eSrc.file, u.file, REPLACE_EXISTING);
                    }
                }
            } else if (eSrc.type == Entry.CEN && eSrc.method != defaultCompressionMethod) {

                /**
                 * We are copying a file within the same Zip file using a
                 * different compression method.
                 */
                try (InputStream in = newInputStream(src);
                     OutputStream out = newOutputStream(dst,
                             CREATE, TRUNCATE_EXISTING, WRITE)) {
                    in.transferTo(out);
                }
                u = getEntry(dst);
            }

            if (!hasCopyAttrs)
                u.mtime = u.atime= u.ctime = System.currentTimeMillis();
            update(u);
            if (deletesrc)
                updateDelete(eSrc);
        } finally {
            endWrite();
        }
    }

    // Returns an output stream for writing the contents into the specified
    // entry.
    OutputStream newOutputStream(byte[] path, OpenOption... options)
        throws IOException
    {
        checkWritable();
        boolean hasCreateNew = false;
        boolean hasCreate = false;
        boolean hasAppend = false;
        boolean hasTruncate = false;
        for (OpenOption opt : options) {
            if (opt == READ)
                throw new IllegalArgumentException("READ not allowed");
            if (opt == CREATE_NEW)
                hasCreateNew = true;
            if (opt == CREATE)
                hasCreate = true;
            if (opt == APPEND)
                hasAppend = true;
            if (opt == TRUNCATE_EXISTING)
                hasTruncate = true;
        }
        if (hasAppend && hasTruncate)
            throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
        beginRead();                 // only need a readlock, the "update()" will
        try {                        // try to obtain a writelock when the os is
            ensureOpen();            // being closed.
            Entry e = getEntry(path);
            if (e != null) {
                if (e.isDir() || hasCreateNew)
                    throw new FileAlreadyExistsException(getString(path));
                if (hasAppend) {
                    OutputStream os = getOutputStream(new Entry(e, Entry.NEW));
                    try (InputStream is = getInputStream(e)) {
                        is.transferTo(os);
                    }
                    return os;
                }
                return getOutputStream(supportPosix ?
                    new PosixEntry((PosixEntry)e, Entry.NEW, defaultCompressionMethod)
                        : new Entry(e, Entry.NEW, defaultCompressionMethod));
            } else {
                if (!hasCreate && !hasCreateNew)
                    throw new NoSuchFileException(getString(path));
                checkParents(path);
                return getOutputStream(supportPosix ?
                    new PosixEntry(path, Entry.NEW, false, defaultCompressionMethod) :
                    new Entry(path, Entry.NEW, false, defaultCompressionMethod));
            }
        } finally {
            endRead();
        }
    }

    // Returns an input stream for reading the contents of the specified
    // file entry.
    InputStream newInputStream(byte[] path) throws IOException {
        beginRead();
        try {
            ensureOpen();
            Entry e = getEntry(path);
            if (e == null)
                throw new NoSuchFileException(getString(path));
            if (e.isDir())
                throw new FileSystemException(getString(path), "is a directory", null);
            return getInputStream(e);
        } finally {
            endRead();
        }
    }

    private void checkOptions(Set<? extends OpenOption> options) {
        // 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();
        }
        if (options.contains(APPEND) && options.contains(TRUNCATE_EXISTING))
            throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
    }

    // Returns an output SeekableByteChannel for either
    // (1) writing the contents of a new entry, if the entry doesn't exist, or
    // (2) updating/replacing the contents of an existing entry.
    // Note: The content of the channel is not compressed until the
    // channel is closed
    private class EntryOutputChannel extends ByteArrayChannel {
        final Entry e;

        EntryOutputChannel(Entry e) {
            super(e.size > 0? (int)e.size : 8192, false);
            this.e = e;
            if (e.mtime == -1)
                e.mtime = System.currentTimeMillis();
            if (e.method == -1)
                e.method = defaultCompressionMethod;
            // store size, compressed size, and crc-32 in datadescriptor
            e.flag = FLAG_DATADESCR;
            if (zc.isUTF8())
                e.flag |= FLAG_USE_UTF8;
        }

        @Override
        public void close() throws IOException {
            super.beginWrite();
            try {
                if (!isOpen())
                    return;
                // will update the entry
                try (OutputStream os = getOutputStream(e)) {
                    os.write(toByteArray());
                }
                super.close();
            } finally {
                super.endWrite();
            }
        }
    }

    // Returns a Writable/ReadByteChannel for now. Might consider to use
    // newFileChannel() instead, which dump the entry data into a regular
    // file on the default file system and create a FileChannel on top of it.
    SeekableByteChannel newByteChannel(byte[] path,
                                       Set<? extends OpenOption> options,
                                       FileAttribute<?>... attrs)
        throws IOException
    {
        checkOptions(options);
        if (options.contains(StandardOpenOption.WRITE) ||
            options.contains(StandardOpenOption.APPEND)) {
            checkWritable();
            beginRead();    // only need a read lock, the "update()" will obtain
                            // the write lock when the channel is closed
            ensureOpen();
            try {
                Entry e = getEntry(path);
                if (e != null) {
                    if (e.isDir() || options.contains(CREATE_NEW))
                        throw new FileAlreadyExistsException(getString(path));
                    SeekableByteChannel sbc =
                            new EntryOutputChannel(supportPosix ?
                                new PosixEntry((PosixEntry)e, Entry.NEW) :
                                new Entry(e, Entry.NEW));
                    if (options.contains(APPEND)) {
                        try (InputStream is = getInputStream(e)) {  // copyover
                            byte[] buf = new byte[8192];
                            ByteBuffer bb = ByteBuffer.wrap(buf);
                            int n;
                            while ((n = is.read(buf)) != -1) {
                                bb.position(0);
                                bb.limit(n);
                                sbc.write(bb);
                            }
                        }
                    }
                    return sbc;
                }
                if (!options.contains(CREATE) && !options.contains(CREATE_NEW))
                    throw new NoSuchFileException(getString(path));
                checkParents(path);
                return new EntryOutputChannel(
                    supportPosix ?
                        new PosixEntry(path, Entry.NEW, false, defaultCompressionMethod, attrs) :
                        new Entry(path, Entry.NEW, false, defaultCompressionMethod, attrs));
            } finally {
                endRead();
            }
        } else {
            beginRead();
            try {
                ensureOpen();
                Entry e = getEntry(path);
                if (e == null || e.isDir())
                    throw new NoSuchFileException(getString(path));
                try (InputStream is = getInputStream(e)) {
                    // TBD: if (e.size < NNNNN);
                    return new ByteArrayChannel(is.readAllBytes(), true);
                }
            } finally {
                endRead();
            }
        }
    }

    // Returns a FileChannel of the specified entry.
    //
    // This implementation creates a temporary file on the default file system,
    // copy the entry data into it if the entry exists, and then create a
    // FileChannel on top of it.
    FileChannel newFileChannel(byte[] path,
                               Set<? extends OpenOption> options,
                               FileAttribute<?>... attrs)
        throws IOException
    {
        checkOptions(options);
        final  boolean forWrite = (options.contains(StandardOpenOption.WRITE) ||
                                   options.contains(StandardOpenOption.APPEND));
        beginRead();
        try {
            ensureOpen();
            Entry e = getEntry(path);
            if (forWrite) {
                checkWritable();
                if (e == null) {
                    if (!options.contains(StandardOpenOption.CREATE) &&
                        !options.contains(StandardOpenOption.CREATE_NEW)) {
                        throw new NoSuchFileException(getString(path));
                    }
                } else {
                    if (options.contains(StandardOpenOption.CREATE_NEW)) {
                        throw new FileAlreadyExistsException(getString(path));
                    }
                    if (e.isDir())
                        throw new FileAlreadyExistsException("directory <"
                            + getString(path) + "> exists");
                }
                options = new HashSet<>(options);
                options.remove(StandardOpenOption.CREATE_NEW); // for tmpfile
            } else if (e == null || e.isDir()) {
                throw new NoSuchFileException(getString(path));
            }

            final boolean isFCH = (e != null && e.type == Entry.FILECH);
            final Path tmpfile = isFCH ? e.file : getTempPathForEntry(path);
            final FileChannel fch = tmpfile.getFileSystem()
                                           .provider()
                                           .newFileChannel(tmpfile, options, attrs);
            final Entry u = isFCH ? e : (
                supportPosix ?
                new PosixEntry(path, tmpfile, Entry.FILECH, attrs) :
                new Entry(path, tmpfile, Entry.FILECH, attrs));
            if (forWrite) {
                u.flag = FLAG_DATADESCR;
                u.method = defaultCompressionMethod;
            }
            // is there a better way to hook into the FileChannel's close method?
            return new FileChannel() {
                public int write(ByteBuffer src) throws IOException {
                    return fch.write(src);
                }
                public long write(ByteBuffer[] srcs, int offset, int length)
                    throws IOException
                {
                    return fch.write(srcs, offset, length);
                }
                public long position() throws IOException {
                    return fch.position();
                }
                public FileChannel position(long newPosition)
                    throws IOException
                {
                    fch.position(newPosition);
                    return this;
                }
                public long size() throws IOException {
                    return fch.size();
                }
                public FileChannel truncate(long size)
                    throws IOException
                {
                    fch.truncate(size);
                    return this;
                }
                public void force(boolean metaData)
                    throws IOException
                {
                    fch.force(metaData);
                }
                public long transferTo(long position, long count,
                                       WritableByteChannel target)
                    throws IOException
                {
                    return fch.transferTo(position, count, target);
                }
                public long transferFrom(ReadableByteChannel src,
                                         long position, long count)
                    throws IOException
                {
                    return fch.transferFrom(src, position, count);
                }
                public int read(ByteBuffer dst) throws IOException {
                    return fch.read(dst);
                }
                public int read(ByteBuffer dst, long position)
                    throws IOException
                {
                    return fch.read(dst, position);
                }
                public long read(ByteBuffer[] dsts, int offset, int length)
                    throws IOException
                {
                    return fch.read(dsts, offset, length);
                }
                public int write(ByteBuffer src, long position)
                    throws IOException
                {
                   return fch.write(src, position);
                }
                public MappedByteBuffer map(MapMode mode,
                                            long position, long size)
                {
                    throw new UnsupportedOperationException();
                }
                public FileLock lock(long position, long size, boolean shared)
                    throws IOException
                {
                    return fch.lock(position, size, shared);
                }
                public FileLock tryLock(long position, long size, boolean shared)
                    throws IOException
                {
                    return fch.tryLock(position, size, shared);
                }
                protected void implCloseChannel() throws IOException {
                    fch.close();
                    if (forWrite) {
                        u.mtime = System.currentTimeMillis();
                        u.size = Files.size(u.file);
                        update(u);
                    } else {
                        if (!isFCH)    // if this is a new fch for reading
                            removeTempPathForEntry(tmpfile);
                    }
               }
            };
        } finally {
            endRead();
        }
    }

    // the outstanding input streams that need to be closed
    private Set<InputStream> streams =
        Collections.synchronizedSet(new HashSet<>());

    private final Set<Path> tmppaths = Collections.synchronizedSet(new HashSet<>());
    private Path getTempPathForEntry(byte[] path) throws IOException {
        Path tmpPath = createTempFileInSameDirectoryAs(zfpath);
        if (path != null) {
            Entry e = getEntry(path);
            if (e != null) {
                try (InputStream is = newInputStream(path)) {
                    Files.copy(is, tmpPath, REPLACE_EXISTING);
                }
            }
        }
        return tmpPath;
    }

    private void removeTempPathForEntry(Path path) throws IOException {
        Files.delete(path);
        tmppaths.remove(path);
    }

    // check if all parents really exist. ZIP spec does not require
    // the existence of any "parent directory".
    private void checkParents(byte[] path) throws IOException {
        beginRead();
        try {
            while ((path = getParent(path)) != null &&
                    path != ROOTPATH) {
                if (!inodes.containsKey(IndexNode.keyOf(path))) {
                    throw new NoSuchFileException(getString(path));
                }
            }
        } finally {
            endRead();
        }
    }

    private static byte[] getParent(byte[] path) {
        int off = getParentOff(path);
        if (off <= 1)
            return ROOTPATH;
        return Arrays.copyOf(path, off);
    }

    private static int getParentOff(byte[] path) {
        int off = path.length - 1;
        if (off > 0 && path[off] == '/')  // isDirectory
            off--;
        while (off > 0 && path[off] != '/') { off--; }
        return off;
    }

    private void beginWrite() {
        rwlock.writeLock().lock();
    }

    private void endWrite() {
        rwlock.writeLock().unlock();
    }

    private void beginRead() {
        rwlock.readLock().lock();
    }

    private void endRead() {
        rwlock.readLock().unlock();
    }

    ///////////////////////////////////////////////////////////////////

    private volatile boolean isOpen = true;
    private final SeekableByteChannel ch; // channel to the zipfile
    final byte[]  cen;     // CEN & ENDHDR
    private END  end;
    private long locpos;   // position of first LOC header (usually 0)

    private final ReadWriteLock rwlock = new ReentrantReadWriteLock();

    // name -> pos (in cen), IndexNode itself can be used as a "key"
    private LinkedHashMap<IndexNode, IndexNode> inodes;

    final byte[] getBytes(String name) {
        return zc.getBytes(name);
    }

    final String getString(byte[] name) {
        return zc.toString(name);
    }

    @SuppressWarnings("deprecation")
    protected void finalize() throws IOException {
        close();
    }

    // Reads len bytes of data from the specified offset into buf.
    // Returns the total number of bytes read.
    // Each/every byte read from here (except the cen, which is mapped).
    final long readFullyAt(byte[] buf, int off, long len, long pos)
        throws IOException
    {
        ByteBuffer bb = ByteBuffer.wrap(buf);
        bb.position(off);
        bb.limit((int)(off + len));
        return readFullyAt(bb, pos);
    }

    private long readFullyAt(ByteBuffer bb, long pos) throws IOException {
        if (ch instanceof FileChannel fch) {
            return fch.read(bb, pos);
        } else {
            synchronized(ch) {
                return ch.position(pos).read(bb);
            }
        }
    }

    // Searches for end of central directory (END) header. The contents of
    // the END header will be read and placed in endbuf. Returns the file
    // position of the END header, otherwise returns -1 if the END header
    // was not found or an error occurred.
    private END findEND() throws IOException {
        byte[] buf = new byte[READBLOCKSZ];
        long ziplen = ch.size();
        long minHDR = (ziplen - END_MAXLEN) > 0 ? ziplen - END_MAXLEN : 0;
        long minPos = minHDR - (buf.length - ENDHDR);

        for (long pos = ziplen - buf.length; pos >= minPos; pos -= (buf.length - ENDHDR)) {
            int off = 0;
            if (pos < 0) {
                // Pretend there are some NUL bytes before start of file
                off = (int)-pos;
                Arrays.fill(buf, 0, off, (byte)0);
            }
            int len = buf.length - off;
            if (readFullyAt(buf, off, len, pos + off) != len)
                throw new ZipException("zip END header not found");

            // Now scan the block backwards for END header signature
            for (int i = buf.length - ENDHDR; i >= 0; i--) {
                if (buf[i]   == (byte)'P'    &&
                    buf[i+1] == (byte)'K'    &&
                    buf[i+2] == (byte)'\005' &&
                    buf[i+3] == (byte)'\006' &&
                    (pos + i + ENDHDR + ENDCOM(buf, i) == ziplen)) {
                    // Found END header
                    buf = Arrays.copyOfRange(buf, i, i + ENDHDR);
                    END end = new END();
                    // end.endsub = ENDSUB(buf); // not used
                    end.centot = ENDTOT(buf);
                    end.cenlen = ENDSIZ(buf);
                    end.cenoff = ENDOFF(buf);
                    // end.comlen = ENDCOM(buf); // not used
                    end.endpos = pos + i;
                    // try if there is zip64 end;
                    byte[] loc64 = new byte[ZIP64_LOCHDR];
                    if (end.endpos < ZIP64_LOCHDR ||
                        readFullyAt(loc64, 0, loc64.length, end.endpos - ZIP64_LOCHDR)
                        != loc64.length ||
                        !locator64SigAt(loc64, 0)) {
                        return end;
                    }
                    long end64pos = ZIP64_LOCOFF(loc64);
                    byte[] end64buf = new byte[ZIP64_ENDHDR];
                    if (readFullyAt(end64buf, 0, end64buf.length, end64pos)
                        != end64buf.length ||
                        !end64SigAt(end64buf, 0)) {
                        return end;
                    }
                    // end64 found,
                    long cenlen64 = ZIP64_ENDSIZ(end64buf);
                    long cenoff64 = ZIP64_ENDOFF(end64buf);
                    long centot64 = ZIP64_ENDTOT(end64buf);
                    // double-check
                    if (cenlen64 != end.cenlen && end.cenlen != ZIP64_MINVAL ||
                        cenoff64 != end.cenoff && end.cenoff != ZIP64_MINVAL ||
                        centot64 != end.centot && end.centot != ZIP64_MINVAL32) {
                        return end;
                    }
                    // to use the end64 values
                    end.cenlen = cenlen64;
                    end.cenoff = cenoff64;
                    end.centot = (int)centot64; // assume total < 2g
                    end.endpos = end64pos;
                    return end;
                }
            }
        }
        throw new ZipException("zip END header not found");
    }

    private void makeParentDirs(IndexNode node, IndexNode root) {
        IndexNode parent;
        ParentLookup lookup = new ParentLookup();
        while (true) {
            int off = getParentOff(node.name);
            // parent is root
            if (off <= 1) {
                node.sibling = root.child;
                root.child = node;
                break;
            }
            // parent exists
            lookup = lookup.as(node.name, off);
            if (inodes.containsKey(lookup)) {
                parent = inodes.get(lookup);
                node.sibling = parent.child;
                parent.child = node;
                break;
            }
            // parent does not exist, add new pseudo directory entry
            parent = new IndexNode(Arrays.copyOf(node.name, off), true);
            inodes.put(parent, parent);
            node.sibling = parent.child;
            parent.child = node;
            node = parent;
        }
    }

    // ZIP directory has two issues:
    // (1) ZIP spec does not require the ZIP file to include
    //     directory entry
    // (2) all entries are not stored/organized in a "tree"
    //     structure.
    // A possible solution is to build the node tree ourself as
    // implemented below.
    private void buildNodeTree() {
        beginWrite();
        try {
            IndexNode root = inodes.remove(LOOKUPKEY.as(ROOTPATH));
            if (root == null) {
                root = new IndexNode(ROOTPATH, true);
            }
            IndexNode[] nodes = inodes.values().toArray(new IndexNode[0]);
            inodes.put(root, root);
            for (IndexNode node : nodes) {
                makeParentDirs(node, root);
            }
        } finally {
            endWrite();
        }
    }

    private void removeFromTree(IndexNode inode) {
        IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(inode.name)));
        IndexNode child = parent.child;
        if (child.equals(inode)) {
            parent.child = child.sibling;
        } else {
            IndexNode last = child;
            while ((child = child.sibling) != null) {
                if (child.equals(inode)) {
                    last.sibling = child.sibling;
                    break;
                } else {
                    last = child;
                }
            }
        }
    }

    /**
     * If a version property has been specified and the file represents a multi-release JAR,
     * determine the requested runtime version and initialize the ZipFileSystem instance accordingly.
     *
     * Checks if the Zip File System property "releaseVersion" has been specified. If it has,
     * use its value to determine the requested version. If not use the value of the "multi-release" property.
     */
    private void initializeReleaseVersion(Map<String, ?> env) throws IOException {
        Object o = env.containsKey(PROPERTY_RELEASE_VERSION) ?
            env.get(PROPERTY_RELEASE_VERSION) :
            env.get(PROPERTY_MULTI_RELEASE);

        if (o != null && isMultiReleaseJar()) {
            int version;
            if (o instanceof String) {
                String s = (String)o;
                if (s.equals("runtime")) {
                    version = Runtime.version().feature();
                } else if (s.matches("^[1-9][0-9]*$")) {
                    version = Version.parse(s).feature();
                } else {
                    throw new IllegalArgumentException("Invalid runtime version");
                }
            } else if (o instanceof Integer) {
                version = Version.parse(((Integer)o).toString()).feature();
            } else if (o instanceof Version) {
                version = ((Version)o).feature();
            } else {
                throw new IllegalArgumentException("env parameter must be String, " +
                    "Integer, or Version");
            }
            createVersionedLinks(version < 0 ? 0 : version);
            setReadOnly();
        }
    }

    /**
     * Returns true if the Manifest main attribute "Multi-Release" is set to true; false otherwise.
     */
    private boolean isMultiReleaseJar() throws IOException {
        try (InputStream is = newInputStream(getBytes("/META-INF/MANIFEST.MF"))) {
            String multiRelease = new Manifest(is).getMainAttributes()
                .getValue(Attributes.Name.MULTI_RELEASE);
            return "true".equalsIgnoreCase(multiRelease);
        } catch (NoSuchFileException x) {
            return false;
        }
    }

    /**
     * Create a map of aliases for versioned entries, for example:
     *   version/PackagePrivate.class -> META-INF/versions/9/version/PackagePrivate.class
     *   version/PackagePrivate.java -> META-INF/versions/9/version/PackagePrivate.java
     *   version/Version.class -> META-INF/versions/10/version/Version.class
     *   version/Version.java -> META-INF/versions/10/version/Version.java
     *
     * Then wrap the map in a function that getEntry can use to override root
     * entry lookup for entries that have corresponding versioned entries.
     */
    private void createVersionedLinks(int version) {
        IndexNode verdir = getInode(getBytes("/META-INF/versions"));
        // nothing to do, if no /META-INF/versions
        if (verdir == null) {
            return;
        }
        // otherwise, create a map and for each META-INF/versions/{n} directory
        // put all the leaf inodes, i.e. entries, into the alias map
        // possibly shadowing lower versioned entries
        HashMap<IndexNode, byte[]> aliasMap = new HashMap<>();
        getVersionMap(version, verdir).values().forEach(versionNode ->
            walk(versionNode.child, entryNode ->
                aliasMap.put(
                    getOrCreateInode(getRootName(entryNode, versionNode), entryNode.isdir),
                    entryNode.name))
        );
        entryLookup = path -> {
            byte[] entry = aliasMap.get(IndexNode.keyOf(path));
            return entry == null ? path : entry;
        };
    }

    /**
     * Create a sorted version map of version -> inode, for inodes <= max version.
     *   9 -> META-INF/versions/9
     *  10 -> META-INF/versions/10
     */
    private TreeMap<Integer, IndexNode> getVersionMap(int version, IndexNode metaInfVersions) {
        TreeMap<Integer,IndexNode> map = new TreeMap<>();
        IndexNode child = metaInfVersions.child;
        while (child != null) {
            Integer key = getVersion(child, metaInfVersions);
            if (key != null && key <= version) {
                map.put(key, child);
            }
            child = child.sibling;
        }
        return map;
    }

    /**
     * Extract the integer version number -- META-INF/versions/9 returns 9.
     */
    private Integer getVersion(IndexNode inode, IndexNode metaInfVersions) {
        try {
            byte[] fullName = inode.name;
            return Integer.parseInt(getString(Arrays
                .copyOfRange(fullName, metaInfVersions.name.length + 1, fullName.length)));
        } catch (NumberFormatException x) {
            // ignore this even though it might indicate issues with the JAR structure
            return null;
        }
    }

    /**
     * Walk the IndexNode tree processing all leaf nodes.
     */
    private void walk(IndexNode inode, Consumer<IndexNode> consumer) {
        if (inode == null) return;
        if (inode.isDir()) {
            walk(inode.child, consumer);
        } else {
            consumer.accept(inode);
        }
        walk(inode.sibling, consumer);
    }

    /**
     * Extract the root name from a versioned entry name.
     * E.g. given inode 'META-INF/versions/9/foo/bar.class'
     * and prefix 'META-INF/versions/9/' returns 'foo/bar.class'.
     */
    private byte[] getRootName(IndexNode inode, IndexNode prefix) {
        byte[] fullName = inode.name;
        return Arrays.copyOfRange(fullName, prefix.name.length, fullName.length);
    }

    // Reads zip file central directory. Returns the file position of first
    // CEN header, otherwise returns -1 if an error occurred. If zip->msg != NULL
    // then the error was a zip format error and zip->msg has the error text.
    // Always pass in -1 for knownTotal; it's used for a recursive call.
    private byte[] initCEN() throws IOException {
        end = findEND();
        if (end.endpos == 0) {
            inodes = new LinkedHashMap<>(10);
            locpos = 0;
            buildNodeTree();
            return null;         // only END header present
        }
        if (end.cenlen > end.endpos)
            throw new ZipException("invalid END header (bad central directory size)");
        long cenpos = end.endpos - end.cenlen;     // position of CEN table

        // Get position of first local file (LOC) header, taking into
        // account that there may be a stub prefixed to the zip file.
        locpos = cenpos - end.cenoff;
        if (locpos < 0)
            throw new ZipException("invalid END header (bad central directory offset)");

        // read in the CEN and END
        byte[] cen = new byte[(int)(end.cenlen + ENDHDR)];
        if (readFullyAt(cen, 0, cen.length, cenpos) != end.cenlen + ENDHDR) {
            throw new ZipException("read CEN tables failed");
        }
        // Iterate through the entries in the central directory
        inodes = new LinkedHashMap<>(end.centot + 1);
        int pos = 0;
        int limit = cen.length - ENDHDR;
        while (pos < limit) {
            if (!cenSigAt(cen, pos))
                throw new ZipException("invalid CEN header (bad signature)");
            int method = CENHOW(cen, pos);
            int nlen   = CENNAM(cen, pos);
            int elen   = CENEXT(cen, pos);
            int clen   = CENCOM(cen, pos);
            int flag   = CENFLG(cen, pos);
            if ((flag & 1) != 0) {
                throw new ZipException("invalid CEN header (encrypted entry)");
            }
            if (method != METHOD_STORED && method != METHOD_DEFLATED) {
                throw new ZipException("invalid CEN header (unsupported compression method: " + method + ")");
            }
            if (pos + CENHDR + nlen > limit) {
                throw new ZipException("invalid CEN header (bad header size)");
            }
            IndexNode inode = new IndexNode(cen, pos, nlen);
            inodes.put(inode, inode);
            if (zc.isUTF8() || (flag & FLAG_USE_UTF8) != 0) {
                checkUTF8(inode.name);
            } else {
                checkEncoding(inode.name);
            }
            // skip ext and comment
            pos += (CENHDR + nlen + elen + clen);
        }
        if (pos + ENDHDR != cen.length) {
            throw new ZipException("invalid CEN header (bad header size)");
        }
        buildNodeTree();
        return cen;
    }

    private  final void checkUTF8(byte[] a) throws ZipException {
        try {
            int end = a.length;
            int pos = 0;
            while (pos < end) {
                // ASCII fast-path: When checking that a range of bytes is
                // valid UTF-8, we can avoid some allocation by skipping
                // past bytes in the 0-127 range
                if (a[pos] < 0) {
                    zc.toString(Arrays.copyOfRange(a, pos, a.length));
                    break;
                }
                pos++;
            }
        } catch(Exception e) {
            throw new ZipException("invalid CEN header (bad entry name)");
        }
    }

    private final void checkEncoding( byte[] a) throws ZipException {
        try {
            zc.toString(a);
        } catch(Exception e) {
            throw new ZipException("invalid CEN header (bad entry name)");
        }
    }


    private void ensureOpen() {
        if (!isOpen)
            throw new ClosedFileSystemException();
    }

    // Creates a new empty temporary file in the same directory as the
    // specified file.  A variant of Files.createTempFile.
    private Path createTempFileInSameDirectoryAs(Path path) throws IOException {
        Path parent = path.toAbsolutePath().getParent();
        Path dir = (parent == null) ? path.getFileSystem().getPath(".") : parent;
        Path tmpPath = Files.createTempFile(dir, "zipfstmp", null);
        tmppaths.add(tmpPath);
        return tmpPath;
    }

    ////////////////////update & sync //////////////////////////////////////

    private boolean hasUpdate = false;

    // shared key. consumer guarantees the "writeLock" before use it.
    private final IndexNode LOOKUPKEY = new IndexNode(null, -1);

    private void updateDelete(IndexNode inode) {
        beginWrite();
        try {
            removeFromTree(inode);
            inodes.remove(inode);
            hasUpdate = true;
        } finally {
             endWrite();
        }
    }

    private void update(Entry e) {
        beginWrite();
        try {
            IndexNode old = inodes.put(e, e);
            if (old != null) {
                removeFromTree(old);
            }
            if (e.type == Entry.NEW || e.type == Entry.FILECH || e.type == Entry.COPY) {
                IndexNode parent = inodes.get(LOOKUPKEY.as(getParent(e.name)));
                e.sibling = parent.child;
                parent.child = e;
            }
            hasUpdate = true;
        } finally {
            endWrite();
        }
    }

    // copy over the whole LOC entry (header if necessary, data and ext) from
    // old zip to the new one.
    private long copyLOCEntry(Entry e, boolean updateHeader,
                              OutputStream os,
                              long written, byte[] buf)
        throws IOException
    {
        long locoff = e.locoff;  // where to read
        e.locoff = written;      // update the e.locoff with new value

        // calculate the size need to write out
        long size = 0;
        //  if there is A ext
        if ((e.flag & FLAG_DATADESCR) != 0) {
            if (e.size >= ZIP64_MINVAL || e.csize >= ZIP64_MINVAL)
                size = 24;
            else
                size = 16;
        }
        // read loc, use the original loc.elen/nlen
        //
        // an extra byte after loc is read, which should be the first byte of the
        // 'name' field of the loc. if this byte is '/', which means the original
        // entry has an absolute path in original zip/jar file, the e.writeLOC()
        // is used to output the loc, in which the leading "/" will be removed
        if (readFullyAt(buf, 0, LOCHDR + 1 , locoff) != LOCHDR + 1)
            throw new ZipException("loc: reading failed");

        if (updateHeader || LOCNAM(buf) > 0 && buf[LOCHDR] == '/') {
            locoff += LOCHDR + LOCNAM(buf) + LOCEXT(buf);  // skip header
            size += e.csize;
            written = e.writeLOC(os) + size;
        } else {
            os.write(buf, 0, LOCHDR);    // write out the loc header
            locoff += LOCHDR;
            // use e.csize,  LOCSIZ(buf) is zero if FLAG_DATADESCR is on
            // size += LOCNAM(buf) + LOCEXT(buf) + LOCSIZ(buf);
            size += LOCNAM(buf) + LOCEXT(buf) + e.csize;
            written = LOCHDR + size;
        }
        int n;
        while (size > 0 &&
            (n = (int)readFullyAt(buf, 0, buf.length, locoff)) != -1)
        {
            if (size < n)
                n = (int)size;
            os.write(buf, 0, n);
            size -= n;
            locoff += n;
        }
        return written;
    }

    private long writeEntry(Entry e, OutputStream os)
        throws IOException {

        if (e.bytes == null && e.file == null)    // dir, 0-length data
            return 0;

        long written = 0;
        if (e.method != METHOD_STORED && e.csize > 0 && (e.crc != 0 || e.size == 0)) {
            // pre-compressed entry, write directly to output stream
            writeTo(e, os);
        } else {
            try (OutputStream os2 = (e.method == METHOD_STORED) ?
                    new EntryOutputStreamCRC32(e, os) : new EntryOutputStreamDef(e, os)) {
                writeTo(e, os2);
            }
        }
        written += e.csize;
        if ((e.flag & FLAG_DATADESCR) != 0) {
            written += e.writeEXT(os);
        }
        return written;
    }

    private void writeTo(Entry e, OutputStream os) throws IOException {
        if (e.bytes != null) {
            os.write(e.bytes, 0, e.bytes.length);
        } else if (e.file != null) {
            if (e.type == Entry.NEW || e.type == Entry.FILECH) {
                try (InputStream is = Files.newInputStream(e.file)) {
                    is.transferTo(os);
                }
            }
            Files.delete(e.file);
            tmppaths.remove(e.file);
        }
    }

    // sync the zip file system, if there is any update
    private void sync() throws IOException {
        if (!hasUpdate)
            return;
        PosixFileAttributes attrs = getPosixAttributes(zfpath);
        Path tmpFile = createTempFileInSameDirectoryAs(zfpath);
        try (OutputStream os = new BufferedOutputStream(Files.newOutputStream(tmpFile, WRITE))) {
            ArrayList<Entry> elist = new ArrayList<>(inodes.size());
            long written = 0;
            byte[] buf = null;
            Entry e;

            final IndexNode manifestInode = inodes.get(
                    IndexNode.keyOf(getBytes("/META-INF/MANIFEST.MF")));
            final Iterator<IndexNode> inodeIterator = inodes.values().iterator();
            boolean manifestProcessed = false;

            // write loc
            while (inodeIterator.hasNext()) {
                final IndexNode inode;

                // write the manifest inode (if any) first so that
                // java.util.jar.JarInputStream can find it
                if (manifestInode == null) {
                    inode = inodeIterator.next();
                } else {
                    if (manifestProcessed) {
                        // advance to next node, filtering out the manifest
                        // which was already written
                        inode = inodeIterator.next();
                        if (inode == manifestInode) {
                            continue;
                        }
                    } else {
                        inode = manifestInode;
                        manifestProcessed = true;
                    }
                }

                if (inode instanceof Entry) {    // an updated inode
                    e = (Entry)inode;
                    try {
                        if (e.type == Entry.COPY) {
                            // entry copy: the only thing changed is the "name"
                            // and "nlen" in LOC header, so we update/rewrite the
                            // LOC in new file and simply copy the rest (data and
                            // ext) without enflating/deflating from the old zip
                            // file LOC entry.
                            if (buf == null)
                                buf = new byte[8192];
                            written += copyLOCEntry(e, true, os, written, buf);
                        } else {                          // NEW, FILECH or CEN
                            e.locoff = written;
                            written += e.writeLOC(os);    // write loc header
                            written += writeEntry(e, os);
                        }
                        elist.add(e);
                    } catch (IOException x) {
                        x.printStackTrace();    // skip any in-accurate entry
                    }
                } else {                        // unchanged inode
                    if (inode.pos == -1) {
                        continue;               // pseudo directory node
                    }
                    if (inode.name.length == 1 && inode.name[0] == '/') {
                        continue;               // no root '/' directory even if it
                                                // exists in original zip/jar file.
                    }
                    e = supportPosix ? new PosixEntry(this, inode) : new Entry(this, inode);
                    try {
                        if (buf == null)
                            buf = new byte[8192];
                        written += copyLOCEntry(e, false, os, written, buf);
                        elist.add(e);
                    } catch (IOException x) {
                        x.printStackTrace();    // skip any wrong entry
                    }
                }
            }

            // now write back the cen and end table
            end.cenoff = written;
            for (Entry entry : elist) {
                written += entry.writeCEN(os);
            }
            end.centot = elist.size();
            end.cenlen = written - end.cenoff;
            end.write(os, written, forceEnd64);
        }
        ch.close();
        Files.delete(zfpath);

        // Set the POSIX permissions of the original Zip File if available
        // before moving the temp file
        if (attrs != null) {
            Files.setPosixFilePermissions(tmpFile, attrs.permissions());
        }
        Files.move(tmpFile, zfpath, REPLACE_EXISTING);
        hasUpdate = false;    // clear
    }

    /**
     * Returns a file's POSIX file attributes.
     * @param path The path to the file
     * @return The POSIX file attributes for the specified file or
     *         null if the POSIX attribute view is not available
     * @throws IOException If an error occurs obtaining the POSIX attributes for
     *                    the specified file
     */
    private PosixFileAttributes getPosixAttributes(Path path) throws IOException {
        try {
            PosixFileAttributeView view =
                    Files.getFileAttributeView(path, PosixFileAttributeView.class);
            // Return if the attribute view is not supported
            if (view == null) {
                return null;
            }
            return view.readAttributes();
        } catch (UnsupportedOperationException e) {
            // PosixFileAttributes not available
            return null;
        }
    }

    private IndexNode getInode(byte[] path) {
        return inodes.get(IndexNode.keyOf(Objects.requireNonNull(entryLookup.apply(path), "path")));
    }

    /**
     * Return the IndexNode from the root tree. If it doesn't exist,
     * it gets created along with all parent directory IndexNodes.
     */
    private IndexNode getOrCreateInode(byte[] path, boolean isdir) {
        IndexNode node = getInode(path);
        // if node exists, return it
        if (node != null) {
            return node;
        }

        // otherwise create new pseudo node and parent directory hierarchy
        node = new IndexNode(path, isdir);
        beginWrite();
        try {
            makeParentDirs(node, Objects.requireNonNull(inodes.get(IndexNode.keyOf(ROOTPATH)), "no root node found"));
            return node;
        } finally {
            endWrite();
        }
    }

    private Entry getEntry(byte[] path) throws IOException {
        IndexNode inode = getInode(path);
        if (inode instanceof Entry)
            return (Entry)inode;
        if (inode == null || inode.pos == -1)
            return null;
        return supportPosix ? new PosixEntry(this, inode): new Entry(this, inode);
    }

    public void deleteFile(byte[] path, boolean failIfNotExists)
        throws IOException
    {
        checkWritable();
        IndexNode inode = getInode(path);
        if (inode == null) {
            if (path != null && path.length == 0)
                throw new ZipException("root directory </> cannot be deleted");
            if (failIfNotExists)
                throw new NoSuchFileException(getString(path));
        } else {
            if (inode.isDir() && inode.child != null)
                throw new DirectoryNotEmptyException(getString(path));
            updateDelete(inode);
        }
    }

    // Returns an out stream for either
    // (1) writing the contents of a new entry, if the entry exists, or
    // (2) updating/replacing the contents of the specified existing entry.
    private OutputStream getOutputStream(Entry e) throws IOException {
        if (e.mtime == -1)
            e.mtime = System.currentTimeMillis();
        if (e.method == -1)
            e.method = defaultCompressionMethod;
        // store size, compressed size, and crc-32 in datadescr
        e.flag = FLAG_DATADESCR;
        if (zc.isUTF8())
            e.flag |= FLAG_USE_UTF8;
        OutputStream os;
        if (useTempFile) {
            e.file = getTempPathForEntry(null);
            os = Files.newOutputStream(e.file, WRITE);
        } else {
            os = new ByteArrayOutputStream((e.size > 0)? (int)e.size : 8192);
        }
        if (e.method == METHOD_DEFLATED) {
            return new DeflatingEntryOutputStream(e, os);
        } else {
            return new EntryOutputStream(e, os);
        }
    }

    private class EntryOutputStream extends FilterOutputStream {
        private final Entry e;
        private long written;
        private boolean isClosed;

        EntryOutputStream(Entry e, OutputStream os) {
            super(os);
            this.e =  Objects.requireNonNull(e, "Zip entry is null");
            // this.written = 0;
        }

        @Override
        public synchronized void write(int b) throws IOException {
            out.write(b);
            written += 1;
        }

        @Override
        public synchronized void write(byte[] b, int off, int len)
                throws IOException {
            out.write(b, off, len);
            written += len;
        }

        @Override
        public synchronized void close() throws IOException {
            if (isClosed) {
                return;
            }
            isClosed = true;
            e.size = written;
            if (out instanceof ByteArrayOutputStream)
                e.bytes = ((ByteArrayOutputStream)out).toByteArray();
            super.close();
            update(e);
        }
    }

    // Output stream returned when writing "deflated" entries into memory,
    // to enable eager (possibly parallel) deflation and reduce memory required.
    private class DeflatingEntryOutputStream extends DeflaterOutputStream {
        private final CRC32 crc;
        private final Entry e;
        private boolean isClosed;

        DeflatingEntryOutputStream(Entry e, OutputStream os) {
            super(os, getDeflater());
            this.e = Objects.requireNonNull(e, "Zip entry is null");
            this.crc = new CRC32();
        }

        @Override
        public synchronized void write(byte[] b, int off, int len)
                throws IOException {
            super.write(b, off, len);
            crc.update(b, off, len);
        }

        @Override
        public synchronized void close() throws IOException {
            if (isClosed)
                return;
            isClosed = true;
            finish();
            e.size  = def.getBytesRead();
            e.csize = def.getBytesWritten();
            e.crc = crc.getValue();
            if (out instanceof ByteArrayOutputStream)
                e.bytes = ((ByteArrayOutputStream)out).toByteArray();
            super.close();
            update(e);
            releaseDeflater(def);
        }
    }

    // Wrapper output stream class to write out a "stored" entry.
    // (1) this class does not close the underlying out stream when
    //     being closed.
    // (2) no need to be "synchronized", only used by sync()
    private class EntryOutputStreamCRC32 extends FilterOutputStream {
        private final CRC32 crc;
        private final Entry e;
        private long written;
        private boolean isClosed;

        EntryOutputStreamCRC32(Entry e, OutputStream os) {
            super(os);
            this.e =  Objects.requireNonNull(e, "Zip entry is null");
            this.crc = new CRC32();
        }

        @Override
        public void write(int b) throws IOException {
            out.write(b);
            crc.update(b);
            written += 1;
        }

        @Override
        public void write(byte[] b, int off, int len)
                throws IOException {
            out.write(b, off, len);
            crc.update(b, off, len);
            written += len;
        }

        @Override
        public void close() {
            if (isClosed)
                return;
            isClosed = true;
            e.size = e.csize = written;
            e.crc = crc.getValue();
        }
    }

    // Wrapper output stream class to write out a "deflated" entry.
    // (1) this class does not close the underlying out stream when
    //     being closed.
    // (2) no need to be "synchronized", only used by sync()
    private class EntryOutputStreamDef extends DeflaterOutputStream {
        private final CRC32 crc;
        private final Entry e;
        private boolean isClosed;

        EntryOutputStreamDef(Entry e, OutputStream os) {
            super(os, getDeflater());
            this.e = Objects.requireNonNull(e, "Zip entry is null");
            this.crc = new CRC32();
        }

        @Override
        public void write(byte[] b, int off, int len) throws IOException {
            super.write(b, off, len);
            crc.update(b, off, len);
        }

        @Override
        public void close() throws IOException {
            if (isClosed)
                return;
            isClosed = true;
            finish();
            e.size = def.getBytesRead();
            e.csize = def.getBytesWritten();
            e.crc = crc.getValue();
            releaseDeflater(def);
        }
    }

    private InputStream getInputStream(Entry e)
        throws IOException
    {
        InputStream eis;
        if (e.type == Entry.NEW) {
            if (e.bytes != null)
                eis = new ByteArrayInputStream(e.bytes);
            else if (e.file != null)
                eis = Files.newInputStream(e.file);
            else
                throw new ZipException("update entry data is missing");
        } else if (e.type == Entry.FILECH) {
            // FILECH result is un-compressed.
            eis = Files.newInputStream(e.file);
            // TBD: wrap to hook close()
            // streams.add(eis);
            return eis;
        } else {  // untouched CEN or COPY
            eis = new EntryInputStream(e);
        }
        if (e.method == METHOD_DEFLATED) {
            // MORE: Compute good size for inflater stream:
            long bufSize = e.size + 2; // Inflater likes a bit of slack
            if (bufSize > 65536)
                bufSize = 8192;
            final long size = e.size;
            eis = new InflaterInputStream(eis, getInflater(), (int)bufSize) {
                private boolean isClosed = false;
                public void close() throws IOException {
                    if (!isClosed) {
                        releaseInflater(inf);
                        this.in.close();
                        isClosed = true;
                        streams.remove(this);
                    }
                }
                // Override fill() method to provide an extra "dummy" byte
                // at the end of the input stream. This is required when
                // using the "nowrap" Inflater option. (it appears the new
                // zlib in 7 does not need it, but keep it for now)
                protected void fill() throws IOException {
                    if (eof) {
                        throw new EOFException(
                            "Unexpected end of ZLIB input stream");
                    }
                    len = this.in.read(buf, 0, buf.length);
                    if (len == -1) {
                        buf[0] = 0;
                        len = 1;
                        eof = true;
                    }
                    inf.setInput(buf, 0, len);
                }
                private boolean eof;

                public int available() {
                    if (isClosed)
                        return 0;
                    long avail = size - inf.getBytesWritten();
                    return avail > (long) Integer.MAX_VALUE ?
                        Integer.MAX_VALUE : (int) avail;
                }
            };
        } else if (e.method == METHOD_STORED) {
            // TBD: wrap/ it does not seem necessary
        } else {
            throw new ZipException("invalid compression method");
        }
        streams.add(eis);
        return eis;
    }

    // Inner class implementing the input stream used to read
    // a (possibly compressed) zip file entry.
    private class EntryInputStream extends InputStream {
        private long pos;                       // current position within entry data
        private long rem;                       // number of remaining bytes within entry

        EntryInputStream(Entry e)
            throws IOException
        {
            rem = e.csize;
            pos = e.locoff;
            if (pos == -1) {
                Entry e2 = getEntry(e.name);
                if (e2 == null) {
                    throw new ZipException("invalid loc for entry <" + getString(e.name) + ">");
                }
                pos = e2.locoff;
            }
            pos = -pos;  // lazy initialize the real data offset
        }

        public int read(byte[] b, int off, int len) throws IOException {
            ensureOpen();
            initDataPos();
            if (rem == 0) {
                return -1;
            }
            if (len <= 0) {
                return 0;
            }
            if (len > rem) {
                len = (int) rem;
            }
            ByteBuffer bb = ByteBuffer.wrap(b);
            bb.position(off);
            bb.limit(off + len);
            long n = readFullyAt(bb, pos);
            if (n > 0) {
                pos += n;
                rem -= n;
            }
            if (rem == 0) {
                close();
            }
            return (int)n;
        }

        public int read() throws IOException {
            byte[] b = new byte[1];
            if (read(b, 0, 1) == 1) {
                return b[0] & 0xff;
            } else {
                return -1;
            }
        }

        public long skip(long n) {
            ensureOpen();
            if (n > rem)
                n = rem;
            pos += n;
            rem -= n;
            if (rem == 0) {
                close();
            }
            return n;
        }

        public int available() {
            return rem > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int) rem;
        }

        public void close() {
            rem = 0;
            streams.remove(this);
        }

        private void initDataPos() throws IOException {
            if (pos <= 0) {
                pos = -pos + locpos;
                byte[] buf = new byte[LOCHDR];
                if (readFullyAt(buf, 0, buf.length, pos) != LOCHDR) {
                    throw new ZipException("invalid loc " + pos + " for entry reading");
                }
                pos += LOCHDR + LOCNAM(buf) + LOCEXT(buf);
            }
        }
    }

    // Maxmum number of de/inflater we cache
    private final int MAX_FLATER = 20;
    // List of available Inflater objects for decompression
    private final List<Inflater> inflaters = new ArrayList<>();

    // Gets an inflater from the list of available inflaters or allocates
    // a new one.
    private Inflater getInflater() {
        synchronized (inflaters) {
            int size = inflaters.size();
            if (size > 0) {
                return inflaters.remove(size - 1);
            } else {
                return new Inflater(true);
            }
        }
    }

    // Releases the specified inflater to the list of available inflaters.
    private void releaseInflater(Inflater inf) {
        synchronized (inflaters) {
            if (inflaters.size() < MAX_FLATER) {
                inf.reset();
                inflaters.add(inf);
            } else {
                inf.end();
            }
        }
    }

    // List of available Deflater objects for compression
    private final List<Deflater> deflaters = new ArrayList<>();

    // Gets a deflater from the list of available deflaters or allocates
    // a new one.
    private Deflater getDeflater() {
        synchronized (deflaters) {
            int size = deflaters.size();
            if (size > 0) {
                return deflaters.remove(size - 1);
            } else {
                return new Deflater(Deflater.DEFAULT_COMPRESSION, true);
            }
        }
    }

    // Releases the specified inflater to the list of available inflaters.
    private void releaseDeflater(Deflater def) {
        synchronized (deflaters) {
            if (deflaters.size() < MAX_FLATER) {
               def.reset();
               deflaters.add(def);
            } else {
               def.end();
            }
        }
    }

    // End of central directory record
    static class END {
        // The fields that are commented out below are not used by anyone and write() uses "0"
        // int  disknum;
        // int  sdisknum;
        // int  endsub;
        int  centot;        // 4 bytes
        long cenlen;        // 4 bytes
        long cenoff;        // 4 bytes
        // int  comlen;     // comment length
        // byte[] comment;

        // members of Zip64 end of central directory locator
        // int diskNum;
        long endpos;
        // int disktot;

        void write(OutputStream os, long offset, boolean forceEnd64) throws IOException {
            boolean hasZip64 = forceEnd64; // false;
            long xlen = cenlen;
            long xoff = cenoff;
            if (xlen >= ZIP64_MINVAL) {
                xlen = ZIP64_MINVAL;
                hasZip64 = true;
            }
            if (xoff >= ZIP64_MINVAL) {
                xoff = ZIP64_MINVAL;
                hasZip64 = true;
            }
            int count = centot;
            if (count >= ZIP64_MINVAL32) {
                count = ZIP64_MINVAL32;
                hasZip64 = true;
            }
            if (hasZip64) {
                //zip64 end of central directory record
                writeInt(os, ZIP64_ENDSIG);       // zip64 END record signature
                writeLong(os, ZIP64_ENDHDR - 12); // size of zip64 end
                writeShort(os, 45);               // version made by
                writeShort(os, 45);               // version needed to extract
                writeInt(os, 0);                  // number of this disk
                writeInt(os, 0);                  // central directory start disk
                writeLong(os, centot);            // number of directory entries on disk
                writeLong(os, centot);            // number of directory entries
                writeLong(os, cenlen);            // length of central directory
                writeLong(os, cenoff);            // offset of central directory

                //zip64 end of central directory locator
                writeInt(os, ZIP64_LOCSIG);       // zip64 END locator signature
                writeInt(os, 0);                  // zip64 END start disk
                writeLong(os, offset);            // offset of zip64 END
                writeInt(os, 1);                  // total number of disks (?)
            }
            writeInt(os, ENDSIG);                 // END record signature
            writeShort(os, 0);                    // number of this disk
            writeShort(os, 0);                    // central directory start disk
            writeShort(os, count);                // number of directory entries on disk
            writeShort(os, count);                // total number of directory entries
            writeInt(os, xlen);                   // length of central directory
            writeInt(os, xoff);                   // offset of central directory
            writeShort(os, 0);                    // zip file comment, not used
        }
    }

    // Internal node that links a "name" to its pos in cen table.
    // The node itself can be used as a "key" to lookup itself in
    // the HashMap inodes.
    static class IndexNode {
        byte[]  name;
        int     hashcode;    // node is hashable/hashed by its name
        boolean isdir;
        int     pos = -1;    // position in cen table, -1 means the
                             // entry does not exist in zip file
        IndexNode child;     // first child
        IndexNode sibling;   // next sibling

        IndexNode() {}

        IndexNode(byte[] name, boolean isdir) {
            name(name);
            this.isdir = isdir;
            this.pos = -1;
        }

        IndexNode(byte[] name, int pos) {
            name(name);
            this.pos = pos;
        }

        // constructor for initCEN() (1) remove trailing '/' (2) pad leading '/'
        IndexNode(byte[] cen, int pos, int nlen) {
            int noff = pos + CENHDR;
            if (cen[noff + nlen - 1] == '/') {
                isdir = true;
                nlen--;
            }
            if (nlen > 0 && cen[noff] == '/') {
                name = Arrays.copyOfRange(cen, noff, noff + nlen);
            } else {
                name = new byte[nlen + 1];
                System.arraycopy(cen, noff, name, 1, nlen);
                name[0] = '/';
            }
            name(normalize(name));
            this.pos = pos;
        }

        // Normalize the IndexNode.name field.
        private byte[] normalize(byte[] path) {
            int len = path.length;
            if (len == 0)
                return path;
            byte prevC = 0;
            for (int pathPos = 0; pathPos < len; pathPos++) {
                byte c = path[pathPos];
                if (c == '/' && prevC == '/')
                    return normalize(path, pathPos - 1);
                prevC = c;
            }
            if (len > 1 && prevC == '/') {
                return Arrays.copyOf(path, len - 1);
            }
            return path;
        }

        private byte[] normalize(byte[] path, int off) {
            // As we know we have at least one / to trim, we can reduce
            // the size of the resulting array
            byte[] to = new byte[path.length - 1];
            int pathPos = 0;
            while (pathPos < off) {
                to[pathPos] = path[pathPos];
                pathPos++;
            }
            int toPos = pathPos;
            byte prevC = 0;
            while (pathPos < path.length) {
                byte c = path[pathPos++];
                if (c == '/' && prevC == '/')
                    continue;
                to[toPos++] = c;
                prevC = c;
            }
            if (toPos > 1 && to[toPos - 1] == '/')
                toPos--;
            return (toPos == to.length) ? to : Arrays.copyOf(to, toPos);
        }

        private static final ThreadLocal<IndexNode> cachedKey = new ThreadLocal<>();

        static final IndexNode keyOf(byte[] name) { // get a lookup key;
            IndexNode key = cachedKey.get();
            if (key == null) {
                key = new IndexNode(name, -1);
                cachedKey.set(key);
            }
            return key.as(name);
        }

        final void name(byte[] name) {
            this.name = name;
            this.hashcode = Arrays.hashCode(name);
        }

        final IndexNode as(byte[] name) {           // reuse the node, mostly
            name(name);                             // as a lookup "key"
            return this;
        }

        boolean isDir() {
            return isdir;
        }

        @Override
        public boolean equals(Object other) {
            if (!(other instanceof IndexNode)) {
                return false;
            }
            if (other instanceof ParentLookup) {
                return ((ParentLookup)other).equals(this);
            }
            return Arrays.equals(name, ((IndexNode)other).name);
        }

        @Override
        public int hashCode() {
            return hashcode;
        }

        @Override
        public String toString() {
            return new String(name) + (isdir ? " (dir)" : " ") + ", index: " + pos;
        }
    }

    static class Entry extends IndexNode implements ZipFileAttributes {
        static final int CEN    = 1;  // entry read from cen
        static final int NEW    = 2;  // updated contents in bytes or file
        static final int FILECH = 3;  // fch update in "file"
        static final int COPY   = 4;  // copy of a CEN entry

        byte[] bytes;                 // updated content bytes
        Path   file;                  // use tmp file to store bytes;
        int    type = CEN;            // default is the entry read from cen

        // entry attributes
        int    version;
        int    flag;
        int    posixPerms = -1; // posix permissions
        int    method = -1;    // compression method
        long   mtime  = -1;    // last modification time (in DOS time)
        long   atime  = -1;    // last access time
        long   ctime  = -1;    // create time
        long   crc    = -1;    // crc-32 of entry data
        long   csize  = -1;    // compressed size of entry data
        long   size   = -1;    // uncompressed size of entry data
        byte[] extra;

        // CEN
        // The fields that are commented out below are not used by anyone and write() uses "0"
        // int    versionMade;
        // int    disk;
        // int    attrs;
        // long   attrsEx;
        long   locoff;
        byte[] comment;

        Entry(byte[] name, boolean isdir, int method) {
            name(name);
            this.isdir = isdir;
            this.mtime  = this.ctime = this.atime = System.currentTimeMillis();
            this.crc    = 0;
            this.size   = 0;
            this.csize  = 0;
            this.method = method;
        }

        @SuppressWarnings("unchecked")
        Entry(byte[] name, int type, boolean isdir, int method, FileAttribute<?>... attrs) {
            this(name, isdir, method);
            this.type = type;
            for (FileAttribute<?> attr : attrs) {
                String attrName = attr.name();
                if (attrName.equals("posix:permissions")) {
                    posixPerms = ZipUtils.permsToFlags((Set<PosixFilePermission>)attr.value());
                }
            }
        }

        Entry(byte[] name, Path file, int type, FileAttribute<?>... attrs) {
            this(name, type, false, METHOD_STORED, attrs);
            this.file = file;
        }

        Entry(Entry e, int type, int compressionMethod) {
            this(e, type);
            this.method = compressionMethod;
        }

        Entry(Entry e, int type) {
            name(e.name);
            this.isdir     = e.isdir;
            this.version   = e.version;
            this.ctime     = e.ctime;
            this.atime     = e.atime;
            this.mtime     = e.mtime;
            this.crc       = e.crc;
            this.size      = e.size;
            this.csize     = e.csize;
            this.method    = e.method;
            this.extra     = e.extra;
            /*
            this.versionMade = e.versionMade;
            this.disk      = e.disk;
            this.attrs     = e.attrs;
            this.attrsEx   = e.attrsEx;
            */
            this.locoff    = e.locoff;
            this.comment   = e.comment;
            this.posixPerms = e.posixPerms;
            this.type      = type;
        }

        Entry(ZipFileSystem zipfs, IndexNode inode) throws IOException {
            readCEN(zipfs, inode);
        }

        // Calculates a suitable base for the version number to
        // be used for fields version made by/version needed to extract.
        // The lower bytes of these 2 byte fields hold the version number
        // (value/10 = major; value%10 = minor)
        // For different features certain minimum versions apply:
        // stored = 10 (1.0), deflated = 20 (2.0), zip64 = 45 (4.5)
        private int version(boolean zip64) throws ZipException {
            if (zip64) {
                return 45;
            }
            if (method == METHOD_DEFLATED)
                return 20;
            else if (method == METHOD_STORED)
                return 10;
            throw new ZipException("unsupported compression method");
        }

        /**
         * Adds information about compatibility of file attribute information
         * to a version value.
         */
        private int versionMadeBy(int version) {
            return (posixPerms < 0) ? version :
                VERSION_MADE_BY_BASE_UNIX | (version & 0xff);
        }

        ///////////////////// CEN //////////////////////
        private void readCEN(ZipFileSystem zipfs, IndexNode inode) throws IOException {
            byte[] cen = zipfs.cen;
            int pos = inode.pos;
            if (!cenSigAt(cen, pos))
                throw new ZipException("invalid CEN header (bad signature)");
            version     = CENVER(cen, pos);
            flag        = CENFLG(cen, pos);
            method      = CENHOW(cen, pos);
            mtime       = dosToJavaTime(CENTIM(cen, pos));
            crc         = CENCRC(cen, pos);
            csize       = CENSIZ(cen, pos);
            size        = CENLEN(cen, pos);
            int nlen    = CENNAM(cen, pos);
            int elen    = CENEXT(cen, pos);
            int clen    = CENCOM(cen, pos);
            /*
            versionMade = CENVEM(cen, pos);
            disk        = CENDSK(cen, pos);
            attrs       = CENATT(cen, pos);
            attrsEx     = CENATX(cen, pos);
            */
            if (CENVEM_FA(cen, pos) == FILE_ATTRIBUTES_UNIX) {
                posixPerms = CENATX_PERMS(cen, pos) & 0xFFF; // 12 bits for setuid, setgid, sticky + perms
            }
            locoff      = CENOFF(cen, pos);
            pos += CENHDR;
            this.name = inode.name;
            this.isdir = inode.isdir;
            this.hashcode = inode.hashcode;

            pos += nlen;
            if (elen > 0) {
                extra = Arrays.copyOfRange(cen, pos, pos + elen);
                pos += elen;
                readExtra(zipfs);
            }
            if (clen > 0) {
                comment = Arrays.copyOfRange(cen, pos, pos + clen);
            }
        }

        private int writeCEN(OutputStream os) throws IOException {
            long csize0  = csize;
            long size0   = size;
            long locoff0 = locoff;
            int elen64   = 0;                // extra for ZIP64
            int elenNTFS = 0;                // extra for NTFS (a/c/mtime)
            int elenEXTT = 0;                // extra for Extended Timestamp
            boolean foundExtraTime = false;  // if time stamp NTFS, EXTT present

            byte[] zname = isdir ? toDirectoryPath(name) : name;

            // confirm size/length
            int nlen = (zname != null) ? zname.length - 1 : 0;  // name has [0] as "slash"
            int elen = (extra != null) ? extra.length : 0;
            int eoff = 0;
            int clen = (comment != null) ? comment.length : 0;
            if (csize >= ZIP64_MINVAL) {
                csize0 = ZIP64_MINVAL;
                elen64 += 8;                 // csize(8)
            }
            if (size >= ZIP64_MINVAL) {
                size0 = ZIP64_MINVAL;        // size(8)
                elen64 += 8;
            }
            if (locoff >= ZIP64_MINVAL) {
                locoff0 = ZIP64_MINVAL;
                elen64 += 8;                 // offset(8)
            }
            if (elen64 != 0) {
                elen64 += 4;                 // header and data sz 4 bytes
            }
            boolean zip64 = (elen64 != 0);
            int version0 = version(zip64);
            while (eoff + 4 < elen) {
                int tag = SH(extra, eoff);
                int sz = SH(extra, eoff + 2);
                if (tag == EXTID_EXTT || tag == EXTID_NTFS) {
                    foundExtraTime = true;
                }
                eoff += (4 + sz);
            }
            if (!foundExtraTime) {
                if (isWindows) {             // use NTFS
                    elenNTFS = 36;           // total 36 bytes
                } else {                     // Extended Timestamp otherwise
                    elenEXTT = 9;            // only mtime in cen
                }
            }
            writeInt(os, CENSIG);            // CEN header signature
            writeShort(os, versionMadeBy(version0)); // version made by
            writeShort(os, version0);        // version needed to extract
            writeShort(os, flag);            // general purpose bit flag
            writeShort(os, method);          // compression method
                                             // last modification time
            writeInt(os, (int)javaToDosTime(mtime));
            writeInt(os, crc);               // crc-32
            writeInt(os, csize0);            // compressed size
            writeInt(os, size0);             // uncompressed size
            writeShort(os, nlen);
            writeShort(os, elen + elen64 + elenNTFS + elenEXTT);

            if (comment != null) {
                writeShort(os, Math.min(clen, 0xffff));
            } else {
                writeShort(os, 0);
            }
            writeShort(os, 0);              // starting disk number
            writeShort(os, 0);              // internal file attributes (unused)
            writeInt(os, posixPerms > 0 ? posixPerms << 16 : 0); // external file
                                            // attributes, used for storing posix
                                            // permissions
            writeInt(os, locoff0);          // relative offset of local header
            writeBytes(os, zname, 1, nlen);
            if (zip64) {
                writeShort(os, EXTID_ZIP64);// Zip64 extra
                writeShort(os, elen64 - 4); // size of "this" extra block
                if (size0 == ZIP64_MINVAL)
                    writeLong(os, size);
                if (csize0 == ZIP64_MINVAL)
                    writeLong(os, csize);
                if (locoff0 == ZIP64_MINVAL)
                    writeLong(os, locoff);
            }
            if (elenNTFS != 0) {
                writeShort(os, EXTID_NTFS);
                writeShort(os, elenNTFS - 4);
                writeInt(os, 0);            // reserved
                writeShort(os, 0x0001);     // NTFS attr tag
                writeShort(os, 24);
                writeLong(os, javaToWinTime(mtime));
                writeLong(os, javaToWinTime(atime));
                writeLong(os, javaToWinTime(ctime));
            }
            if (elenEXTT != 0) {
                writeShort(os, EXTID_EXTT);
                writeShort(os, elenEXTT - 4);
                if (ctime == -1)
                    os.write(0x3);          // mtime and atime
                else
                    os.write(0x7);          // mtime, atime and ctime
                writeInt(os, javaToUnixTime(mtime));
            }
            if (extra != null)              // whatever not recognized
                writeBytes(os, extra);
            if (comment != null)            //TBD: 0, Math.min(commentBytes.length, 0xffff));
                writeBytes(os, comment);
            return CENHDR + nlen + elen + clen + elen64 + elenNTFS + elenEXTT;
        }

        ///////////////////// LOC //////////////////////

        private int writeLOC(OutputStream os) throws IOException {
            byte[] zname = isdir ? toDirectoryPath(name) : name;
            int nlen = (zname != null) ? zname.length - 1 : 0; // [0] is slash
            int elen = (extra != null) ? extra.length : 0;
            boolean foundExtraTime = false;     // if extra timestamp present
            int eoff = 0;
            int elen64 = 0;
            boolean zip64 = false;
            int elenEXTT = 0;
            int elenNTFS = 0;
            writeInt(os, LOCSIG);               // LOC header signature
            if ((flag & FLAG_DATADESCR) != 0) {
                writeShort(os, version(false)); // version needed to extract
                writeShort(os, flag);           // general purpose bit flag
                writeShort(os, method);         // compression method
                // last modification time
                writeInt(os, (int)javaToDosTime(mtime));
                // store size, uncompressed size, and crc-32 in data descriptor
                // immediately following compressed entry data
                writeInt(os, 0);
                writeInt(os, 0);
                writeInt(os, 0);
            } else {
                if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
                    elen64 = 20;    //headid(2) + size(2) + size(8) + csize(8)
                    zip64 = true;
                }
                writeShort(os, version(zip64)); // version needed to extract
                writeShort(os, flag);           // general purpose bit flag
                writeShort(os, method);         // compression method
                                                // last modification time
                writeInt(os, (int)javaToDosTime(mtime));
                writeInt(os, crc);              // crc-32
                if (zip64) {
                    writeInt(os, ZIP64_MINVAL);
                    writeInt(os, ZIP64_MINVAL);
                } else {
                    writeInt(os, csize);        // compressed size
                    writeInt(os, size);         // uncompressed size
                }
            }
            while (eoff + 4 < elen) {
                int tag = SH(extra, eoff);
                int sz = SH(extra, eoff + 2);
                if (tag == EXTID_EXTT || tag == EXTID_NTFS) {
                    foundExtraTime = true;
                }
                eoff += (4 + sz);
            }
            if (!foundExtraTime) {
                if (isWindows) {
                    elenNTFS = 36;              // NTFS, total 36 bytes
                } else {                        // on unix use "ext time"
                    elenEXTT = 9;
                    if (atime != -1)
                        elenEXTT += 4;
                    if (ctime != -1)
                        elenEXTT += 4;
                }
            }
            writeShort(os, nlen);
            writeShort(os, elen + elen64 + elenNTFS + elenEXTT);
            writeBytes(os, zname, 1, nlen);
            if (zip64) {
                writeShort(os, EXTID_ZIP64);
                writeShort(os, 16);
                writeLong(os, size);
                writeLong(os, csize);
            }
            if (elenNTFS != 0) {
                writeShort(os, EXTID_NTFS);
                writeShort(os, elenNTFS - 4);
                writeInt(os, 0);            // reserved
                writeShort(os, 0x0001);     // NTFS attr tag
                writeShort(os, 24);
                writeLong(os, javaToWinTime(mtime));
                writeLong(os, javaToWinTime(atime));
                writeLong(os, javaToWinTime(ctime));
            }
            if (elenEXTT != 0) {
                writeShort(os, EXTID_EXTT);
                writeShort(os, elenEXTT - 4);// size for the folowing data block
                int fbyte = 0x1;
                if (atime != -1)           // mtime and atime
                    fbyte |= 0x2;
                if (ctime != -1)           // mtime, atime and ctime
                    fbyte |= 0x4;
                os.write(fbyte);           // flags byte
                writeInt(os, javaToUnixTime(mtime));
                if (atime != -1)
                    writeInt(os, javaToUnixTime(atime));
                if (ctime != -1)
                    writeInt(os, javaToUnixTime(ctime));
            }
            if (extra != null) {
                writeBytes(os, extra);
            }
            return LOCHDR + nlen + elen + elen64 + elenNTFS + elenEXTT;
        }

        // Data Descriptor
        private int writeEXT(OutputStream os) throws IOException {
            writeInt(os, EXTSIG);           // EXT header signature
            writeInt(os, crc);              // crc-32
            if (csize >= ZIP64_MINVAL || size >= ZIP64_MINVAL) {
                writeLong(os, csize);
                writeLong(os, size);
                return 24;
            } else {
                writeInt(os, csize);        // compressed size
                writeInt(os, size);         // uncompressed size
                return 16;
            }
        }

        // read NTFS, UNIX and ZIP64 data from cen.extra
        private void readExtra(ZipFileSystem zipfs) throws IOException {
            // Note that Section 4.5, Extensible data fields, of the PKWARE ZIP File
            // Format Specification does not mandate a specific order for the
            // data in the extra field, therefore Zip FS cannot assume the data
            // is written in the same order by Zip libraries as Zip FS.
            if (extra == null)
                return;
            int elen = extra.length;
            int off = 0;
            int newOff = 0;
            boolean hasZip64LocOffset = false;
            while (off + 4 < elen) {
                // extra spec: HeaderID+DataSize+Data
                int pos = off;
                int tag = SH(extra, pos);
                int sz = SH(extra, pos + 2);
                pos += 4;
                if (pos + sz > elen)         // invalid data
                    break;
                switch (tag) {
                case EXTID_ZIP64 :
                    if (size == ZIP64_MINVAL) {
                        if (pos + 8 > elen)  // invalid zip64 extra
                            break;           // fields, just skip
                        size = LL(extra, pos);
                        pos += 8;
                    }
                    if (csize == ZIP64_MINVAL) {
                        if (pos + 8 > elen)
                            break;
                        csize = LL(extra, pos);
                        pos += 8;
                    }
                    if (locoff == ZIP64_MINVAL) {
                        if (pos + 8 > elen)
                            break;
                        locoff = LL(extra, pos);
                    }
                    break;
                case EXTID_NTFS:
                    if (sz < 32)
                        break;
                    pos += 4;    // reserved 4 bytes
                    if (SH(extra, pos) !=  0x0001)
                        break;
                    if (SH(extra, pos + 2) != 24)
                        break;
                    // override the loc field, datatime here is
                    // more "accurate"
                    mtime  = winToJavaTime(LL(extra, pos + 4));
                    atime  = winToJavaTime(LL(extra, pos + 12));
                    ctime  = winToJavaTime(LL(extra, pos + 20));
                    break;
                case EXTID_EXTT:
                    // spec says the Extended timestamp in cen only has mtime
                    // need to read the loc to get the extra a/ctime, if flag
                    // "zipinfo-time" is not specified to false;
                    // there is performance cost (move up to loc and read) to
                    // access the loc table foreach entry;
                    if (zipfs.noExtt) {
                        if (sz == 5)
                            mtime = unixToJavaTime(LG(extra, pos + 1));
                         break;
                    }
                    // If the LOC offset is 0xFFFFFFFF, then we need to read the
                    // LOC offset from the EXTID_ZIP64 extra data. Therefore
                    // wait until all of the CEN extra data fields have been processed
                    // prior to reading the LOC extra data field in order to obtain
                    // the Info-ZIP Extended Timestamp.
                    if (locoff != ZIP64_MINVAL) {
                        readLocEXTT(zipfs);
                    } else {
                        hasZip64LocOffset = true;
                    }
                    break;
                default:    // unknown tag
                    System.arraycopy(extra, off, extra, newOff, sz + 4);
                    newOff += (sz + 4);
                }
                off += (sz + 4);
            }

            // We need to read the LOC extra data and the LOC offset was obtained
            // from the EXTID_ZIP64 field.
            if (hasZip64LocOffset) {
                readLocEXTT(zipfs);
            }

            if (newOff != 0 && newOff != extra.length)
                extra = Arrays.copyOf(extra, newOff);
            else
                extra = null;
        }

        /**
         * Read the LOC extra field to obtain the Info-ZIP Extended Timestamp fields
         * @param zipfs The Zip FS to use
         * @throws IOException If an error occurs
         */
        private void readLocEXTT(ZipFileSystem zipfs) throws IOException {
            byte[] buf = new byte[LOCHDR];
            if (zipfs.readFullyAt(buf, 0, buf.length , locoff)
                != buf.length)
                throw new ZipException("loc: reading failed");
            if (!locSigAt(buf, 0))
                throw new ZipException("R"
                                   + Long.toString(getSig(buf, 0), 16));
            int locElen = LOCEXT(buf);
            if (locElen < 9)    // EXTT is at least 9 bytes
                return;
            int locNlen = LOCNAM(buf);
            buf = new byte[locElen];
            if (zipfs.readFullyAt(buf, 0, buf.length , locoff + LOCHDR + locNlen)
                != buf.length)
                throw new ZipException("loc extra: reading failed");
            int locPos = 0;
            while (locPos + 4 < buf.length) {
                int locTag = SH(buf, locPos);
                int locSZ  = SH(buf, locPos + 2);
                locPos += 4;
                if (locTag  != EXTID_EXTT) {
                    locPos += locSZ;
                     continue;
                }
                int end = locPos + locSZ - 4;
                int flag = CH(buf, locPos++);
                if ((flag & 0x1) != 0 && locPos <= end) {
                    mtime = unixToJavaTime(LG(buf, locPos));
                    locPos += 4;
                }
                if ((flag & 0x2) != 0 && locPos <= end) {
                    atime = unixToJavaTime(LG(buf, locPos));
                    locPos += 4;
                }
                if ((flag & 0x4) != 0 && locPos <= end) {
                    ctime = unixToJavaTime(LG(buf, locPos));
                }
                break;
            }
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder(1024);
            Formatter fm = new Formatter(sb);
            fm.format("    name            : %s%n", new String(name));
            fm.format("    creationTime    : %tc%n", creationTime().toMillis());
            fm.format("    lastAccessTime  : %tc%n", lastAccessTime().toMillis());
            fm.format("    lastModifiedTime: %tc%n", lastModifiedTime().toMillis());
            fm.format("    isRegularFile   : %b%n", isRegularFile());
            fm.format("    isDirectory     : %b%n", isDirectory());
            fm.format("    isSymbolicLink  : %b%n", isSymbolicLink());
            fm.format("    isOther         : %b%n", isOther());
            fm.format("    fileKey         : %s%n", fileKey());
            fm.format("    size            : %d%n", size());
            fm.format("    compressedSize  : %d%n", compressedSize());
            fm.format("    crc             : %x%n", crc());
            fm.format("    method          : %d%n", method());
            Set<PosixFilePermission> permissions = storedPermissions().orElse(null);
            if (permissions != null) {
                fm.format("    permissions     : %s%n", permissions);
            }
            fm.close();
            return sb.toString();
        }

        ///////// basic file attributes ///////////
        @Override
        public FileTime creationTime() {
            return FileTime.fromMillis(ctime == -1 ? mtime : ctime);
        }

        @Override
        public boolean isDirectory() {
            return isDir();
        }

        @Override
        public boolean isOther() {
            return false;
        }

        @Override
        public boolean isRegularFile() {
            return !isDir();
        }

        @Override
        public FileTime lastAccessTime() {
            return FileTime.fromMillis(atime == -1 ? mtime : atime);
        }

        @Override
        public FileTime lastModifiedTime() {
            return FileTime.fromMillis(mtime);
        }

        @Override
        public long size() {
            return size;
        }

        @Override
        public boolean isSymbolicLink() {
            return false;
        }

        @Override
        public Object fileKey() {
            return null;
        }

        ///////// zip file attributes ///////////

        @Override
        public long compressedSize() {
            return csize;
        }

        @Override
        public long crc() {
            return crc;
        }

        @Override
        public int method() {
            return method;
        }

        @Override
        public byte[] extra() {
            if (extra != null)
                return Arrays.copyOf(extra, extra.length);
            return null;
        }

        @Override
        public byte[] comment() {
            if (comment != null)
                return Arrays.copyOf(comment, comment.length);
            return null;
        }

        @Override
        public Optional<Set<PosixFilePermission>> storedPermissions() {
            Set<PosixFilePermission> perms = null;
            if (posixPerms != -1) {
                perms = new HashSet<>(PosixFilePermission.values().length);
                for (PosixFilePermission perm : PosixFilePermission.values()) {
                    if ((posixPerms & ZipUtils.permToFlag(perm)) != 0) {
                        perms.add(perm);
                    }
                }
            }
            return Optional.ofNullable(perms);
        }
    }

    final class PosixEntry extends Entry implements PosixFileAttributes {
        private UserPrincipal owner = defaultOwner;
        private GroupPrincipal group = defaultGroup;

        PosixEntry(byte[] name, boolean isdir, int method) {
            super(name, isdir, method);
        }

        PosixEntry(byte[] name, int type, boolean isdir, int method, FileAttribute<?>... attrs) {
            super(name, type, isdir, method, attrs);
        }

        PosixEntry(byte[] name, Path file, int type, FileAttribute<?>... attrs) {
            super(name, file, type, attrs);
        }

        PosixEntry(PosixEntry e, int type, int compressionMethod) {
            super(e, type);
            this.method = compressionMethod;
        }

        PosixEntry(PosixEntry e, int type) {
            super(e, type);
            this.owner = e.owner;
            this.group = e.group;
        }

        PosixEntry(ZipFileSystem zipfs, IndexNode inode) throws IOException {
            super(zipfs, inode);
        }

        @Override
        public UserPrincipal owner() {
            return owner;
        }

        @Override
        public GroupPrincipal group() {
            return group;
        }

        @Override
        public Set<PosixFilePermission> permissions() {
            return storedPermissions().orElse(Set.copyOf(defaultPermissions));
        }
    }

    // purely for parent lookup, so we don't have to copy the parent
    // name every time
    static class ParentLookup extends IndexNode {
        int len;
        ParentLookup() {}

        final ParentLookup as(byte[] name, int len) { // as a lookup "key"
            name(name, len);
            return this;
        }

        void name(byte[] name, int len) {
            this.name = name;
            this.len = len;
            // calculate the hashcode the same way as Arrays.hashCode() does
            int result = 1;
            for (int i = 0; i < len; i++)
                result = 31 * result + name[i];
            this.hashcode = result;
        }

        @Override
        public boolean equals(Object other) {
            if (!(other instanceof IndexNode)) {
                return false;
            }
            byte[] oname = ((IndexNode)other).name;
            return Arrays.equals(name, 0, len,
                                 oname, 0, oname.length);
        }
    }
}
