src/main/java/org/codehaus/plexus/archiver/zip/AbstractZipArchiver.java
@SuppressWarnings({"JavaDoc"})
    protected void zipFile( InputStream in, ZipArchiveOutputStream zOut, String vPath, long lastModified, File fromArchive,
                            int mode, String symlinkDestination )
        throws IOException, ArchiverException
    {
        getLogger().debug( "adding entry " + vPath );

        entries.put( vPath, vPath );

        if ( !skipWriting )
        {
            ZipArchiveEntry ze = new ZipArchiveEntry( vPath );
            setTime(ze, lastModified);

            byte[] header = new byte[4];
            int read = in.read(header);

            boolean compressThis = doCompress;
            if (!recompressAddedZips && isZipHeader(header)){
                compressThis = false;
            }

            ze.setMethod( compressThis ? ZipArchiveEntry.DEFLATED : ZipArchiveEntry.STORED );
            ze.setUnixMode( UnixStat.FILE_FLAG | mode );
            /*
             * ZipOutputStream.putNextEntry expects the ZipEntry to
             * know its size and the CRC sum before you start writing
             * the data when using STORED mode - unless it is seekable.
             *
             * This forces us to process the data twice.
             */


            if (ze.isUnixSymlink()){
                zOut.putArchiveEntry( ze );
                ZipEncoding enc = ZipEncodingHelper.getZipEncoding( getEncoding() );
                final byte[] bytes =  enc.encode( symlinkDestination).array();
                zOut.write( bytes, 0, bytes.length);
            } else if (zOut.isSeekable() || compressThis) {
                zOut.putArchiveEntry( ze );
                if (read > 0) zOut.write(header, 0, read);
                IOUtil.copy( in, zOut, 8 * 1024);
            } else {
                if (in.markSupported())
                {
                    in.mark( Integer.MAX_VALUE );
                    readWithZipStats(in, header, read, ze, null);
                    in.reset();
                    zOut.putArchiveEntry( ze);
                    if (read > 0) zOut.write(header, 0, read);
                    IOUtil.copy(in, zOut, 8 * 1024);
                }
                else
                {
                    // Store data into a byte[]
                    // todo: explain how on earth this code works with zip streams > 128KB ???
                    ByteArrayOutputStream bos = new ByteArrayOutputStream(128 * 1024);
                    readWithZipStats(in, header,read, ze, bos);
                    zOut.putArchiveEntry(ze);
                    if (read > 0) zOut.write(header, 0, read);
                    bos.writeTo( zOut);
                }
            }

            zOut.closeArchiveEntry();
        }
    }
@SuppressWarnings({"JavaDoc"})
    protected void zipFile( InputStream in, ZipArchiveOutputStream zOut, String vPath, long lastModified, File fromArchive,
                            int mode, String symlinkDestination )
        throws IOException, ArchiverException
    {
        getLogger().debug( "adding entry " + vPath );

        entries.put( vPath, vPath );

        if ( !skipWriting )
        {
            ZipArchiveEntry ze = new ZipArchiveEntry( vPath );
            setTime(ze, lastModified);

            byte[] header = new byte[4];
            int read = in.read(header);

            boolean compressThis = doCompress;
            if (!recompressAddedZips && isZipHeader(header)){
                compressThis = false;
            }

            ze.setMethod( compressThis ? ZipArchiveEntry.DEFLATED : ZipArchiveEntry.STORED );
            ze.setUnixMode( UnixStat.FILE_FLAG | mode );
            /*
             * ZipOutputStream.putNextEntry expects the ZipEntry to
             * know its size and the CRC sum before you start writing
             * the data when using STORED mode - unless it is seekable.
             *
             * This forces us to process the data twice.
             */


            if (ze.isUnixSymlink()){
                zOut.putArchiveEntry( ze );
                ZipEncoding enc = ZipEncodingHelper.getZipEncoding( getEncoding() );
                final byte[] bytes =  enc.encode( symlinkDestination).array();
                zOut.write( bytes, 0, bytes.length);
            } else if (zOut.isSeekable() || compressThis) {
                zOut.putArchiveEntry( ze );
                if (read > 0) zOut.write(header, 0, read);
                IOUtil.copy( in, zOut, 8 * 1024);
            } else {
                if (in.markSupported())
                {
                    in.mark( Integer.MAX_VALUE );
                    readWithZipStats(in, header, read, ze, null);
                    in.reset();
                    zOut.putArchiveEntry( ze);
                    if (read > 0) zOut.write(header, 0, read);
                    IOUtil.copy(in, zOut, 8 * 1024);
                }
                else
                {
                    // Store data into a byte[]
                    // todo: explain how on earth this code works with zip streams > 128KB ???
                    ByteArrayOutputStream bos = new ByteArrayOutputStream(128 * 1024);
                    readWithZipStats(in, header,read, ze, bos);
                    zOut.putArchiveEntry(ze);
                    if (read > 0) zOut.write(header, 0, read);
                    bos.writeTo( zOut);
                }
            }

            zOut.closeArchiveEntry();
        }
    }
Adds a new entry to the archive, takes care of duplicates as well.

@param in           the stream to read data for the entry from.
@param zOut         the stream to write to.
@param vPath        the name this entry shall have in the archive.
@param lastModified last modification time for the entry.
@param fromArchive  the original archive we are copying this
@param symlinkDestination