[DRE-commits] [ruby-zip] 01/02: Imported Upstream version 1.1.2

Antonio Terceiro terceiro at moszumanska.debian.org
Sun Mar 23 17:44:21 UTC 2014


This is an automated email from the git hooks/post-receive script.

terceiro pushed a commit to branch master
in repository ruby-zip.

commit 4dff2b821eed0954e4d49e5922fd967a9ad5fdf4
Author: Antonio Terceiro <terceiro at debian.org>
Date:   Sun Mar 23 14:24:02 2014 -0300

    Imported Upstream version 1.1.2
---
 .gitignore                                   |    1 +
 test/alltests.rb => .simplecov               |    9 -
 .travis.yml                                  |    7 +-
 Changelog.md                                 |   10 +
 Gemfile                                      |   10 +
 README.md                                    |   70 +-
 Rakefile                                     |   18 +-
 TODO                                         |    1 -
 lib/zip.rb                                   |    4 +-
 lib/zip/central_directory.rb                 |   29 +-
 lib/zip/deflater.rb                          |    2 +-
 lib/zip/entry.rb                             |   66 +-
 lib/zip/entry_set.rb                         |    2 +-
 lib/zip/errors.rb                            |   12 +-
 lib/zip/extra_field.rb                       |   11 +-
 lib/zip/extra_field/generic.rb               |    8 +-
 lib/zip/extra_field/old_unix.rb              |   45 +
 lib/zip/file.rb                              |   83 +-
 lib/zip/inflater.rb                          |   59 +-
 lib/zip/input_stream.rb                      |   32 +-
 lib/zip/output_stream.rb                     |   74 +-
 lib/zip/streamable_stream.rb                 |   29 +-
 lib/zip/version.rb                           |    2 +-
 test/.cvsignore                              |   11 -
 test/basic_zip_file_test.rb                  |   64 +
 test/central_directory_entry_test.rb         |   73 +
 test/central_directory_test.rb               |  100 ++
 test/data/.cvsignore                         |    1 -
 test/deflater_test.rb                        |   62 +
 test/entry_set_test.rb                       |  125 ++
 test/entry_test.rb                           |  132 ++
 test/extra_field_test.rb                     |   69 +
 test/file_extract_directory_test.rb          |   55 +
 test/file_extract_test.rb                    |   90 ++
 test/file_split_test.rb                      |   60 +
 test/file_test.rb                            |  543 +++++++
 test/filesystem/dir_iterator_test.rb         |   62 +
 test/filesystem/directory_test.rb            |  131 ++
 test/filesystem/file_mutating_test.rb        |  100 ++
 test/filesystem/file_nonmutating_test.rb     |  505 +++++++
 test/filesystem/file_stat_test.rb            |   66 +
 test/gentestfiles.rb                         |  199 ++-
 test/inflater_test.rb                        |   14 +
 test/input_stream_test.rb                    |  160 ++
 test/ioextras/abstract_input_stream_test.rb  |  103 ++
 test/ioextras/abstract_output_stream_test.rb |  106 ++
 test/ioextras/fake_io_test.rb                |   18 +
 test/ioextrastest.rb                         |  234 ---
 test/local_entry_test.rb                     |  153 ++
 test/output_stream_test.rb                   |  114 ++
 test/pass_thru_compressor_test.rb            |   31 +
 test/pass_thru_decompressor_test.rb          |   15 +
 test/settings_test.rb                        |   71 +
 test/test_helper.rb                          |  228 +++
 test/unicode_file_names_and_comments.rb      |   38 +
 test/zip64_full_test.rb                      |   73 +-
 test/zip64_support_test.rb                   |   15 +
 test/zipfilesystemtest.rb                    |  893 -----------
 test/ziptest.rb                              | 2075 --------------------------
 testAllRubies.sh                             |    4 -
 60 files changed, 3783 insertions(+), 3594 deletions(-)

diff --git a/.gitignore b/.gitignore
index 2f25087..8c23598 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ test/huge.zip
 test/centralEntryHeader.bin
 test/data/generated/
 test/deflatertest.bin
+test/compressiontest_*.bin
 test/dummy.txt
 test/localEntryHeader.bin
 test/okToDeleteMoved.txt
diff --git a/test/alltests.rb b/.simplecov
old mode 100755
new mode 100644
similarity index 53%
rename from test/alltests.rb
rename to .simplecov
index aa64010..b205ee2
--- a/test/alltests.rb
+++ b/.simplecov
@@ -1,5 +1,3 @@
-#!/usr/bin/env ruby
-require 'simplecov'
 require 'coveralls'
 
 SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
@@ -9,10 +7,3 @@ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
 SimpleCov.start do
   add_filter '/test'
 end
-Dir.chdir File.join(File.dirname(__FILE__))
-
-$VERBOSE = true
-
-require 'ioextrastest'
-require 'ziptest'
-require 'zipfilesystemtest'
diff --git a/.travis.yml b/.travis.yml
index b6016d0..e6be98e 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,10 +1,10 @@
 language: ruby
 rvm:
-  - 1.9.2
   - 1.9.3
   - 2.0.0
+  - 2.1.1
   - ruby-head
-  - rbx-19mode
+  - rbx
 matrix:
   include:
   - rvm: jruby-19mode
@@ -19,8 +19,5 @@ before_script:
   - sudo apt-get install -qq zip unzip
   - echo `whereis zip`
   - echo `whereis unzip`
-branches:
-  only:
-    - master
 allow_failures:
   - rvm: ruby-head
diff --git a/Changelog.md b/Changelog.md
index f099839..734ccaa 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,13 @@
+1.1.1
+=====
+
+* Speedup deflater (@loadhigh)
+* Less Arrays and Strings allocations (@srawlins)
+* Fix Zip64 writting support (@mrjamesriley)
+* Fix StringIO support (@simonoff)
+* Posibility to change default compression level
+* Make Zip64 write support optional via configuration 
+
 1.1.0
 =====
 
diff --git a/Gemfile b/Gemfile
index 7c6d3ed..8dfc2a4 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,6 +1,16 @@
 source 'https://rubygems.org'
 
+
+platforms :rbx do
+  gem 'rubysl', '~> 2.0'
+  gem 'rubysl-test-unit'
+  gem 'rubinius-developer_tools'
+  gem 'json'
+end
+
+
 gemspec
 gem 'rake'
 gem 'coveralls', :require => false
 gem 'pry'
+gem 'minitest'
diff --git a/README.md b/README.md
index 5137c5d..71a9f77 100644
--- a/README.md
+++ b/README.md
@@ -9,11 +9,11 @@ rubyzip is a ruby library for reading and writing zip files.
 
 Rubyzip interface changed!!! No need to do `require "zip/zip"` and `Zip` prefix in class names removed.
 
-If you have issues with any third-party gems what required rubyzip you can use next temporary fix:
+If you have issues with any third-party gems what required old version of rubyzip you can use next workaround:
 
 ```ruby
-# Place this line before your library or on the head of your Gemfile
-gem 'rubyzip', '< 1.0.0'
+gem 'rubyzip', '>= 1.0.0' # will load new rubyzip version
+gem 'zip-zip' # will load compatibility for old rubyzip API.
 ```
 
 ## Requirements
@@ -53,6 +53,7 @@ Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
     # - The original file, including the path to find it
     zipfile.add(filename, folder + '/' + filename)
   end
+  zipfile.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
 end
 ```
 
@@ -90,6 +91,26 @@ fruit/orange
 
 After this entries in zip archive will be saved in ordered state.
 
+### Reading a Zip file
+
+```ruby
+Zip::File.open('foo.zip') do |zip_file|
+  # Handle entries one by one
+  zip_file.each do |entry|
+    # Extract to file/directory/symlink
+    puts "Extracting #{entry.name}"
+    entry.extract(dest_file)
+
+    # Read into memory
+    content = entry.get_input_stream.read
+  end
+
+  # Find specific entry
+  entry = zip_file.glob('*.csv').first
+  puts entry.get_input_stream.read
+end
+```
+
 ## Known issues
 
 ### Modify docx file with rubyzip
@@ -115,32 +136,6 @@ end
 File.open(new_path, "w") {|f| f.write(buffer.string) }
 ```
 
-## Further Documentation
-
-There is more than one way to access or create a zip archive with
-rubyzip. The basic API is modeled after the classes in
-java.util.zip from the Java SDK. This means there are classes such
-as Zip::InputStream, Zip::OutputStream and
-Zip::File. Zip::InputStream provides a basic interface for
-iterating through the entries in a zip archive and reading from the
-entries in the same way as from a regular File or IO
-object. OutputStream is the corresponding basic output
-facility. Zip::File provides a mean for accessing the archives
-central directory and provides means for accessing any entry without
-having to iterate through the archive. Unlike Java's
-java.util.zip.ZipFile rubyzip's Zip::File is mutable, which means
-it can be used to change zip files as well.
-
-Another way to access a zip archive with rubyzip is to use rubyzip's
-Zip::FileSystem API. Using this API files can be read from and
-written to the archive in much the same manner as ruby's builtin
-classes allows files to be read from and written to the file system.
-
-For details about the specific behaviour of classes and methods refer
-to the test suite. Finally you can generate the rdoc documentation or
-visit http://rubyzip.sourceforge.net.
-
-
 ## Configuration
 
 By default, rubyzip will not overwrite files if they already exist inside of the extracted path.  To change this behavior, you may specify a configuration option like so:
@@ -163,6 +158,14 @@ If you want to store non english names and want to open properly file on Windows
 Zip.unicode_names = true
 ```
 
+You can set the default compression level like so:
+
+```ruby
+Zip.default_compression = Zlib::DEFAULT_COMPRESSION
+```
+
+It defaults to `Zlib::DEFAULT_COMPRESSION`. Possible values are `Zlib::BEST_COMPRESSION`, `Zlib::DEFAULT_COMPRESSION` and `Zlib::NO_COMPRESSION`
+
 All settings in same time
 
 ```ruby
@@ -170,9 +173,18 @@ All settings in same time
     c.on_exists_proc = true
     c.continue_on_exists_proc = true
     c.unicode_names = true
+    c.default_compression = Zlib::BEST_COMPRESSION
   end
 ```
 
+By default Zip64 support is disabled for writing. To enable it do next:
+
+```ruby
+Zip.write_zip64_support = true
+```
+
+_NOTE_: If you will enable Zip64 writing then you will need zip extractor with Zip64 support to extract archive.
+
 ## Developing
 
 To run tests you need run next commands:
diff --git a/Rakefile b/Rakefile
index fef685f..0e41a39 100644
--- a/Rakefile
+++ b/Rakefile
@@ -4,16 +4,16 @@ require 'rake/testtask'
 task :default => :test
 
 Rake::TestTask.new(:test) do |test|
-  test.libs << File.join(File.dirname(__FILE__), 'lib')
-  test.libs << File.join(File.dirname(__FILE__), 'test')
-  test.pattern = File.join(File.dirname(__FILE__), 'test/alltests.rb')
+  test.libs << 'lib'
+  test.libs << 'test'
+  test.pattern = 'test/**/*_test.rb'
   test.verbose = true
 end
 
-Rake::TestTask.new(:zip64_full_test) do |test|
-  test.libs << File.join(File.dirname(__FILE__), 'lib')
-  test.libs << File.join(File.dirname(__FILE__), 'test')
-  test.pattern = File.join(File.dirname(__FILE__), 'test/zip64_full_test.rb')
-  test.verbose = true
-end
+#Rake::TestTask.new(:zip64_full_test) do |test|
+#  test.libs << File.join(File.dirname(__FILE__), 'lib')
+#  test.libs << File.join(File.dirname(__FILE__), 'test')
+#  test.pattern = File.join(File.dirname(__FILE__), 'test/zip64_full_test.rb')
+#  test.verbose = true
+#end
 
diff --git a/TODO b/TODO
index 0e89e39..16b9a2e 100644
--- a/TODO
+++ b/TODO
@@ -4,7 +4,6 @@
 * Suggestion: Add ZipFile/ZipInputStream example that demonstrates extracting all entries.
 * Suggestion: ZipFile#extract destination should default to "."
 * Suggestion: ZipEntry should have extract(), get_input_stream() methods etc
-* Suggestion: ZipInputStream/ZipOutputStream should accept an IO object in addition to a filename.
 * (is buffering used anywhere with write?)
 * Inflater.sysread should pass the buffer to produce_input.
 * Implement ZipFsDir.glob
diff --git a/lib/zip.rb b/lib/zip.rb
index f78a9fe..1ddafa8 100644
--- a/lib/zip.rb
+++ b/lib/zip.rb
@@ -34,7 +34,7 @@ end
 
 module Zip
   extend self
-  attr_accessor :unicode_names, :on_exists_proc, :continue_on_exists_proc, :sort_entries
+  attr_accessor :unicode_names, :on_exists_proc, :continue_on_exists_proc, :sort_entries, :default_compression, :write_zip64_support
 
   def reset!
     @_ran_once = false
@@ -42,6 +42,8 @@ module Zip
     @on_exists_proc = false
     @continue_on_exists_proc = false
     @sort_entries = false
+    @default_compression = ::Zlib::DEFAULT_COMPRESSION
+    @write_zip64_support = false
   end
 
   def setup
diff --git a/lib/zip/central_directory.rb b/lib/zip/central_directory.rb
index 50d3756..b02de4c 100755
--- a/lib/zip/central_directory.rb
+++ b/lib/zip/central_directory.rb
@@ -26,10 +26,13 @@ module Zip
       @entry_set.each { |entry| entry.write_c_dir_entry(io) }
       eocd_offset = io.tell
       cdir_size = eocd_offset - cdir_offset
-      has_zip64_entry = @entry_set.any? { |entry| entry.extra['Zip64'] }
-      if has_zip64_entry || cdir_offset > 0xFFFFFFFF || cdir_size > 0xFFFFFFFF || @entry_set.size > 0xFFFF
-        write_64_e_o_c_d(io, cdir_offset, cdir_size)
-        write_64_eocd_locator(io, eocd_offset)
+      if ::Zip.write_zip64_support
+        need_zip64_eocd = cdir_offset > 0xFFFFFFFF || cdir_size > 0xFFFFFFFF || @entry_set.size > 0xFFFF
+        need_zip64_eocd ||= @entry_set.any? { |entry| entry.extra['Zip64'] }
+        if need_zip64_eocd
+          write_64_e_o_c_d(io, cdir_offset, cdir_size)
+          write_64_eocd_locator(io, eocd_offset)
+        end
       end
       write_e_o_c_d(io, cdir_offset, cdir_size)
     end
@@ -93,7 +96,7 @@ module Zip
       @size_in_bytes                                = Entry.read_zip_64_long(buf)
       @cdir_offset                                  = Entry.read_zip_64_long(buf)
       @zip_64_extensible                            = buf.slice!(0, buf.bytesize)
-      raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
+      raise Error, "Zip consistency problem while reading eocd structure" unless buf.size == 0
     end
 
     def read_e_o_c_d(buf) #:nodoc:
@@ -105,19 +108,19 @@ module Zip
       @size_in_bytes                                = Entry.read_zip_long(buf)
       @cdir_offset                                  = Entry.read_zip_long(buf)
       comment_length                                = Entry.read_zip_short(buf)
-      @comment                                      = if comment_length <= 0
+      @comment                                      = if comment_length.to_i <= 0
                                                         buf.slice!(0, buf.size)
                                                       else
                                                         buf.read(comment_length)
                                                       end
-      raise ZipError, "Zip consistency problem while reading eocd structure" unless buf.size == 0
+      raise Error, "Zip consistency problem while reading eocd structure" unless buf.size == 0
     end
 
     def read_central_directory_entries(io) #:nodoc:
       begin
         io.seek(@cdir_offset, IO::SEEK_SET)
       rescue Errno::EINVAL
-        raise ZipError, "Zip consistency problem while reading central directory entry"
+        raise Error, "Zip consistency problem while reading central directory entry"
       end
       @entry_set = EntrySet.new
       @size.times do
@@ -137,7 +140,7 @@ module Zip
 
     def get_e_o_c_d(buf) #:nodoc:
       sig_index = buf.rindex([END_OF_CDS].pack('V'))
-      raise ZipError, "Zip end of central directory signature not found" unless sig_index
+      raise Error, "Zip end of central directory signature not found" unless sig_index
       buf = buf.slice!((sig_index + 4)..(buf.bytesize))
 
       def buf.read(count)
@@ -162,9 +165,9 @@ module Zip
 
     def get_64_e_o_c_d(buf) #:nodoc:
       zip_64_start = buf.rindex([ZIP64_END_OF_CDS].pack('V'))
-      raise ZipError, "Zip64 end of central directory signature not found" unless zip_64_start
+      raise Error, "Zip64 end of central directory signature not found" unless zip_64_start
       zip_64_locator = buf.rindex([ZIP64_EOCD_LOCATOR].pack('V'))
-      raise ZipError, "Zip64 end of central directory signature locator not found" unless zip_64_locator
+      raise Error, "Zip64 end of central directory signature locator not found" unless zip_64_locator
       buf = buf.slice!((zip_64_start + 4)..zip_64_locator)
 
       def buf.read(count)
@@ -179,7 +182,7 @@ module Zip
       @entry_set.each(&proc)
     end
 
-    # Returns the number of entries in the central directory (and 
+    # Returns the number of entries in the central directory (and
     # consequently in the zip archive).
     def size
       @entry_set.size
@@ -189,7 +192,7 @@ module Zip
       cdir = new
       cdir.read_from_stream(io)
       return cdir
-    rescue ZipError
+    rescue Error
       return nil
     end
 
diff --git a/lib/zip/deflater.rb b/lib/zip/deflater.rb
index 01e923b..84a8c0b 100755
--- a/lib/zip/deflater.rb
+++ b/lib/zip/deflater.rb
@@ -1,7 +1,7 @@
 module Zip
   class Deflater < Compressor #:nodoc:all
 
-    def initialize(output_stream, level = ::Zlib::DEFAULT_COMPRESSION)
+    def initialize(output_stream, level = Zip.default_compression)
       super()
       @output_stream = output_stream
       @zlib_deflater = ::Zlib::Deflate.new(level, -::Zlib::MAX_WBITS)
diff --git a/lib/zip/entry.rb b/lib/zip/entry.rb
index 23691e4..23a307c 100755
--- a/lib/zip/entry.rb
+++ b/lib/zip/entry.rb
@@ -15,7 +15,7 @@ module Zip
 
     def set_default_vars_values
       @local_header_offset      = 0
-      @local_header_size        = 0
+      @local_header_size        = nil # not known until local entry is created or read
       @internal_file_attributes = 1
       @external_file_attributes = 0
       @header_signature         = ::Zip::CENTRAL_DIRECTORY_ENTRY_SIGNATURE
@@ -46,7 +46,7 @@ module Zip
 
     def check_name(name)
       if name.start_with?('/')
-        raise ::Zip::ZipEntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
+        raise ::Zip::EntryNameError, "Illegal ZipEntry name '#{name}', name must not start with /"
       end
     end
 
@@ -92,7 +92,7 @@ module Zip
     end
 
     def file_type_is?(type)
-      raise ZipInternalError, "current filetype is unknown: #{self.inspect}" unless @ftype
+      raise InternalError, "current filetype is unknown: #{self.inspect}" unless @ftype
       @ftype == type
     end
 
@@ -130,9 +130,9 @@ module Zip
     # check before rewriting an entry (after file sizes are known)
     # that we didn't change the header size (and thus clobber file data or something)
     def verify_local_header_size!
-      return if @local_header_size == 0
+      return if @local_header_size.nil?
       new_size = calculate_local_header_size
-      raise ZipError, "local header size changed (#{@local_header_size} -> #{new_size})" if @local_header_size != new_size
+      raise Error, "local header size changed (#{@local_header_size} -> #{new_size})" if @local_header_size != new_size
     end
 
     def cdir_header_size #:nodoc:all
@@ -177,18 +177,23 @@ module Zip
       end
 
       def read_c_dir_entry(io) #:nodoc:all
-        entry = new(io.path)
+        path = if io.is_a?(::IO)
+              io.path
+             else
+               io
+             end
+        entry = new(path)
         entry.read_c_dir_entry(io)
         entry
-      rescue ZipError
+      rescue Error
         nil
       end
 
       def read_local_entry(io)
-        entry = self.new
+        entry = self.new(io)
         entry.read_local_entry(io)
         entry
-      rescue ZipError
+      rescue Error
         nil
       end
 
@@ -217,13 +222,13 @@ module Zip
       static_sized_fields_buf = io.read(::Zip::LOCAL_ENTRY_STATIC_HEADER_LENGTH)
 
       unless static_sized_fields_buf.bytesize == ::Zip::LOCAL_ENTRY_STATIC_HEADER_LENGTH
-        raise ZipError, "Premature end of file. Not enough data for zip entry local header"
+        raise Error, "Premature end of file. Not enough data for zip entry local header"
       end
 
       unpack_local_entry(static_sized_fields_buf)
 
       unless @header_signature == ::Zip::LOCAL_ENTRY_SIGNATURE
-        raise ::Zip::ZipError, "Zip local header magic not found at location '#{local_header_offset}'"
+        raise ::Zip::Error, "Zip local header magic not found at location '#{local_header_offset}'"
       end
       set_time(@last_mod_date, @last_mod_time)
 
@@ -233,7 +238,7 @@ module Zip
       @name.gsub!('\\', '/')
 
       if extra && extra.bytesize != @extra_length
-        raise ::Zip::ZipError, "Truncated local zip entry header"
+        raise ::Zip::Error, "Truncated local zip entry header"
       else
         if ::Zip::ExtraField === @extra
           @extra.merge(extra)
@@ -327,19 +332,19 @@ module Zip
 
     def check_c_dir_entry_static_header_length(buf)
       unless buf.bytesize == ::Zip::CDIR_ENTRY_STATIC_HEADER_LENGTH
-        raise ZipError, 'Premature end of file. Not enough data for zip cdir entry header'
+        raise Error, 'Premature end of file. Not enough data for zip cdir entry header'
       end
     end
 
     def check_c_dir_entry_signature
       unless header_signature == ::Zip::CENTRAL_DIRECTORY_ENTRY_SIGNATURE
-        raise ZipError, "Zip local header magic not found at location '#{local_header_offset}'"
+        raise Error, "Zip local header magic not found at location '#{local_header_offset}'"
       end
     end
 
     def check_c_dir_entry_comment_size
       unless @comment && @comment.bytesize == @comment_length
-        raise ::Zip::ZipError, "Truncated cdir zip entry header"
+        raise ::Zip::Error, "Truncated cdir zip entry header"
       end
     end
 
@@ -363,7 +368,6 @@ module Zip
       check_c_dir_entry_comment_size
       set_ftype_from_c_dir_entry
       parse_zip64_extra(false)
-      @local_header_size = calculate_local_header_size
     end
 
     def file_stat(path) # :nodoc:
@@ -422,7 +426,10 @@ module Zip
         (zip64 && zip64.disk_start_number) ? 0xFFFF : 0, # disk number start
         @internal_file_attributes, # file type (binary=0, text=1)
         @external_file_attributes, # native filesystem attributes
-        (zip64 && zip64.relative_header_offset) ? 0xFFFFFFFF : @local_header_offset
+        (zip64 && zip64.relative_header_offset) ? 0xFFFFFFFF : @local_header_offset,
+        @name,
+        @extra,
+        @comment
       ].pack('VCCvvvvvVVVvvvvvVV')
     end
 
@@ -511,7 +518,7 @@ module Zip
                  end
                  :file
                when 'directory'
-                 @name += "/" unless name_is_directory?
+                 @name += '/' unless name_is_directory?
                  :directory
                when 'link'
                  if name_is_directory?
@@ -530,9 +537,9 @@ module Zip
 
     def write_to_zip_output_stream(zip_output_stream) #:nodoc:all
       if @ftype == :directory
-        zip_output_stream.put_next_entry(self)
+        zip_output_stream.put_next_entry(self, nil, nil, ::Zip::Entry::STORED)
       elsif @filepath
-        zip_output_stream.put_next_entry(self, nil, nil, nil)
+        zip_output_stream.put_next_entry(self, nil, nil, ::Zip::Entry::DEFLATED)
         get_input_stream { |is| ::Zip::IOExtras.copy_stream(zip_output_stream, is) }
       else
         zip_output_stream.copy_raw_entry(self)
@@ -546,7 +553,11 @@ module Zip
     end
 
     def get_raw_input_stream(&block)
-      ::File.open(@zipfile, "rb", &block)
+      if @zipfile.is_a?(::IO) || @zipfile.is_a?(::StringIO)
+        yield @zipfile
+      else
+        ::File.open(@zipfile, "rb", &block)
+      end
     end
 
     private
@@ -558,8 +569,8 @@ module Zip
     end
 
     def create_file(dest_path, continue_on_exists_proc = proc { Zip.continue_on_exists_proc })
-      if ::File.exists?(dest_path) && !yield(self, dest_path)
-        raise ::Zip::ZipDestinationFileExistsError,
+      if ::File.exist?(dest_path) && !yield(self, dest_path)
+        raise ::Zip::DestinationFileExistsError,
               "Destination '#{dest_path}' already exists"
       end
       ::File.open(dest_path, "wb") do |os|
@@ -576,11 +587,11 @@ module Zip
 
     def create_directory(dest_path)
       return if ::File.directory?(dest_path)
-      if ::File.exists?(dest_path)
+      if ::File.exist?(dest_path)
         if block_given? && yield(self, dest_path)
           ::FileUtils::rm_f dest_path
         else
-          raise ::Zip::ZipDestinationFileExistsError,
+          raise ::Zip::DestinationFileExistsError,
                 "Cannot create directory '#{dest_path}'. "+
                   "A file already exists with that name"
         end
@@ -605,12 +616,12 @@ module Zip
           if ::File.readlink(dest_path) == linkto
             return
           else
-            raise ZipDestinationFileExistsError,
+            raise ::Zip::DestinationFileExistsError,
                   "Cannot create symlink '#{dest_path}'. "+
                     "A symlink already exists with that name"
           end
         else
-          raise ZipDestinationFileExistsError,
+          raise ::Zip::DestinationFileExistsError,
                 "Cannot create symlink '#{dest_path}'. "+
                   "A file already exists with that name"
         end
@@ -633,6 +644,7 @@ module Zip
 
     # create a zip64 extra information field if we need one
     def prep_zip64_extra(for_local_header) #:nodoc:all
+      return unless ::Zip.write_zip64_support
       need_zip64 = @size >= 0xFFFFFFFF || @compressed_size >= 0xFFFFFFFF
       unless for_local_header
         need_zip64 ||= @local_header_offset >= 0xFFFFFFFF
diff --git a/lib/zip/entry_set.rb b/lib/zip/entry_set.rb
index 265acbd..4667150 100755
--- a/lib/zip/entry_set.rb
+++ b/lib/zip/entry_set.rb
@@ -77,7 +77,7 @@ module Zip
 
     private
     def to_key(entry)
-      entry.to_s.sub(/\/$/, '')
+      entry.to_s.chomp('/')
     end
   end
 end
diff --git a/lib/zip/errors.rb b/lib/zip/errors.rb
index 7043ee9..78e3156 100644
--- a/lib/zip/errors.rb
+++ b/lib/zip/errors.rb
@@ -1,8 +1,8 @@
 module Zip
-  class ZipError < StandardError; end
-  class ZipEntryExistsError < ZipError; end
-  class ZipDestinationFileExistsError < ZipError; end
-  class ZipCompressionMethodError < ZipError; end
-  class ZipEntryNameError < ZipError; end
-  class ZipInternalError < ZipError; end
+  class Error < StandardError; end
+  class EntryExistsError < Error; end
+  class DestinationFileExistsError < Error; end
+  class CompressionMethodError < Error; end
+  class EntryNameError < Error; end
+  class InternalError < Error; end
 end
diff --git a/lib/zip/extra_field.rb b/lib/zip/extra_field.rb
index 6760a4a..f7a7172 100755
--- a/lib/zip/extra_field.rb
+++ b/lib/zip/extra_field.rb
@@ -52,7 +52,7 @@ module Zip
 
     def create(name)
       unless field_class = ID_MAP.values.find { |k| k.name == name }
-        raise ZipError, "Unknown extra field '#{name}'"
+        raise Error, "Unknown extra field '#{name}'"
       end
       self[name] = field_class.new
     end
@@ -60,17 +60,19 @@ module Zip
     # place Unknown last, so "extra" data that is missing the proper signature/size
     # does not prevent known fields from being read back in
     def ordered_values
-      self.keys.sort_by { |k| k == 'Unknown' ? 1 : 0 }.map { |k| self[k] }
+      result = []
+      self.each { |k,v| k == 'Unknown' ? result.push(v) : result.unshift(v) }
+      result
     end
 
     def to_local_bin
-      ordered_values.map { |v| v.to_local_bin.force_encoding('BINARY') }.join
+      ordered_values.map! { |v| v.to_local_bin.force_encoding('BINARY') }.join
     end
 
     alias :to_s :to_local_bin
 
     def to_c_dir_bin
-      ordered_values.map { |v| v.to_c_dir_bin.force_encoding('BINARY') }.join
+      ordered_values.map! { |v| v.to_c_dir_bin.force_encoding('BINARY') }.join
     end
 
     def c_dir_size
@@ -88,6 +90,7 @@ end
 
 require 'zip/extra_field/generic'
 require 'zip/extra_field/universal_time'
+require 'zip/extra_field/old_unix'
 require 'zip/extra_field/unix'
 require 'zip/extra_field/zip64'
 require 'zip/extra_field/zip64_placeholder'
diff --git a/lib/zip/extra_field/generic.rb b/lib/zip/extra_field/generic.rb
index be53544..d375722 100644
--- a/lib/zip/extra_field/generic.rb
+++ b/lib/zip/extra_field/generic.rb
@@ -7,7 +7,7 @@ module Zip
     end
 
     def self.name
-      self.to_s.split("::")[-1]
+      @name ||= self.to_s.split("::")[-1]
     end
 
     # return field [size, content] or false
@@ -32,12 +32,12 @@ module Zip
 
     def to_local_bin
       s = pack_for_local
-      self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") + s
+      self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") << s
     end
 
     def to_c_dir_bin
       s = pack_for_c_dir
-      self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") + s
+      self.class.const_get(:HEADER_ID) + [s.bytesize].pack("v") << s
     end
   end
-end
\ No newline at end of file
+end
diff --git a/lib/zip/extra_field/old_unix.rb b/lib/zip/extra_field/old_unix.rb
new file mode 100644
index 0000000..3c6a440
--- /dev/null
+++ b/lib/zip/extra_field/old_unix.rb
@@ -0,0 +1,45 @@
+module Zip
+  # Olf Info-ZIP Extra for UNIX uid/gid and file timestampes
+  class ExtraField::OldUnix < ExtraField::Generic
+    HEADER_ID = "UX"
+    register_map
+
+    def initialize(binstr = nil)
+      @uid = 0
+      @gid = 0
+      @atime = nil
+      @mtime = nil
+      binstr and merge(binstr)
+    end
+
+    attr_accessor :uid, :gid, :atime, :mtime
+
+    def merge(binstr)
+      return if binstr.empty?
+      size, content = initial_parse(binstr)
+      # size: 0 for central directory. 4 for local header
+      return if (!size || size == 0)
+      atime, mtime, uid, gid = content.unpack("VVvv")
+      @uid ||= uid
+      @gid ||= gid
+      @atime ||= atime
+      @mtime ||= mtime
+    end
+
+    def ==(other)
+      @uid == other.uid &&
+        @gid == other.gid &&
+          @atime == other.atime &&
+            @mtime == other.mtime
+    end
+
+    def pack_for_local
+      [@atime, @mtime, @uid, @gid].pack("VVvv")
+    end
+
+    def pack_for_c_dir
+      [@atime, @mtime].pack("VV")
+    end
+  end
+
+end
\ No newline at end of file
diff --git a/lib/zip/file.rb b/lib/zip/file.rb
index 33cf931..87a69a0 100755
--- a/lib/zip/file.rb
+++ b/lib/zip/file.rb
@@ -70,7 +70,7 @@ module Zip
       @comment = ''
       @create  = create
       case
-      when ::File.exists?(file_name) && !buffer
+      when !buffer && ::File.exist?(file_name)
         @create = nil
         @exist_file_perms = ::File.stat(file_name).mode
         ::File.open(name, 'rb') do |f|
@@ -79,7 +79,7 @@ module Zip
       when create
         @entry_set = EntrySet.new
       else
-        raise ZipError, "File #{file_name} not found"
+        raise Error, "File #{file_name} not found"
       end
       @stored_entries      = @entry_set.dup
       @stored_comment      = @comment
@@ -94,40 +94,38 @@ module Zip
       # ruby's builtin File.open method.
       def open(file_name, create = nil)
         zf = ::Zip::File.new(file_name, create)
-        if block_given?
-          begin
-            yield zf
-          ensure
-            zf.close
-          end
-        else
-          zf
+        return zf unless block_given?
+        begin
+          yield zf
+        ensure
+          zf.close
         end
       end
 
       # Same as #open. But outputs data to a buffer instead of a file
       def add_buffer
-        zf = ::Zip::File.new('', true, true)
+        io = ::StringIO.new('')
+        zf = ::Zip::File.new(io, true, true)
         yield zf
-        zf.write_buffer
+        zf.write_buffer(io)
       end
 
       # Like #open, but reads zip archive contents from a String or open IO
       # stream, and outputs data to a buffer.
-      # (This can be used to extract data from a 
+      # (This can be used to extract data from a
       # downloaded zip archive without first saving it to disk.)
       def open_buffer(io, options = {})
-        unless io.is_a?(IO) || io.is_a?(String)
-          raise "Zip::File.open_buffer expects an argument of class String or IO. Found: #{io.class}"
+        unless io.is_a?(IO) || io.is_a?(String) || io.is_a?(Tempfile)
+          raise "Zip::File.open_buffer expects an argument of class String, IO, or Tempfile. Found: #{io.class}"
         end
-        zf = ::Zip::File.new('', true, true, options)
         if io.is_a?(::String)
           require 'stringio'
           io = ::StringIO.new(io)
         end
+        zf = ::Zip::File.new(io, true, true, options)
         zf.read_from_stream(io)
         yield zf
-        zf.write_buffer
+        zf.write_buffer(io)
       end
 
       # Iterates over the contents of the ZipFile. This is more efficient
@@ -196,7 +194,7 @@ module Zip
 
       # Splits an archive into parts with segment size
       def split(zip_file_name, segment_size = MAX_SEGMENT_SIZE, delete_zip_file = true, partial_zip_file_name = nil)
-        raise ZipError, "File #{zip_file_name} not found" unless ::File.exists?(zip_file_name)
+        raise Error, "File #{zip_file_name} not found" unless ::File.exist?(zip_file_name)
         raise Errno::ENOENT, zip_file_name unless ::File.readable?(zip_file_name)
         zip_file_size = ::File.size(zip_file_name)
         segment_size  = get_segment_size_for_split(segment_size)
@@ -227,24 +225,24 @@ module Zip
 
     # Returns an output stream to the specified entry. If entry is not an instance
     # of Zip::Entry, a new Zip::Entry will be initialized using the arguments
-    # specified. If a block is passed the stream object is passed to the block and 
-    # the stream is automatically closed afterwards just as with ruby's builtin 
+    # specified. If a block is passed the stream object is passed to the block and
+    # the stream is automatically closed afterwards just as with ruby's builtin
     # File.open method.
-    def get_output_stream(entry, permissionInt = nil, comment = nil, extra = nil, compressed_size = nil, crc = nil, compression_method = nil, size = nil, time = nil,  &aProc)
-      newEntry =
+    def get_output_stream(entry, permission_int = nil, comment = nil, extra = nil, compressed_size = nil, crc = nil, compression_method = nil, size = nil, time = nil,  &aProc)
+      new_entry =
         if entry.kind_of?(Entry)
           entry
         else
           Entry.new(@name, entry.to_s, comment, extra, compressed_size, crc, compression_method, size, time)
         end
-      if newEntry.directory?
+      if new_entry.directory?
         raise ArgumentError,
-              "cannot open stream to directory entry - '#{newEntry}'"
+              "cannot open stream to directory entry - '#{new_entry}'"
       end
-      newEntry.unix_perms = permissionInt
-      zipStreamableEntry  = StreamableStream.new(newEntry)
-      @entry_set << zipStreamableEntry
-      zipStreamableEntry.get_output_stream(&aProc)
+      new_entry.unix_perms = permission_int
+      zip_streamable_entry = StreamableStream.new(new_entry)
+      @entry_set << zip_streamable_entry
+      zip_streamable_entry.get_output_stream(&aProc)
     end
 
     # Returns the name of the zip archive
@@ -258,12 +256,13 @@ module Zip
     end
 
     # Convenience method for adding the contents of a file to the archive
-    def add(entry, srcPath, &continue_on_exists_proc)
-      continue_on_exists_proc ||= proc { Zip.continue_on_exists_proc }
+    def add(entry, src_path, &continue_on_exists_proc)
+      continue_on_exists_proc ||= proc { ::Zip.continue_on_exists_proc }
       check_entry_exists(entry, continue_on_exists_proc, "add")
-      newEntry = entry.kind_of?(Entry) ? entry : Entry.new(@name, entry.to_s)
-      newEntry.gather_fileinfo_from_srcpath(srcPath)
-      @entry_set << newEntry
+      new_entry = entry.kind_of?(::Zip::Entry) ? entry : ::Zip::Entry.new(@name, entry.to_s)
+      new_entry.gather_fileinfo_from_srcpath(src_path)
+      new_entry.dirty = true
+      @entry_set << new_entry
     end
 
     # Removes the specified entry.
@@ -290,7 +289,7 @@ module Zip
 
     # Extracts entry to file dest_path.
     def extract(entry, dest_path, &block)
-      block       ||= proc { ::Zip.on_exists_proc }
+      block ||= proc { ::Zip.on_exists_proc }
       found_entry = get_entry(entry)
       found_entry.extract(dest_path, &block)
     end
@@ -298,9 +297,9 @@ module Zip
     # Commits changes that has been made since the previous commit to
     # the zip archive.
     def commit
-      return if !commit_required?
-      on_success_replace do |tmpFile|
-        ::Zip::OutputStream.open(tmpFile) do |zos|
+      return unless commit_required?
+      on_success_replace do |tmp_file|
+        ::Zip::OutputStream.open(tmp_file) do |zos|
           @entry_set.each do |e|
             e.write_to_zip_output_stream(zos)
             e.dirty = false
@@ -313,8 +312,8 @@ module Zip
     end
 
     # Write buffer write changes to buffer and return
-    def write_buffer
-      OutputStream.write_buffer do |zos|
+    def write_buffer(io = ::StringIO.new(''))
+      ::Zip::OutputStream.write_buffer(io) do |zos|
         @entry_set.each { |e| e.write_to_zip_output_stream(zos) }
         zos.comment = comment
       end
@@ -331,7 +330,7 @@ module Zip
       @entry_set.each do |e|
         return true if e.dirty
       end
-      @comment != @stored_comment || @entry_set != @stored_entries || @create == File::CREATE
+      @comment != @stored_comment || @entry_set != @stored_entries || @create == ::Zip::File::CREATE
     end
 
     # Searches for entry with the specified name. Returns nil if
@@ -388,7 +387,7 @@ module Zip
         if continue_on_exists_proc.call
           remove get_entry(entryName)
         else
-          raise ZipEntryExistsError,
+          raise ::Zip::EntryExistsError,
                 procedureName + " failed. Entry #{entryName} already exists"
         end
       end
@@ -401,7 +400,7 @@ module Zip
     end
 
     def on_success_replace
-      tmpfile     = get_tempfile
+      tmpfile      = get_tempfile
       tmp_filename = tmpfile.path
       tmpfile.close
       if yield tmp_filename
diff --git a/lib/zip/inflater.rb b/lib/zip/inflater.rb
index 615a0c2..c24361c 100755
--- a/lib/zip/inflater.rb
+++ b/lib/zip/inflater.rb
@@ -4,26 +4,42 @@ module Zip
       super
       @zlib_inflater           = ::Zlib::Inflate.new(-Zlib::MAX_WBITS)
       @output_buffer           = ''
+      @output_buffer_pos       = 0
       @has_returned_empty_string = false
     end
 
     def sysread(number_of_bytes = nil, buf = '')
+      buf ||= ''
+      buf.clear
       readEverything = number_of_bytes.nil?
-      while readEverything || @output_buffer.bytesize < number_of_bytes
+      if readEverything
+        buf << @output_buffer[@output_buffer_pos... at output_buffer.bytesize]
+
+        move_output_buffer_pos(buf.bytesize)
+      else
+        buf << @output_buffer[@output_buffer_pos, number_of_bytes]
+
+        move_output_buffer_pos(buf.bytesize)
+
+        if buf.bytesize == number_of_bytes
+          return buf
+        end
+      end
+      while readEverything || buf.bytesize + @output_buffer.bytesize < number_of_bytes
         break if internal_input_finished?
-        @output_buffer << internal_produce_input(buf)
+        @output_buffer << internal_produce_input
       end
-      return value_when_finished if @output_buffer.bytesize == 0 && input_finished?
-      end_index = number_of_bytes.nil? ? @output_buffer.bytesize : number_of_bytes
-      @output_buffer.slice!(0...end_index)
+      return value_when_finished(number_of_bytes, buf) if @output_buffer.bytesize == 0 && input_finished?
+      end_index = (number_of_bytes.nil? ? @output_buffer.bytesize : number_of_bytes) - buf.bytesize
+      data = @output_buffer[0...end_index]
+
+      move_output_buffer_pos(data.bytesize)
+
+      buf << data
     end
 
     def produce_input
-      if (@output_buffer.empty?)
-        internal_produce_input
-      else
-        @output_buffer.slice!(0...(@output_buffer.length))
-      end
+      sysread()
     end
 
     # to be used with produce_input, not read (as read may still have more data cached)
@@ -37,7 +53,16 @@ module Zip
 
     private
 
-    def internal_produce_input(buf = '')
+    def move_output_buffer_pos(inc)
+      @output_buffer_pos += inc
+      if @output_buffer_pos == @output_buffer.bytesize
+        @output_buffer.clear
+        @output_buffer_pos = 0
+      end
+    end
+
+    def internal_produce_input
+      buf = ''
       retried = 0
       begin
         @zlib_inflater.inflate(@input_stream.read(Decompressor::CHUNK_SIZE, buf))
@@ -52,10 +77,14 @@ module Zip
       @zlib_inflater.finished?
     end
 
-    def value_when_finished # mimic behaviour of ruby File object.
-      return if @has_returned_empty_string
-      @has_returned_empty_string = true
-      ''
+    def value_when_finished(number_of_bytes, buf) # mimic behaviour of ruby File object.
+      if number_of_bytes.nil?
+        buf
+      elsif buf.bytesize == 0
+        nil
+      else
+        buf
+      end
     end
   end
 end
diff --git a/lib/zip/input_stream.rb b/lib/zip/input_stream.rb
index 1b4e870..9ca039b 100755
--- a/lib/zip/input_stream.rb
+++ b/lib/zip/input_stream.rb
@@ -1,41 +1,41 @@
 module Zip
   # InputStream is the basic class for reading zip entries in a
   # zip file. It is possible to create a InputStream object directly,
-  # passing the zip file name to the constructor, but more often than not 
+  # passing the zip file name to the constructor, but more often than not
   # the InputStream will be obtained from a File (perhaps using the
-  # ZipFileSystem interface) object for a particular entry in the zip 
+  # ZipFileSystem interface) object for a particular entry in the zip
   # archive.
   #
   # A InputStream inherits IOExtras::AbstractInputStream in order
-  # to provide an IO-like interface for reading from a single zip 
-  # entry. Beyond methods for mimicking an IO-object it contains 
-  # the method get_next_entry for iterating through the entries of 
+  # to provide an IO-like interface for reading from a single zip
+  # entry. Beyond methods for mimicking an IO-object it contains
+  # the method get_next_entry for iterating through the entries of
   # an archive. get_next_entry returns a Entry object that describes
   # the zip entry the InputStream is currently reading from.
   #
-  # Example that creates a zip archive with ZipOutputStream and reads it 
+  # Example that creates a zip archive with ZipOutputStream and reads it
   # back again with a InputStream.
   #
   #   require 'zip'
-  #   
+  #
   #   Zip::OutputStream.open("my.zip") do |io|
-  #   
+  #
   #     io.put_next_entry("first_entry.txt")
   #     io.write "Hello world!"
-  #   
+  #
   #     io.put_next_entry("adir/first_entry.txt")
   #     io.write "Hello again!"
   #   end
   #
-  #   
+  #
   #   Zip::InputStream.open("my.zip") do |io|
-  #   
+  #
   #     while (entry = io.get_next_entry)
   #       puts "Contents of #{entry.name}: '#{io.read}'"
   #     end
   #   end
   #
-  # java.util.zip.ZipInputStream is the original inspiration for this 
+  # java.util.zip.ZipInputStream is the original inspiration for this
   # class.
 
   class InputStream
@@ -60,7 +60,7 @@ module Zip
 
     # Returns a Entry object. It is necessary to call this
     # method on a newly created InputStream before reading from
-    # the first entry in the archive. Returns nil when there are 
+    # the first entry in the archive. Returns nil when there are
     # no more entries.
     def get_next_entry
       @archive_io.seek(@current_entry.next_header_offset, IO::SEEK_SET) if @current_entry
@@ -112,7 +112,9 @@ module Zip
     def get_io(io_or_file, offset = 0)
       case io_or_file
       when IO, StringIO
-        io_or_file
+        io = io_or_file.dup
+        io.seek(offset, ::IO::SEEK_SET)
+        io
       else
         file = ::File.open(io_or_file, 'rb')
         file.seek(offset, ::IO::SEEK_SET)
@@ -136,7 +138,7 @@ module Zip
       when @current_entry.compression_method == ::Zip::Entry::DEFLATED
         ::Zip::Inflater.new(@archive_io)
       else
-        raise ZipCompressionMethodError,
+        raise ::Zip::CompressionMethodError,
               "Unsupported compression method #{@current_entry.compression_method}"
       end
     end
diff --git a/lib/zip/output_stream.rb b/lib/zip/output_stream.rb
index 0fb830e..c01f592 100755
--- a/lib/zip/output_stream.rb
+++ b/lib/zip/output_stream.rb
@@ -24,14 +24,17 @@ module Zip
 
     # Opens the indicated zip file. If a file with that name already
     # exists it will be overwritten.
-    def initialize(fileName, stream=false)
+    def initialize(file_name, stream=false)
       super()
-      @fileName = fileName
-      if stream
-        @output_stream = ::StringIO.new
-      else
-        @output_stream = ::File.new(@fileName, "wb")
-      end
+      @file_name = file_name
+      @output_stream = if stream
+                         iostream = @file_name.dup
+                         iostream.reopen
+                         iostream.rewind
+                         iostream
+                       else
+                         ::File.new(@file_name, "wb")
+                       end
       @entry_set = ::Zip::EntrySet.new
       @compressor = ::Zip::NullCompressor.instance
       @closed = false
@@ -43,19 +46,19 @@ module Zip
     # stream is passed to the block and closed when the block
     # returns.
     class << self
-      def open(fileName)
-        return new(fileName) unless block_given?
-        zos = new(fileName)
+      def open(file_name)
+        return new(file_name) unless block_given?
+        zos = new(file_name)
         yield zos
       ensure
         zos.close if zos
       end
 
-	    # Same as #open but writes to a filestream instead
-      def write_buffer
-        zos = new('', true)
+      # Same as #open but writes to a filestream instead
+      def write_buffer(io)
+        zos = new(io, true)
         yield zos
-        return zos.close_buffer
+        zos.close_buffer
       end
     end
 
@@ -79,35 +82,36 @@ module Zip
       @output_stream
     end
 
-	  # Closes the current entry and opens a new for writing.
+    # Closes the current entry and opens a new for writing.
     # +entry+ can be a ZipEntry object or a string.
-    def put_next_entry(entryname, comment = nil, extra = nil, compression_method = Entry::DEFLATED,  level = Zlib::DEFAULT_COMPRESSION)
-      raise ZipError, "zip stream is closed" if @closed
-      if entryname.kind_of?(Entry)
-        new_entry = entryname
+    def put_next_entry(entry_name, comment = nil, extra = nil, compression_method = Entry::DEFLATED, level = Zip.default_compression)
+      raise Error, "zip stream is closed" if @closed
+      if entry_name.kind_of?(Entry)
+        new_entry = entry_name
       else
-        new_entry = Entry.new(@fileName, entryname.to_s)
+        new_entry = Entry.new(@file_name, entry_name.to_s)
       end
-      new_entry.comment = comment if !comment.nil?
-      if (!extra.nil?)
+      new_entry.comment = comment unless comment.nil?
+      unless extra.nil?
         new_entry.extra = ExtraField === extra ? extra : ExtraField.new(extra.to_s)
       end
-      new_entry.compression_method = compression_method if !compression_method.nil?
+      new_entry.compression_method = compression_method unless compression_method.nil?
       init_next_entry(new_entry, level)
       @current_entry = new_entry
     end
 
     def copy_raw_entry(entry)
       entry = entry.dup
-      raise ZipError, "zip stream is closed" if @closed
-      raise ZipError, "entry is not a ZipEntry" if !entry.kind_of?(Entry)
+      raise Error, "zip stream is closed" if @closed
+      raise Error, "entry is not a ZipEntry" unless entry.is_a?(Entry)
       finalize_current_entry
       @entry_set << entry
-      src_pos = entry.local_entry_offset
+      src_pos = entry.local_header_offset
       entry.write_local_entry(@output_stream)
       @compressor = NullCompressor.instance
       entry.get_raw_input_stream do |is|
         is.seek(src_pos, IO::SEEK_SET)
+        ::Zip::Entry.read_local_entry(is)
         IOExtras.copy_stream_n(@output_stream, is, entry.compressed_size)
       end
       @compressor = NullCompressor.instance
@@ -123,10 +127,10 @@ module Zip
       @current_entry.size = @compressor.size
       @current_entry.crc = @compressor.crc
       @current_entry = nil
-      @compressor = NullCompressor.instance
+      @compressor = ::Zip::NullCompressor.instance
     end
 
-    def init_next_entry(entry, level = Zlib::DEFAULT_COMPRESSION)
+    def init_next_entry(entry, level = Zip.default_compression)
       finalize_current_entry
       @entry_set << entry
       entry.write_local_entry(@output_stream)
@@ -135,10 +139,13 @@ module Zip
 
     def get_compressor(entry, level)
       case entry.compression_method
-        when Entry::DEFLATED then Deflater.new(@output_stream, level)
-        when Entry::STORED   then PassThruCompressor.new(@output_stream)
-      else raise ZipCompressionMethodError,
-        "Invalid compression method: '#{entry.compression_method}'"
+      when Entry::DEFLATED then
+        ::Zip::Deflater.new(@output_stream, level)
+      when Entry::STORED then
+        ::Zip::PassThruCompressor.new(@output_stream)
+      else
+        raise ::Zip::CompressionMethodError,
+              "Invalid compression method: '#{entry.compression_method}'"
       end
     end
 
@@ -163,10 +170,13 @@ module Zip
     end
 
     public
+
     # Modeled after IO.<<
     def << (data)
       @compressor << data
+      self
     end
+
   end
 end
 
diff --git a/lib/zip/streamable_stream.rb b/lib/zip/streamable_stream.rb
index 7f2bbe9..7b1da0e 100755
--- a/lib/zip/streamable_stream.rb
+++ b/lib/zip/streamable_stream.rb
@@ -2,39 +2,44 @@ module Zip
   class StreamableStream < DelegateClass(Entry) #nodoc:all
     def initialize(entry)
       super(entry)
-      @tempFile = Tempfile.new(::File.basename(name), ::File.dirname(zipfile))
-      @tempFile.binmode
+      dirname = if zipfile.is_a?(::String)
+                  ::File.dirname(zipfile)
+                else
+                  '.'
+                end
+      @temp_file = Tempfile.new(::File.basename(name), dirname)
+      @temp_file.binmode
     end
 
     def get_output_stream
       if block_given?
         begin
-          yield(@tempFile)
+          yield(@temp_file)
         ensure
-          @tempFile.close
+          @temp_file.close
         end
       else
-        @tempFile
+        @temp_file
       end
     end
 
     def get_input_stream
-      if ! @tempFile.closed?
+      if !@temp_file.closed?
         raise StandardError, "cannot open entry for reading while its open for writing - #{name}"
       end
-      @tempFile.open # reopens tempfile from top
-      @tempFile.binmode
+      @temp_file.open # reopens tempfile from top
+      @temp_file.binmode
       if block_given?
         begin
-          yield(@tempFile)
+          yield(@temp_file)
         ensure
-          @tempFile.close
+          @temp_file.close
         end
       else
-        @tempFile
+        @temp_file
       end
     end
-    
+
     def write_to_zip_output_stream(aZipOutputStream)
       aZipOutputStream.put_next_entry(self)
       get_input_stream { |is| ::Zip::IOExtras.copy_stream(aZipOutputStream, is) }
diff --git a/lib/zip/version.rb b/lib/zip/version.rb
index 0b5a7e7..57455c3 100644
--- a/lib/zip/version.rb
+++ b/lib/zip/version.rb
@@ -1,3 +1,3 @@
 module Zip
-  VERSION = '1.1.0'
+  VERSION = '1.1.2'
 end
diff --git a/test/.cvsignore b/test/.cvsignore
deleted file mode 100644
index 0bd75a2..0000000
--- a/test/.cvsignore
+++ /dev/null
@@ -1,11 +0,0 @@
-4entry_copy.zip
-cdirtest.bin
-centralEntryHeader.bin
-deflatertest.bin
-dummy.txt
-emptyOutDir
-localEntryHeader.bin
-okToDeleteMoved.txt
-output.zip
-test_putOnClosedStream.zip
-zipWithDirs_copy.zip
diff --git a/test/basic_zip_file_test.rb b/test/basic_zip_file_test.rb
new file mode 100644
index 0000000..527f5b8
--- /dev/null
+++ b/test/basic_zip_file_test.rb
@@ -0,0 +1,64 @@
+require 'test_helper'
+
+class BasicZipFileTest < MiniTest::Unit::TestCase
+  include AssertEntry
+
+  def setup
+    @zip_file = ::Zip::File.new(TestZipFile::TEST_ZIP2.zip_name)
+    @testEntryNameIndex=0
+  end
+
+  def test_entries
+    assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort,
+                 @zip_file.entries.entries.sort.map { |e| e.name })
+  end
+
+  def test_each
+    count = 0
+    visited = {}
+    @zip_file.each {
+        |entry|
+      assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
+      assert(!visited.include?(entry.name))
+      visited[entry.name] = nil
+      count = count.succ
+    }
+    assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
+  end
+
+  def test_foreach
+    count = 0
+    visited = {}
+    ::Zip::File.foreach(TestZipFile::TEST_ZIP2.zip_name) {
+        |entry|
+      assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
+      assert(!visited.include?(entry.name))
+      visited[entry.name] = nil
+      count = count.succ
+    }
+    assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
+  end
+
+  def test_get_input_stream
+    count = 0
+    visited = {}
+    @zip_file.each do |entry|
+      assert_entry(entry.name, @zip_file.get_input_stream(entry), entry.name)
+      assert(!visited.include?(entry.name))
+      visited[entry.name] = nil
+      count = count.succ
+    end
+    assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
+  end
+
+  def test_get_input_streamBlock
+    fileAndEntryName = @zip_file.entries.first.name
+    @zip_file.get_input_stream(fileAndEntryName) {
+        |zis|
+      assert_entryContentsForStream(fileAndEntryName,
+                                    zis,
+                                    fileAndEntryName)
+    }
+  end
+
+end
diff --git a/test/central_directory_entry_test.rb b/test/central_directory_entry_test.rb
new file mode 100644
index 0000000..3901d12
--- /dev/null
+++ b/test/central_directory_entry_test.rb
@@ -0,0 +1,73 @@
+require 'test_helper'
+
+class ZipCentralDirectoryEntryTest < MiniTest::Unit::TestCase
+
+  def test_read_from_stream
+    File.open("test/data/testDirectory.bin", "rb") {
+        |file|
+      entry = ::Zip::Entry.read_c_dir_entry(file)
+
+      assert_equal("longAscii.txt", entry.name)
+      assert_equal(::Zip::Entry::DEFLATED, entry.compression_method)
+      assert_equal(106490, entry.size)
+      assert_equal(3784, entry.compressed_size)
+      assert_equal(0xfcd1799c, entry.crc)
+      assert_equal("", entry.comment)
+
+      entry = ::Zip::Entry.read_c_dir_entry(file)
+      assert_equal("empty.txt", entry.name)
+      assert_equal(::Zip::Entry::STORED, entry.compression_method)
+      assert_equal(0, entry.size)
+      assert_equal(0, entry.compressed_size)
+      assert_equal(0x0, entry.crc)
+      assert_equal("", entry.comment)
+
+      entry = ::Zip::Entry.read_c_dir_entry(file)
+      assert_equal("short.txt", entry.name)
+      assert_equal(::Zip::Entry::STORED, entry.compression_method)
+      assert_equal(6, entry.size)
+      assert_equal(6, entry.compressed_size)
+      assert_equal(0xbb76fe69, entry.crc)
+      assert_equal("", entry.comment)
+
+      entry = ::Zip::Entry.read_c_dir_entry(file)
+      assert_equal("longBinary.bin", entry.name)
+      assert_equal(::Zip::Entry::DEFLATED, entry.compression_method)
+      assert_equal(1000024, entry.size)
+      assert_equal(70847, entry.compressed_size)
+      assert_equal(0x10da7d59, entry.crc)
+      assert_equal('', entry.comment)
+
+      entry = ::Zip::Entry.read_c_dir_entry(file)
+      assert_equal(nil, entry)
+# Fields that are not check by this test:
+#          version made by                 2 bytes
+#          version needed to extract       2 bytes
+#          general purpose bit flag        2 bytes
+#          last mod file time              2 bytes
+#          last mod file date              2 bytes
+#          compressed size                 4 bytes
+#          uncompressed size               4 bytes
+#          disk number start               2 bytes
+#          internal file attributes        2 bytes
+#          external file attributes        4 bytes
+#          relative offset of local header 4 bytes
+
+#          file name (variable size)
+#          extra field (variable size)
+#          file comment (variable size)
+
+    }
+  end
+
+  def test_ReadEntryFromTruncatedZipFile
+    fragment=""
+    File.open("test/data/testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
+    fragment.extend(IOizeString)
+    entry = ::Zip::Entry.new
+    entry.read_c_dir_entry(fragment)
+    fail "ZipError expected"
+  rescue ::Zip::Error
+  end
+
+end
diff --git a/test/central_directory_test.rb b/test/central_directory_test.rb
new file mode 100644
index 0000000..d16c9e8
--- /dev/null
+++ b/test/central_directory_test.rb
@@ -0,0 +1,100 @@
+require 'test_helper'
+
+class ZipCentralDirectoryTest < MiniTest::Unit::TestCase
+
+  def test_read_from_stream
+    ::File.open(TestZipFile::TEST_ZIP2.zip_name, "rb") {
+        |zipFile|
+      cdir = ::Zip::CentralDirectory.read_from_stream(zipFile)
+
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size)
+      assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) {
+          |cdirEntry, testEntryName|
+        cdirEntry.name == testEntryName
+      })
+      assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment)
+    }
+  end
+
+  def test_readFromInvalidStream
+    File.open("test/data/file2.txt", "rb") {
+        |zipFile|
+      cdir = ::Zip::CentralDirectory.new
+      cdir.read_from_stream(zipFile)
+    }
+    fail "ZipError expected!"
+  rescue ::Zip::Error
+  end
+
+  def test_ReadFromTruncatedZipFile
+    fragment=""
+    File.open("test/data/testDirectory.bin", "rb") { |f| fragment = f.read }
+    fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
+    fragment.extend(IOizeString)
+    entry = ::Zip::CentralDirectory.new
+    entry.read_from_stream(fragment)
+    fail "ZipError expected"
+  rescue ::Zip::Error
+  end
+
+  def test_write_to_stream
+    entries = [::Zip::Entry.new("file.zip", "flimse", "myComment", "somethingExtra"),
+               ::Zip::Entry.new("file.zip", "secondEntryName"),
+               ::Zip::Entry.new("file.zip", "lastEntry.txt", "Has a comment too")]
+    cdir = ::Zip::CentralDirectory.new(entries, "my zip comment")
+    File.open("test/data/generated/cdirtest.bin", "wb") { |f| cdir.write_to_stream(f) }
+    cdirReadback = ::Zip::CentralDirectory.new
+    File.open("test/data/generated/cdirtest.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
+
+    assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
+  end
+
+  def test_write64_to_stream
+    ::Zip.write_zip64_support = true
+    entries = [::Zip::Entry.new("file.zip", "file1-little", "comment1", "", 200, 101, ::Zip::Entry::STORED, 200),
+               ::Zip::Entry.new("file.zip", "file2-big", "comment2", "", 18000000000, 102, ::Zip::Entry::DEFLATED, 20000000000),
+               ::Zip::Entry.new("file.zip", "file3-alsobig", "comment3", "", 15000000000, 103, ::Zip::Entry::DEFLATED, 21000000000),
+               ::Zip::Entry.new("file.zip", "file4-little", "comment4", "", 100, 104, ::Zip::Entry::DEFLATED, 121)]
+    [0, 250, 18000000300, 33000000350].each_with_index do |offset, index|
+      entries[index].local_header_offset = offset
+    end
+    cdir = ::Zip::CentralDirectory.new(entries, "zip comment")
+    File.open("test/data/generated/cdir64test.bin", "wb") { |f| cdir.write_to_stream(f) }
+    cdirReadback = ::Zip::CentralDirectory.new
+    File.open("test/data/generated/cdir64test.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
+
+    assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
+    assert_equal(::Zip::VERSION_NEEDED_TO_EXTRACT_ZIP64, cdirReadback.instance_variable_get(:@version_needed_for_extract))
+  end
+
+  def test_equality
+    cdir1 = ::Zip::CentralDirectory.new([::Zip::Entry.new("file.zip", "flimse", nil,
+                                                          "somethingExtra"),
+                                         ::Zip::Entry.new("file.zip", "secondEntryName"),
+                                         ::Zip::Entry.new("file.zip", "lastEntry.txt")],
+                                        "my zip comment")
+    cdir2 = ::Zip::CentralDirectory.new([::Zip::Entry.new("file.zip", "flimse", nil,
+                                                          "somethingExtra"),
+                                         ::Zip::Entry.new("file.zip", "secondEntryName"),
+                                         ::Zip::Entry.new("file.zip", "lastEntry.txt")],
+                                        "my zip comment")
+    cdir3 = ::Zip::CentralDirectory.new([::Zip::Entry.new("file.zip", "flimse", nil,
+                                                          "somethingExtra"),
+                                         ::Zip::Entry.new("file.zip", "secondEntryName"),
+                                         ::Zip::Entry.new("file.zip", "lastEntry.txt")],
+                                        "comment?")
+    cdir4 = ::Zip::CentralDirectory.new([::Zip::Entry.new("file.zip", "flimse", nil,
+                                                          "somethingExtra"),
+                                         ::Zip::Entry.new("file.zip", "lastEntry.txt")],
+                                        "comment?")
+    assert_equal(cdir1, cdir1)
+    assert_equal(cdir1, cdir2)
+
+    assert(cdir1 != cdir3)
+    assert(cdir2 != cdir3)
+    assert(cdir2 != cdir3)
+    assert(cdir3 != cdir4)
+
+    assert(cdir3 != "hello")
+  end
+end
diff --git a/test/data/.cvsignore b/test/data/.cvsignore
deleted file mode 100644
index 86d4c2d..0000000
--- a/test/data/.cvsignore
+++ /dev/null
@@ -1 +0,0 @@
-generated
diff --git a/test/deflater_test.rb b/test/deflater_test.rb
new file mode 100644
index 0000000..292e146
--- /dev/null
+++ b/test/deflater_test.rb
@@ -0,0 +1,62 @@
+require 'test_helper'
+
+class DeflaterTest < MiniTest::Unit::TestCase
+  include CrcTest
+
+  def test_outputOperator
+    txt = load_file("test/data/file2.txt")
+    deflate(txt, "deflatertest.bin")
+    inflatedTxt = inflate("deflatertest.bin")
+    assert_equal(txt, inflatedTxt)
+  end
+
+  def test_default_compression
+    txt = load_file("test/data/file2.txt")
+
+    Zip.default_compression = ::Zlib::BEST_COMPRESSION
+    deflate(txt, "compressiontest_best_compression.bin")
+    Zip.default_compression = ::Zlib::DEFAULT_COMPRESSION
+    deflate(txt, "compressiontest_default_compression.bin")
+    Zip.default_compression = ::Zlib::NO_COMPRESSION
+    deflate(txt, "compressiontest_no_compression.bin")
+
+    best    = File.size("compressiontest_best_compression.bin")
+    default = File.size("compressiontest_default_compression.bin")
+    no      = File.size("compressiontest_no_compression.bin")
+
+    assert(best < default)
+    assert(best < no)
+    assert(default < no)
+  end
+
+
+  private
+  def load_file(fileName)
+    txt = nil
+    File.open(fileName, "rb") { |f| txt = f.read }
+  end
+
+  def deflate(data, fileName)
+    File.open(fileName, "wb") {
+        |file|
+      deflater = ::Zip::Deflater.new(file)
+      deflater << data
+      deflater.finish
+      assert_equal(deflater.size, data.size)
+      file << "trailing data for zlib with -MAX_WBITS"
+    }
+  end
+
+  def inflate(fileName)
+    txt = nil
+    File.open(fileName, "rb") {
+        |file|
+      inflater = ::Zip::Inflater.new(file)
+      txt = inflater.sysread
+    }
+  end
+
+  def test_crc
+    run_crc_test(::Zip::Deflater)
+  end
+end
diff --git a/test/entry_set_test.rb b/test/entry_set_test.rb
new file mode 100644
index 0000000..dbd1713
--- /dev/null
+++ b/test/entry_set_test.rb
@@ -0,0 +1,125 @@
+require 'test_helper'
+
+class ZipEntrySetTest < MiniTest::Unit::TestCase
+  ZIP_ENTRIES = [
+      ::Zip::Entry.new("zipfile.zip", "name1", "comment1"),
+      ::Zip::Entry.new("zipfile.zip", "name3", "comment1"),
+      ::Zip::Entry.new("zipfile.zip", "name2", "comment1"),
+      ::Zip::Entry.new("zipfile.zip", "name4", "comment1"),
+      ::Zip::Entry.new("zipfile.zip", "name5", "comment1"),
+      ::Zip::Entry.new("zipfile.zip", "name6", "comment1")
+  ]
+
+  def setup
+    @zipEntrySet = ::Zip::EntrySet.new(ZIP_ENTRIES)
+  end
+
+  def test_include
+    assert(@zipEntrySet.include?(ZIP_ENTRIES.first))
+    assert(!@zipEntrySet.include?(::Zip::Entry.new("different.zip", "different", "aComment")))
+  end
+
+  def test_size
+    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
+    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.length)
+    @zipEntrySet << ::Zip::Entry.new("a", "b", "c")
+    assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.length)
+  end
+
+  def test_add
+    zes = ::Zip::EntrySet.new
+    entry1 = ::Zip::Entry.new("zf.zip", "name1")
+    entry2 = ::Zip::Entry.new("zf.zip", "name2")
+    zes << entry1
+    assert(zes.include?(entry1))
+    zes.push(entry2)
+    assert(zes.include?(entry2))
+  end
+
+  def test_delete
+    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
+    entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
+    assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
+    assert_equal(ZIP_ENTRIES.first, entry)
+
+    entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
+    assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
+    assert_nil(entry)
+  end
+
+  def test_each
+    # Used each instead each_with_index due the bug in jRuby
+    count = 0
+    @zipEntrySet.each do |entry|
+      assert(ZIP_ENTRIES.include?(entry))
+      count += 1
+    end
+    assert_equal(ZIP_ENTRIES.size, count)
+  end
+
+  def test_entries
+    assert_equal(ZIP_ENTRIES, @zipEntrySet.entries)
+  end
+
+  def test_entries_with_sort
+    ::Zip.sort_entries = true
+    assert_equal(ZIP_ENTRIES.sort, @zipEntrySet.entries)
+    ::Zip.sort_entries = false
+    assert_equal(ZIP_ENTRIES, @zipEntrySet.entries)
+  end
+
+  def test_compound
+    newEntry = ::Zip::Entry.new("zf.zip", "new entry", "new entry's comment")
+    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
+    @zipEntrySet << newEntry
+    assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.size)
+    assert(@zipEntrySet.include?(newEntry))
+
+    @zipEntrySet.delete(newEntry)
+    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
+  end
+
+  def test_dup
+    copy = @zipEntrySet.dup
+    assert_equal(@zipEntrySet, copy)
+
+    # demonstrate that this is a deep copy
+    copy.entries[0].name = "a totally different name"
+    assert(@zipEntrySet != copy)
+  end
+
+  def test_parent
+    entries = [
+        ::Zip::Entry.new("zf.zip", "a/"),
+        ::Zip::Entry.new("zf.zip", "a/b/"),
+        ::Zip::Entry.new("zf.zip", "a/b/c/")
+    ]
+    entrySet = ::Zip::EntrySet.new(entries)
+
+    assert_equal(nil, entrySet.parent(entries[0]))
+    assert_equal(entries[0], entrySet.parent(entries[1]))
+    assert_equal(entries[1], entrySet.parent(entries[2]))
+  end
+
+  def test_glob
+    res = @zipEntrySet.glob('name[2-4]')
+    assert_equal(3, res.size)
+    assert_equal(ZIP_ENTRIES[1, 3].sort, res.sort)
+  end
+
+  def test_glob2
+    entries = [
+        ::Zip::Entry.new("zf.zip", "a/"),
+        ::Zip::Entry.new("zf.zip", "a/b/b1"),
+        ::Zip::Entry.new("zf.zip", "a/b/c/"),
+        ::Zip::Entry.new("zf.zip", "a/b/c/c1")
+    ]
+    entrySet = ::Zip::EntrySet.new(entries)
+
+    assert_equal(entries[0, 1], entrySet.glob("*"))
+#    assert_equal(entries[FIXME], entrySet.glob("**"))
+#    res = entrySet.glob('a*')
+#    assert_equal(entries.size, res.size)
+#    assert_equal(entrySet.map { |e| e.name }, res.map { |e| e.name })
+  end
+end
diff --git a/test/entry_test.rb b/test/entry_test.rb
new file mode 100644
index 0000000..1b0a578
--- /dev/null
+++ b/test/entry_test.rb
@@ -0,0 +1,132 @@
+require 'test_helper'
+
+class ZipEntryTest < MiniTest::Unit::TestCase
+  TEST_ZIPFILE = "someZipFile.zip"
+  TEST_COMMENT = "a comment"
+  TEST_COMPRESSED_SIZE = 1234
+  TEST_CRC = 325324
+  TEST_EXTRA = "Some data here"
+  TEST_COMPRESSIONMETHOD = ::Zip::Entry::DEFLATED
+  TEST_NAME = "entry name"
+  TEST_SIZE = 8432
+  TEST_ISDIRECTORY = false
+  TEST_TIME = Time.now
+
+  def test_constructorAndGetters
+    entry = ::Zip::Entry.new(TEST_ZIPFILE,
+                             TEST_NAME,
+                             TEST_COMMENT,
+                             TEST_EXTRA,
+                             TEST_COMPRESSED_SIZE,
+                             TEST_CRC,
+                             TEST_COMPRESSIONMETHOD,
+                             TEST_SIZE,
+                             TEST_TIME)
+
+    assert_equal(TEST_COMMENT, entry.comment)
+    assert_equal(TEST_COMPRESSED_SIZE, entry.compressed_size)
+    assert_equal(TEST_CRC, entry.crc)
+    assert_instance_of(::Zip::ExtraField, entry.extra)
+    assert_equal(TEST_COMPRESSIONMETHOD, entry.compression_method)
+    assert_equal(TEST_NAME, entry.name)
+    assert_equal(TEST_SIZE, entry.size)
+    assert_equal(TEST_TIME, entry.time)
+  end
+
+  def test_is_directoryAndIsFile
+    assert(::Zip::Entry.new(TEST_ZIPFILE, "hello").file?)
+    assert(!::Zip::Entry.new(TEST_ZIPFILE, "hello").directory?)
+
+    assert(::Zip::Entry.new(TEST_ZIPFILE, "dir/hello").file?)
+    assert(!::Zip::Entry.new(TEST_ZIPFILE, "dir/hello").directory?)
+
+    assert(::Zip::Entry.new(TEST_ZIPFILE, "hello/").directory?)
+    assert(!::Zip::Entry.new(TEST_ZIPFILE, "hello/").file?)
+
+    assert(::Zip::Entry.new(TEST_ZIPFILE, "dir/hello/").directory?)
+    assert(!::Zip::Entry.new(TEST_ZIPFILE, "dir/hello/").file?)
+  end
+
+  def test_equality
+    entry1 = ::Zip::Entry.new("file.zip", "name", "isNotCompared",
+                              "something extra", 123, 1234,
+                              ::Zip::Entry::DEFLATED, 10000)
+    entry2 = ::Zip::Entry.new("file.zip", "name", "isNotComparedXXX",
+                              "something extra", 123, 1234,
+                              ::Zip::Entry::DEFLATED, 10000)
+    entry3 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
+                              "something extra", 123, 1234,
+                              ::Zip::Entry::DEFLATED, 10000)
+    entry4 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
+                              "something extraXX", 123, 1234,
+                              ::Zip::Entry::DEFLATED, 10000)
+    entry5 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
+                              "something extraXX", 12, 1234,
+                              ::Zip::Entry::DEFLATED, 10000)
+    entry6 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
+                              "something extraXX", 12, 123,
+                              ::Zip::Entry::DEFLATED, 10000)
+    entry7 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
+                              "something extraXX", 12, 123,
+                              ::Zip::Entry::STORED, 10000)
+    entry8 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
+                              "something extraXX", 12, 123,
+                              ::Zip::Entry::STORED, 100000)
+
+    assert_equal(entry1, entry1)
+    assert_equal(entry1, entry2)
+
+    assert(entry2 != entry3)
+    assert(entry3 != entry4)
+    assert(entry4 != entry5)
+    assert(entry5 != entry6)
+    assert(entry6 != entry7)
+    assert(entry7 != entry8)
+
+    assert(entry7 != "hello")
+    assert(entry7 != 12)
+  end
+
+  def test_compare
+    assert_equal(0, (::Zip::Entry.new("zf.zip", "a") <=> ::Zip::Entry.new("zf.zip", "a")))
+    assert_equal(1, (::Zip::Entry.new("zf.zip", "b") <=> ::Zip::Entry.new("zf.zip", "a")))
+    assert_equal(-1, (::Zip::Entry.new("zf.zip", "a") <=> ::Zip::Entry.new("zf.zip", "b")))
+
+    entries = [
+        ::Zip::Entry.new("zf.zip", "5"),
+        ::Zip::Entry.new("zf.zip", "1"),
+        ::Zip::Entry.new("zf.zip", "3"),
+        ::Zip::Entry.new("zf.zip", "4"),
+        ::Zip::Entry.new("zf.zip", "0"),
+        ::Zip::Entry.new("zf.zip", "2")
+    ]
+
+    entries.sort!
+    assert_equal("0", entries[0].to_s)
+    assert_equal("1", entries[1].to_s)
+    assert_equal("2", entries[2].to_s)
+    assert_equal("3", entries[3].to_s)
+    assert_equal("4", entries[4].to_s)
+    assert_equal("5", entries[5].to_s)
+  end
+
+  def test_parentAsString
+    entry1 = ::Zip::Entry.new("zf.zip", "aa")
+    entry2 = ::Zip::Entry.new("zf.zip", "aa/")
+    entry3 = ::Zip::Entry.new("zf.zip", "aa/bb")
+    entry4 = ::Zip::Entry.new("zf.zip", "aa/bb/")
+    entry5 = ::Zip::Entry.new("zf.zip", "aa/bb/cc")
+    entry6 = ::Zip::Entry.new("zf.zip", "aa/bb/cc/")
+
+    assert_equal(nil, entry1.parent_as_string)
+    assert_equal(nil, entry2.parent_as_string)
+    assert_equal("aa/", entry3.parent_as_string)
+    assert_equal("aa/", entry4.parent_as_string)
+    assert_equal("aa/bb/", entry5.parent_as_string)
+    assert_equal("aa/bb/", entry6.parent_as_string)
+  end
+
+  def test_entry_name_cannot_start_with_slash
+    assert_raises(::Zip::EntryNameError) { ::Zip::Entry.new("zf.zip", "/hej/der") }
+  end
+end
diff --git a/test/extra_field_test.rb b/test/extra_field_test.rb
new file mode 100644
index 0000000..6e1371e
--- /dev/null
+++ b/test/extra_field_test.rb
@@ -0,0 +1,69 @@
+require 'test_helper'
+
+class ZipExtraFieldTest < MiniTest::Unit::TestCase
+  def test_new
+    extra_pure = ::Zip::ExtraField.new("")
+    extra_withstr = ::Zip::ExtraField.new("foo")
+    assert_instance_of(::Zip::ExtraField, extra_pure)
+    assert_instance_of(::Zip::ExtraField, extra_withstr)
+  end
+
+  def test_unknownfield
+    extra = ::Zip::ExtraField.new("foo")
+    assert_equal(extra["Unknown"], "foo")
+    extra.merge("a")
+    assert_equal(extra["Unknown"], "fooa")
+    extra.merge("barbaz")
+    assert_equal(extra.to_s, "fooabarbaz")
+  end
+
+
+  def test_merge
+    str = "UT\x5\0\x3\250$\r at Ux\0\0"
+    extra1 = ::Zip::ExtraField.new("")
+    extra2 = ::Zip::ExtraField.new(str)
+    assert(!extra1.member?("UniversalTime"))
+    assert(extra2.member?("UniversalTime"))
+    extra1.merge(str)
+    assert_equal(extra1["UniversalTime"].mtime, extra2["UniversalTime"].mtime)
+  end
+
+  def test_length
+    str = "UT\x5\0\x3\250$\r at Ux\0\0Te\0\0testit"
+    extra = ::Zip::ExtraField.new(str)
+    assert_equal(extra.local_size, extra.to_local_bin.size)
+    assert_equal(extra.c_dir_size, extra.to_c_dir_bin.size)
+    extra.merge("foo")
+    assert_equal(extra.local_size, extra.to_local_bin.size)
+    assert_equal(extra.c_dir_size, extra.to_c_dir_bin.size)
+  end
+
+
+  def test_to_s
+    str = "UT\x5\0\x3\250$\r at Ux\0\0Te\0\0testit"
+    extra = ::Zip::ExtraField.new(str)
+    assert_instance_of(String, extra.to_s)
+
+    s = extra.to_s
+    extra.merge("foo")
+    assert_equal(s.length + 3, extra.to_s.length)
+  end
+
+  def test_equality
+    str = "UT\x5\0\x3\250$\r@"
+    extra1 = ::Zip::ExtraField.new(str)
+    extra2 = ::Zip::ExtraField.new(str)
+    extra3 = ::Zip::ExtraField.new(str)
+    assert_equal(extra1, extra2)
+
+    extra2["UniversalTime"].mtime = ::Zip::DOSTime.now
+    assert(extra1 != extra2)
+
+    extra3.create("IUnix")
+    assert(extra1 != extra3)
+
+    extra1.create("IUnix")
+    assert_equal(extra1, extra3)
+  end
+
+end
diff --git a/test/file_extract_directory_test.rb b/test/file_extract_directory_test.rb
new file mode 100644
index 0000000..dce59f0
--- /dev/null
+++ b/test/file_extract_directory_test.rb
@@ -0,0 +1,55 @@
+require 'test_helper'
+
+class ZipFileExtractDirectoryTest < MiniTest::Unit::TestCase
+  include CommonZipFileFixture
+  TEST_OUT_NAME = "emptyOutDir"
+
+  def open_zip(&aProc)
+    assert(aProc != nil)
+    ::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
+  end
+
+  def extract_test_dir(&aProc)
+    open_zip {
+        |zf|
+      zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
+    }
+  end
+
+  def setup
+    super
+
+    Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
+    File.delete(TEST_OUT_NAME) if File.exist? TEST_OUT_NAME
+  end
+
+  def test_extractDirectory
+    extract_test_dir
+    assert(File.directory?(TEST_OUT_NAME))
+  end
+
+  def test_extractDirectoryExistsAsDir
+    Dir.mkdir TEST_OUT_NAME
+    extract_test_dir
+    assert(File.directory?(TEST_OUT_NAME))
+  end
+
+  def test_extractDirectoryExistsAsFile
+    File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
+    assert_raises(::Zip::DestinationFileExistsError) { extract_test_dir }
+  end
+
+  def test_extractDirectoryExistsAsFileOverwrite
+    File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
+    gotCalled = false
+    extract_test_dir {
+        |entry, destPath|
+      gotCalled = true
+      assert_equal(TEST_OUT_NAME, destPath)
+      assert(entry.directory?)
+      true
+    }
+    assert(gotCalled)
+    assert(File.directory?(TEST_OUT_NAME))
+  end
+end
diff --git a/test/file_extract_test.rb b/test/file_extract_test.rb
new file mode 100644
index 0000000..4d1e9a6
--- /dev/null
+++ b/test/file_extract_test.rb
@@ -0,0 +1,90 @@
+require 'test_helper'
+
+class ZipFileExtractTest < MiniTest::Unit::TestCase
+  include CommonZipFileFixture
+  EXTRACTED_FILENAME = "extEntry"
+  ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entry_names.reverse
+
+  def setup
+    super
+    ::File.delete(EXTRACTED_FILENAME) if ::File.exist?(EXTRACTED_FILENAME)
+  end
+
+  def test_extract
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
+
+      assert(File.exist?(EXTRACTED_FILENAME))
+      AssertEntry::assert_contents(EXTRACTED_FILENAME,
+                                   zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
+
+
+      ::File.unlink(EXTRACTED_FILENAME)
+
+      entry = zf.get_entry(ENTRY_TO_EXTRACT)
+      entry.extract(EXTRACTED_FILENAME)
+
+      assert(File.exist?(EXTRACTED_FILENAME))
+      AssertEntry::assert_contents(EXTRACTED_FILENAME,
+                                   entry.get_input_stream() { |is| is.read })
+
+    }
+  end
+
+  def test_extractExists
+    writtenText = "written text"
+    ::File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
+
+    assert_raises(::Zip::DestinationFileExistsError) {
+      ::Zip::File.open(TEST_ZIP.zip_name) { |zf|
+        zf.extract(zf.entries.first, EXTRACTED_FILENAME)
+      }
+    }
+    File.open(EXTRACTED_FILENAME, "r") { |f|
+      assert_equal(writtenText, f.read)
+    }
+  end
+
+  def test_extractExistsOverwrite
+    writtenText = "written text"
+    ::File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
+
+    gotCalledCorrectly = false
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      zf.extract(zf.entries.first, EXTRACTED_FILENAME) {
+          |entry, extractLoc|
+        gotCalledCorrectly = zf.entries.first == entry &&
+            extractLoc == EXTRACTED_FILENAME
+        true
+      }
+    }
+
+    assert(gotCalledCorrectly)
+    ::File.open(EXTRACTED_FILENAME, "r") {
+        |f|
+      assert(writtenText != f.read)
+    }
+  end
+
+  def test_extractNonEntry
+    zf = ::Zip::File.new(TEST_ZIP.zip_name)
+    assert_raises(Errno::ENOENT) { zf.extract("nonExistingEntry", "nonExistingEntry") }
+  ensure
+    zf.close if zf
+  end
+
+  def test_extractNonEntry2
+    outFile = "outfile"
+    assert_raises(Errno::ENOENT) {
+      zf = ::Zip::File.new(TEST_ZIP.zip_name)
+      nonEntry = "hotdog-diddelidoo"
+      assert(!zf.entries.include?(nonEntry))
+      zf.extract(nonEntry, outFile)
+      zf.close
+    }
+    assert(!File.exist?(outFile))
+  end
+
+end
diff --git a/test/file_split_test.rb b/test/file_split_test.rb
new file mode 100644
index 0000000..edde665
--- /dev/null
+++ b/test/file_split_test.rb
@@ -0,0 +1,60 @@
+require 'test_helper'
+
+class ZipFileSplitTest < MiniTest::Unit::TestCase
+  TEST_ZIP = TestZipFile::TEST_ZIP2.clone
+  TEST_ZIP.zip_name = "large_zip_file.zip"
+  EXTRACTED_FILENAME = "test/data/generated/extEntry"
+  UNSPLITTED_FILENAME = "test/data/generated/unsplitted.zip"
+  ENTRY_TO_EXTRACT = TEST_ZIP.entry_names.first
+
+  def setup
+    FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
+  end
+
+  def teardown
+    File.delete(TEST_ZIP.zip_name)
+    File.delete(UNSPLITTED_FILENAME) if File.exist?(UNSPLITTED_FILENAME)
+
+    Dir["#{TEST_ZIP.zip_name}.*"].each do |zip_file_name|
+      File.delete(zip_file_name) if File.exist?(zip_file_name)
+    end
+  end
+
+  def test_split_method_respond
+    assert_respond_to ::Zip::File, :split, "Does not have split class method"
+  end
+
+  def test_split
+    result = ::Zip::File.split(TEST_ZIP.zip_name, 65536, false)
+
+    unless result.nil?
+      Dir["#{TEST_ZIP.zip_name}.*"].sort.each_with_index do |zip_file_name, index|
+        File.open(zip_file_name, 'rb') do |zip_file|
+          zip_file.read([::Zip::File::SPLIT_SIGNATURE].pack('V').size) if index == 0
+          File.open(UNSPLITTED_FILENAME, 'ab') do |file|
+            file << zip_file.read
+          end
+        end
+      end
+
+      ::Zip::File.open(UNSPLITTED_FILENAME) do |zf|
+        zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
+
+        assert(File.exist?(EXTRACTED_FILENAME))
+        AssertEntry::assert_contents(EXTRACTED_FILENAME,
+                                     zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
+
+
+        File.unlink(EXTRACTED_FILENAME)
+
+        entry = zf.get_entry(ENTRY_TO_EXTRACT)
+        entry.extract(EXTRACTED_FILENAME)
+
+        assert(File.exist?(EXTRACTED_FILENAME))
+        AssertEntry::assert_contents(EXTRACTED_FILENAME,
+                                     entry.get_input_stream() { |is| is.read })
+
+      end
+    end
+  end
+end
diff --git a/test/file_test.rb b/test/file_test.rb
new file mode 100644
index 0000000..9b36bd4
--- /dev/null
+++ b/test/file_test.rb
@@ -0,0 +1,543 @@
+require 'test_helper'
+
+
+class ZipFileTest < MiniTest::Unit::TestCase
+  include CommonZipFileFixture
+
+  def teardown
+    ::Zip.write_zip64_support = false
+  end
+
+  def test_createFromScratchToBuffer
+    comment = "a short comment"
+
+    buffer = ::Zip::File.add_buffer do |zf|
+      zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
+      zf.mkdir("dir1")
+      zf.comment = comment
+    end
+
+    ::File.open(EMPTY_FILENAME, 'wb') { |file| file.write buffer.string }
+    # Not sure if the following line was just accidentally left in, but
+    # it's not related to the tests and breaks on windows
+    `cp #{EMPTY_FILENAME} ~/test.zip` unless Zip::RUNNING_ON_WINDOWS
+
+    zfRead = ::Zip::File.new(EMPTY_FILENAME)
+    assert_equal(comment, zfRead.comment)
+    assert_equal(2, zfRead.entries.length)
+  end
+
+  def test_createFromScratch
+    comment = "a short comment"
+
+    zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE)
+    zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
+    zf.mkdir("dir1")
+    zf.comment = comment
+    zf.close
+
+    zfRead = ::Zip::File.new(EMPTY_FILENAME)
+    assert_equal(comment, zfRead.comment)
+    assert_equal(2, zfRead.entries.length)
+  end
+
+  def test_get_output_stream
+    entryCount = nil
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      entryCount = zf.size
+      zf.get_output_stream('newEntry.txt') {
+          |os|
+        os.write "Putting stuff in newEntry.txt"
+      }
+      assert_equal(entryCount+1, zf.size)
+      assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
+
+      zf.get_output_stream(zf.get_entry('test/data/generated/empty.txt')) {
+          |os|
+        os.write "Putting stuff in data/generated/empty.txt"
+      }
+      assert_equal(entryCount+1, zf.size)
+      assert_equal("Putting stuff in data/generated/empty.txt", zf.read("test/data/generated/empty.txt"))
+
+      custom_entry_args = [ZipEntryTest::TEST_COMMENT, ZipEntryTest::TEST_EXTRA, ZipEntryTest::TEST_COMPRESSED_SIZE, ZipEntryTest::TEST_CRC, ::Zip::Entry::STORED, ZipEntryTest::TEST_SIZE, ZipEntryTest::TEST_TIME]
+      zf.get_output_stream('entry_with_custom_args.txt', nil, *custom_entry_args) {
+          |os|
+        os.write "Some data"
+      }
+      assert_equal(entryCount+2, zf.size)
+      entry = zf.get_entry('entry_with_custom_args.txt')
+      assert_equal(custom_entry_args[0], entry.comment)
+      assert_equal(custom_entry_args[2], entry.compressed_size)
+      assert_equal(custom_entry_args[3], entry.crc)
+      assert_equal(custom_entry_args[4], entry.compression_method)
+      assert_equal(custom_entry_args[5], entry.size)
+      assert_equal(custom_entry_args[6], entry.time)
+
+      zf.get_output_stream('entry.bin') {
+          |os|
+        os.write(::File.open('test/data/generated/5entry.zip', 'rb').read)
+      }
+    }
+
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      assert_equal(entryCount+3, zf.size)
+      assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
+      assert_equal("Putting stuff in data/generated/empty.txt", zf.read("test/data/generated/empty.txt"))
+      assert_equal(File.open('test/data/generated/5entry.zip', 'rb').read, zf.read("entry.bin"))
+    }
+  end
+
+  def test_add
+    srcFile = "test/data/file2.txt"
+    entryName = "newEntryName.rb"
+    assert(::File.exist?(srcFile))
+    zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE)
+    zf.add(entryName, srcFile)
+    zf.close
+
+    zfRead = ::Zip::File.new(EMPTY_FILENAME)
+    assert_equal("", zfRead.comment)
+    assert_equal(1, zfRead.entries.length)
+    assert_equal(entryName, zfRead.entries.first.name)
+    AssertEntry.assert_contents(srcFile,
+                                zfRead.get_input_stream(entryName) { |zis| zis.read })
+  end
+
+  def test_recover_permissions_after_add_files_to_archive
+    srcZip = TEST_ZIP.zip_name
+    ::File.chmod(0664, srcZip)
+    srcFile = "test/data/file2.txt"
+    entryName = "newEntryName.rb"
+    assert_equal(::File.stat(srcZip).mode, 0100664)
+    assert(::File.exist?(srcZip))
+    zf = ::Zip::File.new(srcZip, ::Zip::File::CREATE)
+    zf.add(entryName, srcFile)
+    zf.close
+    assert_equal(::File.stat(srcZip).mode, 0100664)
+  end
+
+  def test_addExistingEntryName
+    assert_raises(::Zip::EntryExistsError) {
+      ::Zip::File.open(TEST_ZIP.zip_name) {
+          |zf|
+        zf.add(zf.entries.first.name, "test/data/file2.txt")
+      }
+    }
+  end
+
+  def test_addExistingEntryNameReplace
+    gotCalled = false
+    replacedEntry = nil
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      replacedEntry = zf.entries.first.name
+      zf.add(replacedEntry, "test/data/file2.txt") { gotCalled = true; true }
+    }
+    assert(gotCalled)
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      assert_contains(zf, replacedEntry, "test/data/file2.txt")
+    }
+  end
+
+  def test_addDirectory
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
+    }
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
+      assert(dirEntry.directory?)
+    }
+  end
+
+  def test_remove
+    entryToRemove, *remainingEntries = TEST_ZIP.entry_names
+
+    FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
+
+    zf = ::Zip::File.new(TEST_ZIP.zip_name)
+    assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
+    zf.remove(entryToRemove)
+    assert(!zf.entries.map { |e| e.name }.include?(entryToRemove))
+    assert_equal(zf.entries.map { |x| x.name }.sort, remainingEntries.sort)
+    zf.close
+
+    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
+    assert(!zfRead.entries.map { |e| e.name }.include?(entryToRemove))
+    assert_equal(zfRead.entries.map { |x| x.name }.sort, remainingEntries.sort)
+    zfRead.close
+  end
+
+  def test_rename
+    entryToRename, * = TEST_ZIP.entry_names
+
+    zf = ::Zip::File.new(TEST_ZIP.zip_name)
+    assert(zf.entries.map { |e| e.name }.include?(entryToRename))
+
+    contents = zf.read(entryToRename)
+    newName = "changed entry name"
+    assert(!zf.entries.map { |e| e.name }.include?(newName))
+
+    zf.rename(entryToRename, newName)
+    assert(zf.entries.map { |e| e.name }.include?(newName))
+
+    assert_equal(contents, zf.read(newName))
+
+    zf.close
+
+    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
+    assert(zfRead.entries.map { |e| e.name }.include?(newName))
+    assert_equal(contents, zfRead.read(newName))
+    zfRead.close
+  end
+
+  def test_rename_with_each
+    zf_name = 'test_rename_zip.zip'
+    if ::File.exist?(zf_name)
+      ::File.unlink(zf_name)
+    end
+    arr = []
+    arr_renamed = []
+    ::Zip::File.open(zf_name, ::Zip::File::CREATE) do |zf|
+      zf.mkdir('test')
+      arr << 'test/'
+      arr_renamed << 'Ztest/'
+      %w(a b c d).each do |f|
+        zf.get_output_stream("test/#{f}") { |file| file.puts 'aaaa' }
+        arr << "test/#{f}"
+        arr_renamed << "Ztest/#{f}"
+      end
+    end
+    zf = ::Zip::File.open(zf_name)
+    assert_equal(zf.entries.map(&:name), arr)
+    zf.close
+    Zip::File.open(zf_name, "wb") do |z|
+      z.each do |f|
+        z.rename(f, "Z#{f.name}")
+      end
+    end
+    zf = ::Zip::File.open(zf_name)
+    assert_equal(zf.entries.map(&:name), arr_renamed)
+    zf.close
+    if ::File.exist?(zf_name)
+      ::File.unlink(zf_name)
+    end
+  end
+
+  def test_renameToExistingEntry
+    oldEntries = nil
+    ::Zip::File.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
+
+    assert_raises(::Zip::EntryExistsError) do
+      ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+        zf.rename(zf.entries[0], zf.entries[1].name)
+      end
+    end
+
+    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+      assert_equal(oldEntries.sort.map { |e| e.name }, zf.entries.sort.map { |e| e.name })
+    end
+  end
+
+  def test_renameToExistingEntryOverwrite
+    oldEntries = nil
+    ::Zip::File.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
+
+    gotCalled = false
+    renamedEntryName = nil
+    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+      renamedEntryName = zf.entries[0].name
+      zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
+    end
+
+    assert(gotCalled)
+    oldEntries.delete_if { |e| e.name == renamedEntryName }
+    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+      assert_equal(oldEntries.sort.map { |e| e.name },
+                   zf.entries.sort.map { |e| e.name })
+    end
+  end
+
+  def test_renameNonEntry
+    nonEntry = "bogusEntry"
+    target_entry = "target_entryName"
+    zf = ::Zip::File.new(TEST_ZIP.zip_name)
+    assert(!zf.entries.include?(nonEntry))
+    assert_raises(Errno::ENOENT) {
+      zf.rename(nonEntry, target_entry)
+    }
+    zf.commit
+    assert(!zf.entries.include?(target_entry))
+  ensure
+    zf.close
+  end
+
+  def test_renameEntryToExistingEntry
+    entry1, entry2, * = TEST_ZIP.entry_names
+    zf = ::Zip::File.new(TEST_ZIP.zip_name)
+    assert_raises(::Zip::EntryExistsError) {
+      zf.rename(entry1, entry2)
+    }
+  ensure
+    zf.close
+  end
+
+  def test_replace
+    entryToReplace = TEST_ZIP.entry_names[2]
+    newEntrySrcFilename = "test/data/file2.txt"
+    zf = ::Zip::File.new(TEST_ZIP.zip_name)
+    zf.replace(entryToReplace, newEntrySrcFilename)
+
+    zf.close
+    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
+    AssertEntry::assert_contents(newEntrySrcFilename,
+                                 zfRead.get_input_stream(entryToReplace) { |is| is.read })
+    AssertEntry::assert_contents(TEST_ZIP.entry_names[0],
+                                 zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read })
+    AssertEntry::assert_contents(TEST_ZIP.entry_names[1],
+                                 zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read })
+    AssertEntry::assert_contents(TEST_ZIP.entry_names[3],
+                                 zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read })
+    zfRead.close
+  end
+
+  def test_replaceNonEntry
+    entryToReplace = "nonExistingEntryname"
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      assert_raises(Errno::ENOENT) {
+        zf.replace(entryToReplace, "test/data/file2.txt")
+      }
+    }
+  end
+
+  def test_commit
+    newName = "renamedFirst"
+    zf = ::Zip::File.new(TEST_ZIP.zip_name)
+    oldName = zf.entries.first
+    zf.rename(oldName, newName)
+    zf.commit
+
+    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
+    assert(zfRead.entries.detect { |e| e.name == newName } != nil)
+    assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
+    zfRead.close
+
+    zf.close
+    res = system("unzip -t #{TEST_ZIP.zip_name}")
+    assert_equal(res, true)
+  end
+
+  def test_double_commit(filename = 'test/data/generated/double_commit_test.zip')
+    ::FileUtils.touch('test/data/generated/test_double_commit1.txt')
+    ::FileUtils.touch('test/data/generated/test_double_commit2.txt')
+    zf = ::Zip::File.open(filename, ::Zip::File::CREATE)
+    zf.add('test1.txt', 'test/data/generated/test_double_commit1.txt')
+    zf.commit
+    zf.add('test2.txt', 'test/data/generated/test_double_commit2.txt')
+    zf.commit
+    zf.close
+    zf2 = ::Zip::File.open(filename)
+    assert(zf2.entries.detect {|e| e.name == 'test1.txt'} != nil )
+    assert(zf2.entries.detect {|e| e.name == 'test2.txt'} != nil )
+    res = system("unzip -t #{filename}")
+    assert_equal(res, true)
+  end
+
+  def test_double_commit_zip64
+    ::Zip.write_zip64_support = true
+    test_double_commit('test/data/generated/double_commit_test64.zip')
+  end
+
+  def test_write_buffer
+    newName = "renamedFirst"
+    zf = ::Zip::File.new(TEST_ZIP.zip_name)
+    oldName = zf.entries.first
+    zf.rename(oldName, newName)
+    io = ::StringIO.new('')
+    buffer = zf.write_buffer(io)
+    File.open(TEST_ZIP.zip_name, 'wb') { |f| f.write buffer.string }
+    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
+    assert(zfRead.entries.detect { |e| e.name == newName } != nil)
+    assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
+    zfRead.close
+
+    zf.close
+  end
+
+  # This test tests that after commit, you
+  # can delete the file you used to add the entry to the zip file
+  # with
+  def test_commitUseZipEntry
+    FileUtils.cp(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
+    zf = ::Zip::File.open(TEST_ZIP.zip_name)
+    zf.add("okToDelete.txt", "okToDelete.txt")
+    assert_contains(zf, "okToDelete.txt")
+    zf.commit
+    File.rename("okToDelete.txt", "okToDeleteMoved.txt")
+    assert_contains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
+  end
+
+#  def test_close
+#    zf = ZipFile.new(TEST_ZIP.zip_name)
+#    zf.close
+#    assert_raises(IOError) {
+#      zf.extract(TEST_ZIP.entry_names.first, "hullubullu")
+#    }
+#  end
+
+  def test_compound1
+    renamedName = "renamedName"
+    originalEntries = []
+    filename_to_remove = ''
+    begin
+      zf = ::Zip::File.new(TEST_ZIP.zip_name)
+      originalEntries = zf.entries.dup
+
+      assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
+      zf.add(TestFiles::RANDOM_ASCII_FILE1,
+             TestFiles::RANDOM_ASCII_FILE1)
+      assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
+
+      entry_to_rename = zf.entries.find { |entry| entry.name.match('longAscii') }
+      zf.rename(entry_to_rename, renamedName)
+      assert_contains(zf, renamedName)
+
+      TestFiles::BINARY_TEST_FILES.each {
+          |filename|
+        zf.add(filename, filename)
+        assert_contains(zf, filename)
+      }
+
+      assert_contains(zf, originalEntries.last.to_s)
+      filename_to_remove = originalEntries.map(&:to_s).find { |name| name.match('longBinary') }
+      zf.remove(filename_to_remove)
+      assert_not_contains(zf, filename_to_remove)
+
+    ensure
+      zf.close
+    end
+    begin
+      zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
+      assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
+      assert_contains(zfRead, renamedName)
+      TestFiles::BINARY_TEST_FILES.each {
+          |filename|
+        assert_contains(zfRead, filename)
+      }
+      assert_not_contains(zfRead, filename_to_remove)
+    ensure
+      zfRead.close
+    end
+  end
+
+  def test_compound2
+    begin
+      zf = ::Zip::File.new(TEST_ZIP.zip_name)
+      originalEntries = zf.entries.dup
+
+      originalEntries.each {
+          |entry|
+        zf.remove(entry)
+        assert_not_contains(zf, entry)
+      }
+      assert(zf.entries.empty?)
+
+      TestFiles::ASCII_TEST_FILES.each {
+          |filename|
+        zf.add(filename, filename)
+        assert_contains(zf, filename)
+      }
+      assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
+
+      zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
+      assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0])
+      assert_contains(zf, "newName")
+    ensure
+      zf.close
+    end
+    begin
+      zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
+      asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
+      asciiTestFiles.shift
+      asciiTestFiles.each {
+          |filename|
+        assert_contains(zf, filename)
+      }
+
+      assert_contains(zf, "newName")
+    ensure
+      zfRead.close
+    end
+  end
+
+  def test_changeComment
+    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+      zf.comment = "my changed comment"
+    end
+    zfRead = ::Zip::File.open(TEST_ZIP.zip_name)
+    assert_equal("my changed comment", zfRead.comment)
+  end
+
+  def test_preserve_file_order
+    entryNames = nil
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      entryNames = zf.entries.map { |e| e.to_s }
+      zf.get_output_stream("a.txt") { |os| os.write "this is a.txt" }
+      zf.get_output_stream("z.txt") { |os| os.write "this is z.txt" }
+      zf.get_output_stream("k.txt") { |os| os.write "this is k.txt" }
+      entryNames << "a.txt" << "z.txt" << "k.txt"
+    }
+
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      assert_equal(entryNames, zf.entries.map { |e| e.to_s })
+      entries = zf.entries.sort_by { |e| e.name }.reverse
+      entries.each {
+          |e|
+        zf.remove e
+        zf.get_output_stream(e) { |os| os.write "foo" }
+      }
+      entryNames = entries.map { |e| e.to_s }
+    }
+    ::Zip::File.open(TEST_ZIP.zip_name) {
+        |zf|
+      assert_equal(entryNames, zf.entries.map { |e| e.to_s })
+    }
+  end
+
+  def test_streaming
+    fname = ::File.join(::File.expand_path(::File.dirname(__FILE__)), "../README.md")
+    zname = "test/data/generated/README.zip"
+    Zip::File.open(zname, Zip::File::CREATE) do |zipfile|
+      zipfile.get_output_stream(File.basename(fname)) do |f|
+        f.puts File.read(fname)
+      end
+    end
+
+    data = nil
+    Zip::File.open_buffer(File.binread(zname)) do |zipfile|
+      zipfile.each do |entry|
+        next unless entry.name =~ /README.md/
+        data = zipfile.read(entry)
+      end
+    end
+    assert data
+    assert data =~ /Simonov/
+  end
+
+  private
+  def assert_contains(zf, entryName, filename = entryName)
+    assert(zf.entries.detect { |e| e.name == entryName } != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
+    assert_entryContents(zf, entryName, filename) if File.exist?(filename)
+  end
+
+  def assert_not_contains(zf, entryName)
+    assert(zf.entries.detect { |e| e.name == entryName } == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
+  end
+end
diff --git a/test/filesystem/dir_iterator_test.rb b/test/filesystem/dir_iterator_test.rb
new file mode 100644
index 0000000..b53886f
--- /dev/null
+++ b/test/filesystem/dir_iterator_test.rb
@@ -0,0 +1,62 @@
+require 'test_helper'
+require 'zip/filesystem'
+
+class ZipFsDirIteratorTest < MiniTest::Unit::TestCase
+
+  FILENAME_ARRAY = [ "f1", "f2", "f3", "f4", "f5", "f6"  ]
+
+  def setup
+    @dirIt = ::Zip::FileSystem::ZipFsDirIterator.new(FILENAME_ARRAY)
+  end
+
+  def test_close
+    @dirIt.close
+    assert_raises(IOError, "closed directory") {
+      @dirIt.each { |e| p e }
+    }
+    assert_raises(IOError, "closed directory") {
+      @dirIt.read
+    }
+    assert_raises(IOError, "closed directory") {
+      @dirIt.rewind
+    }
+    assert_raises(IOError, "closed directory") {
+      @dirIt.seek(0)
+    }
+    assert_raises(IOError, "closed directory") {
+      @dirIt.tell
+    }
+
+  end
+
+  def test_each
+    # Tested through Enumerable.entries
+    assert_equal(FILENAME_ARRAY, @dirIt.entries)
+  end
+
+  def test_read
+    FILENAME_ARRAY.size.times {
+      |i|
+      assert_equal(FILENAME_ARRAY[i], @dirIt.read)
+    }
+  end
+
+  def test_rewind
+    @dirIt.read
+    @dirIt.read
+    assert_equal(FILENAME_ARRAY[2], @dirIt.read)
+    @dirIt.rewind
+    assert_equal(FILENAME_ARRAY[0], @dirIt.read)
+  end
+
+  def test_tell_seek
+    @dirIt.read
+    @dirIt.read
+    pos = @dirIt.tell
+    valAtPos = @dirIt.read
+    @dirIt.read
+    @dirIt.seek(pos)
+    assert_equal(valAtPos, @dirIt.read)
+  end
+
+end
diff --git a/test/filesystem/directory_test.rb b/test/filesystem/directory_test.rb
new file mode 100644
index 0000000..d434a70
--- /dev/null
+++ b/test/filesystem/directory_test.rb
@@ -0,0 +1,131 @@
+require 'test_helper'
+require 'zip/filesystem'
+
+class ZipFsDirectoryTest < MiniTest::Unit::TestCase
+  TEST_ZIP = "test/data/generated/zipWithDirs_copy.zip"
+
+  def setup
+    FileUtils.cp("test/data/zipWithDirs.zip", TEST_ZIP)
+  end
+
+  def test_delete
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+      assert_raises(Errno::ENOENT, "No such file or directory - NoSuchFile.txt") {
+        zf.dir.delete("NoSuchFile.txt")
+      }
+      assert_raises(Errno::EINVAL, "Invalid argument - file1") {
+        zf.dir.delete("file1")
+      }
+      assert(zf.file.exists?("dir1"))
+      zf.dir.delete("dir1")
+      assert(! zf.file.exists?("dir1"))
+    }
+  end
+
+  def test_mkdir
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+      assert_raises(Errno::EEXIST, "File exists - dir1") {
+        zf.dir.mkdir("file1")
+      }
+      assert_raises(Errno::EEXIST, "File exists - dir1") {
+        zf.dir.mkdir("dir1")
+      }
+      assert(!zf.file.exists?("newDir"))
+      zf.dir.mkdir("newDir")
+      assert(zf.file.directory?("newDir"))
+      assert(!zf.file.exists?("newDir2"))
+      zf.dir.mkdir("newDir2", 3485)
+      assert(zf.file.directory?("newDir2"))
+    }
+  end
+
+  def test_pwd_chdir_entries
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+      assert_equal("/", zf.dir.pwd)
+
+      assert_raises(Errno::ENOENT, "No such file or directory - no such dir") {
+        zf.dir.chdir "no such dir"
+      }
+
+      assert_raises(Errno::EINVAL, "Invalid argument - file1") {
+        zf.dir.chdir "file1"
+      }
+
+      assert_equal(["dir1", "dir2", "file1"].sort, zf.dir.entries(".").sort)
+      zf.dir.chdir "dir1"
+      assert_equal("/dir1", zf.dir.pwd)
+      assert_equal(["dir11", "file11", "file12"], zf.dir.entries(".").sort)
+
+      zf.dir.chdir "../dir2/dir21"
+      assert_equal("/dir2/dir21", zf.dir.pwd)
+      assert_equal(["dir221"].sort, zf.dir.entries(".").sort)
+    }
+  end
+
+  def test_foreach
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+
+      blockCalled = false
+      assert_raises(Errno::ENOENT, "No such file or directory - noSuchDir") {
+        zf.dir.foreach("noSuchDir") { |e| blockCalled = true }
+      }
+      assert(! blockCalled)
+
+      assert_raises(Errno::ENOTDIR, "Not a directory - file1") {
+        zf.dir.foreach("file1") { |e| blockCalled = true }
+      }
+      assert(! blockCalled)
+
+      entries = []
+      zf.dir.foreach(".") { |e| entries << e }
+      assert_equal(["dir1", "dir2", "file1"].sort, entries.sort)
+
+      entries = []
+      zf.dir.foreach("dir1") { |e| entries << e }
+      assert_equal(["dir11", "file11", "file12"], entries.sort)
+    }
+  end
+
+  def test_chroot
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+      assert_raises(NotImplementedError) {
+        zf.dir.chroot
+      }
+    }
+  end
+
+  # Globbing not supported yet
+  #def test_glob
+  #  # test alias []-operator too
+  #  fail "implement test"
+  #end
+
+  def test_open_new
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+
+      assert_raises(Errno::ENOTDIR, "Not a directory - file1") {
+        zf.dir.new("file1")
+      }
+
+      assert_raises(Errno::ENOENT, "No such file or directory - noSuchFile") {
+        zf.dir.new("noSuchFile")
+      }
+
+      d = zf.dir.new(".")
+      assert_equal(["file1", "dir1", "dir2"].sort, d.entries.sort)
+      d.close
+
+      zf.dir.open("dir1") {
+        |dir|
+        assert_equal(["dir11", "file11", "file12"].sort, dir.entries.sort)
+      }
+    }
+  end
+
+end
diff --git a/test/filesystem/file_mutating_test.rb b/test/filesystem/file_mutating_test.rb
new file mode 100644
index 0000000..d06f4cd
--- /dev/null
+++ b/test/filesystem/file_mutating_test.rb
@@ -0,0 +1,100 @@
+require 'test_helper'
+require 'zip/filesystem'
+
+class ZipFsFileMutatingTest < MiniTest::Unit::TestCase
+  TEST_ZIP = "test/data/generated/zipWithDirs_copy.zip"
+  def setup
+    FileUtils.cp("test/data/zipWithDirs.zip", TEST_ZIP)
+  end
+
+  def teardown
+  end
+
+  def test_delete
+    do_test_delete_or_unlink(:delete)
+  end
+
+  def test_unlink
+    do_test_delete_or_unlink(:unlink)
+  end
+
+  def test_open_write
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+
+      zf.file.open("test_open_write_entry", "w") {
+        |f|
+        f.write "This is what I'm writing"
+      }
+      assert_equal("This is what I'm writing",
+                    zf.file.read("test_open_write_entry"))
+
+      # Test with existing entry
+      zf.file.open("file1", "wb") { #also check that 'b' option is ignored
+        |f|
+        f.write "This is what I'm writing too"
+      }
+      assert_equal("This is what I'm writing too",
+                    zf.file.read("file1"))
+    }
+  end
+
+  def test_rename
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+      assert_raises(Errno::ENOENT, "") {
+        zf.file.rename("NoSuchFile", "bimse")
+      }
+      zf.file.rename("file1", "newNameForFile1")
+    }
+
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+      assert(! zf.file.exists?("file1"))
+      assert(zf.file.exists?("newNameForFile1"))
+    }
+  end
+
+  def test_chmod
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+
+      zf.file.chmod(0765, "file1")
+    }
+
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+      assert_equal(0100765,  zf.file.stat("file1").mode)
+    }
+  end
+
+  def do_test_delete_or_unlink(symbol)
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+      assert(zf.file.exists?("dir2/dir21/dir221/file2221"))
+      zf.file.send(symbol, "dir2/dir21/dir221/file2221")
+      assert(! zf.file.exists?("dir2/dir21/dir221/file2221"))
+
+      assert(zf.file.exists?("dir1/file11"))
+      assert(zf.file.exists?("dir1/file12"))
+      zf.file.send(symbol, "dir1/file11", "dir1/file12")
+      assert(! zf.file.exists?("dir1/file11"))
+      assert(! zf.file.exists?("dir1/file12"))
+
+      assert_raises(Errno::ENOENT) { zf.file.send(symbol, "noSuchFile") }
+      assert_raises(Errno::EISDIR) { zf.file.send(symbol, "dir1/dir11") }
+      assert_raises(Errno::EISDIR) { zf.file.send(symbol, "dir1/dir11/") }
+    }
+
+    ::Zip::File.open(TEST_ZIP) {
+      |zf|
+      assert(! zf.file.exists?("dir2/dir21/dir221/file2221"))
+      assert(! zf.file.exists?("dir1/file11"))
+      assert(! zf.file.exists?("dir1/file12"))
+
+      assert(zf.file.exists?("dir1/dir11"))
+      assert(zf.file.exists?("dir1/dir11/"))
+    }
+  end
+
+end
diff --git a/test/filesystem/file_nonmutating_test.rb b/test/filesystem/file_nonmutating_test.rb
new file mode 100644
index 0000000..683eb86
--- /dev/null
+++ b/test/filesystem/file_nonmutating_test.rb
@@ -0,0 +1,505 @@
+require 'test_helper'
+require 'zip/filesystem'
+
+class ZipFsFileNonmutatingTest < MiniTest::Unit::TestCase
+  def setup
+    @zipsha = Digest::SHA1.file("test/data/zipWithDirs.zip")
+    @zip_file = ::Zip::File.new("test/data/zipWithDirs.zip")
+  end
+
+  def teardown
+    @zip_file.close if @zip_file
+    assert_equal(@zipsha, Digest::SHA1.file("test/data/zipWithDirs.zip"))
+  end
+
+  def test_umask
+    assert_equal(::File.umask, @zip_file.file.umask)
+    @zip_file.file.umask(0006)
+  end
+
+  def test_exists?
+    assert(! @zip_file.file.exists?("notAFile"))
+    assert(@zip_file.file.exists?("file1"))
+    assert(@zip_file.file.exists?("dir1"))
+    assert(@zip_file.file.exists?("dir1/"))
+    assert(@zip_file.file.exists?("dir1/file12"))
+    assert(@zip_file.file.exist?("dir1/file12")) # notice, tests exist? alias of exists? !
+
+    @zip_file.dir.chdir "dir1/"
+    assert(!@zip_file.file.exists?("file1"))
+    assert(@zip_file.file.exists?("file12"))
+  end
+
+  def test_open_read
+    blockCalled = false
+    @zip_file.file.open("file1", "r") {
+      |f|
+      blockCalled = true
+      assert_equal("this is the entry 'file1' in my test archive!",
+        f.readline.chomp)
+    }
+    assert(blockCalled)
+
+    blockCalled = false
+    @zip_file.file.open("file1", "rb") { # test binary flag is ignored
+      |f|
+      blockCalled = true
+      assert_equal("this is the entry 'file1' in my test archive!",
+        f.readline.chomp)
+    }
+    assert(blockCalled)
+
+    blockCalled = false
+    @zip_file.dir.chdir "dir2"
+    @zip_file.file.open("file21", "r") {
+      |f|
+      blockCalled = true
+      assert_equal("this is the entry 'dir2/file21' in my test archive!",
+        f.readline.chomp)
+    }
+    assert(blockCalled)
+    @zip_file.dir.chdir "/"
+
+    assert_raises(Errno::ENOENT) {
+      @zip_file.file.open("noSuchEntry")
+    }
+
+    begin
+      is = @zip_file.file.open("file1")
+      assert_equal("this is the entry 'file1' in my test archive!",
+        is.readline.chomp)
+    ensure
+      is.close if is
+    end
+  end
+
+  def test_new
+    begin
+      is = @zip_file.file.new("file1")
+      assert_equal("this is the entry 'file1' in my test archive!",
+        is.readline.chomp)
+    ensure
+      is.close if is
+    end
+    begin
+      is = @zip_file.file.new("file1") {
+  fail "should not call block"
+      }
+    ensure
+      is.close if is
+    end
+  end
+
+  def test_symlink
+    assert_raises(NotImplementedError) {
+      @zip_file.file.symlink("file1", "aSymlink")
+    }
+  end
+
+  def test_size
+    assert_raises(Errno::ENOENT) { @zip_file.file.size("notAFile") }
+    assert_equal(72, @zip_file.file.size("file1"))
+    assert_equal(0, @zip_file.file.size("dir2/dir21"))
+
+    assert_equal(72, @zip_file.file.stat("file1").size)
+    assert_equal(0, @zip_file.file.stat("dir2/dir21").size)
+  end
+
+  def test_size?
+    assert_equal(nil, @zip_file.file.size?("notAFile"))
+    assert_equal(72, @zip_file.file.size?("file1"))
+    assert_equal(nil, @zip_file.file.size?("dir2/dir21"))
+
+    assert_equal(72, @zip_file.file.stat("file1").size?)
+    assert_equal(nil, @zip_file.file.stat("dir2/dir21").size?)
+  end
+
+
+  def test_file?
+    assert(@zip_file.file.file?("file1"))
+    assert(@zip_file.file.file?("dir2/file21"))
+    assert(! @zip_file.file.file?("dir1"))
+    assert(! @zip_file.file.file?("dir1/dir11"))
+
+    assert(@zip_file.file.stat("file1").file?)
+    assert(@zip_file.file.stat("dir2/file21").file?)
+    assert(! @zip_file.file.stat("dir1").file?)
+    assert(! @zip_file.file.stat("dir1/dir11").file?)
+  end
+
+  include ExtraAssertions
+
+  def test_dirname
+    assert_forwarded(File, :dirname, "retVal", "a/b/c/d") {
+      @zip_file.file.dirname("a/b/c/d")
+    }
+  end
+
+  def test_basename
+    assert_forwarded(File, :basename, "retVal", "a/b/c/d") {
+      @zip_file.file.basename("a/b/c/d")
+    }
+  end
+
+  def test_split
+    assert_forwarded(File, :split, "retVal", "a/b/c/d") {
+      @zip_file.file.split("a/b/c/d")
+    }
+  end
+
+  def test_join
+    assert_equal("a/b/c", @zip_file.file.join("a/b", "c"))
+    assert_equal("a/b/c/d", @zip_file.file.join("a/b", "c/d"))
+    assert_equal("/c/d", @zip_file.file.join("", "c/d"))
+    assert_equal("a/b/c/d", @zip_file.file.join("a", "b", "c", "d"))
+  end
+
+  def test_utime
+    t_now = ::Zip::DOSTime.now
+    t_bak = @zip_file.file.mtime("file1")
+    @zip_file.file.utime(t_now, "file1")
+    assert_equal(t_now, @zip_file.file.mtime("file1"))
+    @zip_file.file.utime(t_bak, "file1")
+    assert_equal(t_bak, @zip_file.file.mtime("file1"))
+  end
+
+
+  def assert_always_false(operation)
+    assert(! @zip_file.file.send(operation, "noSuchFile"))
+    assert(! @zip_file.file.send(operation, "file1"))
+    assert(! @zip_file.file.send(operation, "dir1"))
+    assert(! @zip_file.file.stat("file1").send(operation))
+    assert(! @zip_file.file.stat("dir1").send(operation))
+  end
+
+  def assert_true_if_entry_exists(operation)
+    assert(! @zip_file.file.send(operation, "noSuchFile"))
+    assert(@zip_file.file.send(operation, "file1"))
+    assert(@zip_file.file.send(operation, "dir1"))
+    assert(@zip_file.file.stat("file1").send(operation))
+    assert(@zip_file.file.stat("dir1").send(operation))
+  end
+
+  def test_pipe?
+    assert_always_false(:pipe?)
+  end
+
+  def test_blockdev?
+    assert_always_false(:blockdev?)
+  end
+
+  def test_symlink?
+    assert_always_false(:symlink?)
+  end
+
+  def test_socket?
+    assert_always_false(:socket?)
+  end
+
+  def test_chardev?
+    assert_always_false(:chardev?)
+  end
+
+  def test_truncate
+    assert_raises(StandardError, "truncate not supported") {
+      @zip_file.file.truncate("file1", 100)
+    }
+  end
+
+  def assert_e_n_o_e_n_t(operation, args = ["NoSuchFile"])
+    assert_raises(Errno::ENOENT) {
+      @zip_file.file.send(operation, *args)
+    }
+  end
+
+  def test_ftype
+    assert_e_n_o_e_n_t(:ftype)
+    assert_equal("file", @zip_file.file.ftype("file1"))
+    assert_equal("directory", @zip_file.file.ftype("dir1/dir11"))
+    assert_equal("directory", @zip_file.file.ftype("dir1/dir11/"))
+  end
+
+  def test_link
+    assert_raises(NotImplementedError) {
+      @zip_file.file.link("file1", "someOtherString")
+    }
+  end
+
+  def test_directory?
+    assert(! @zip_file.file.directory?("notAFile"))
+    assert(! @zip_file.file.directory?("file1"))
+    assert(! @zip_file.file.directory?("dir1/file11"))
+    assert(@zip_file.file.directory?("dir1"))
+    assert(@zip_file.file.directory?("dir1/"))
+    assert(@zip_file.file.directory?("dir2/dir21"))
+
+    assert(! @zip_file.file.stat("file1").directory?)
+    assert(! @zip_file.file.stat("dir1/file11").directory?)
+    assert(@zip_file.file.stat("dir1").directory?)
+    assert(@zip_file.file.stat("dir1/").directory?)
+    assert(@zip_file.file.stat("dir2/dir21").directory?)
+  end
+
+  def test_chown
+    assert_equal(2, @zip_file.file.chown(1,2, "dir1", "file1"))
+    assert_equal(1, @zip_file.file.stat("dir1").uid)
+    assert_equal(2, @zip_file.file.stat("dir1").gid)
+    assert_equal(2, @zip_file.file.chown(nil, nil, "dir1", "file1"))
+  end
+
+  def test_zero?
+    assert(! @zip_file.file.zero?("notAFile"))
+    assert(! @zip_file.file.zero?("file1"))
+    assert(@zip_file.file.zero?("dir1"))
+    blockCalled = false
+    ::Zip::File.open("test/data/generated/5entry.zip") {
+      |zf|
+      blockCalled = true
+      assert(zf.file.zero?("test/data/generated/empty.txt"))
+    }
+    assert(blockCalled)
+
+    assert(! @zip_file.file.stat("file1").zero?)
+    assert(@zip_file.file.stat("dir1").zero?)
+    blockCalled = false
+    ::Zip::File.open("test/data/generated/5entry.zip") {
+      |zf|
+      blockCalled = true
+      assert(zf.file.stat("test/data/generated/empty.txt").zero?)
+    }
+    assert(blockCalled)
+  end
+
+  def test_expand_path
+    ::Zip::File.open("test/data/zipWithDirs.zip") {
+      |zf|
+      assert_equal("/", zf.file.expand_path("."))
+      zf.dir.chdir "dir1"
+      assert_equal("/dir1", zf.file.expand_path("."))
+      assert_equal("/dir1/file12", zf.file.expand_path("file12"))
+      assert_equal("/", zf.file.expand_path(".."))
+      assert_equal("/dir2/dir21", zf.file.expand_path("../dir2/dir21"))
+    }
+  end
+
+  def test_mtime
+    assert_equal(::Zip::DOSTime.at(1027694306),
+      @zip_file.file.mtime("dir2/file21"))
+    assert_equal(::Zip::DOSTime.at(1027690863),
+      @zip_file.file.mtime("dir2/dir21"))
+    assert_raises(Errno::ENOENT) {
+      @zip_file.file.mtime("noSuchEntry")
+    }
+
+    assert_equal(::Zip::DOSTime.at(1027694306),
+      @zip_file.file.stat("dir2/file21").mtime)
+    assert_equal(::Zip::DOSTime.at(1027690863),
+      @zip_file.file.stat("dir2/dir21").mtime)
+  end
+
+  def test_ctime
+    assert_nil(@zip_file.file.ctime("file1"))
+    assert_nil(@zip_file.file.stat("file1").ctime)
+  end
+
+  def test_atime
+    assert_nil(@zip_file.file.atime("file1"))
+    assert_nil(@zip_file.file.stat("file1").atime)
+  end
+
+  def test_readable?
+    assert(! @zip_file.file.readable?("noSuchFile"))
+    assert(@zip_file.file.readable?("file1"))
+    assert(@zip_file.file.readable?("dir1"))
+    assert(@zip_file.file.stat("file1").readable?)
+    assert(@zip_file.file.stat("dir1").readable?)
+  end
+
+  def test_readable_real?
+    assert(! @zip_file.file.readable_real?("noSuchFile"))
+    assert(@zip_file.file.readable_real?("file1"))
+    assert(@zip_file.file.readable_real?("dir1"))
+    assert(@zip_file.file.stat("file1").readable_real?)
+    assert(@zip_file.file.stat("dir1").readable_real?)
+  end
+
+  def test_writable?
+    assert(! @zip_file.file.writable?("noSuchFile"))
+    assert(@zip_file.file.writable?("file1"))
+    assert(@zip_file.file.writable?("dir1"))
+    assert(@zip_file.file.stat("file1").writable?)
+    assert(@zip_file.file.stat("dir1").writable?)
+  end
+
+  def test_writable_real?
+    assert(! @zip_file.file.writable_real?("noSuchFile"))
+    assert(@zip_file.file.writable_real?("file1"))
+    assert(@zip_file.file.writable_real?("dir1"))
+    assert(@zip_file.file.stat("file1").writable_real?)
+    assert(@zip_file.file.stat("dir1").writable_real?)
+  end
+
+  def test_executable?
+    assert(! @zip_file.file.executable?("noSuchFile"))
+    assert(! @zip_file.file.executable?("file1"))
+    assert(@zip_file.file.executable?("dir1"))
+    assert(! @zip_file.file.stat("file1").executable?)
+    assert(@zip_file.file.stat("dir1").executable?)
+  end
+
+  def test_executable_real?
+    assert(! @zip_file.file.executable_real?("noSuchFile"))
+    assert(! @zip_file.file.executable_real?("file1"))
+    assert(@zip_file.file.executable_real?("dir1"))
+    assert(! @zip_file.file.stat("file1").executable_real?)
+    assert(@zip_file.file.stat("dir1").executable_real?)
+  end
+
+  def test_owned?
+    assert_true_if_entry_exists(:owned?)
+  end
+
+  def test_grpowned?
+    assert_true_if_entry_exists(:grpowned?)
+  end
+
+  def test_setgid?
+    assert_always_false(:setgid?)
+  end
+
+  def test_setuid?
+    assert_always_false(:setgid?)
+  end
+
+  def test_sticky?
+    assert_always_false(:sticky?)
+  end
+
+  def test_readlink
+    assert_raises(NotImplementedError) {
+      @zip_file.file.readlink("someString")
+    }
+  end
+
+  def test_stat
+    s = @zip_file.file.stat("file1")
+    assert(s.kind_of?(File::Stat)) # It pretends
+    assert_raises(Errno::ENOENT, "No such file or directory - noSuchFile") {
+      @zip_file.file.stat("noSuchFile")
+    }
+  end
+
+  def test_lstat
+    assert(@zip_file.file.lstat("file1").file?)
+  end
+
+  def test_pipe
+    assert_raises(NotImplementedError) {
+      @zip_file.file.pipe
+    }
+  end
+
+  def test_foreach
+    ::Zip::File.open("test/data/generated/zipWithDir.zip") do |zf|
+      ref = []
+      File.foreach("test/data/file1.txt") { |e| ref << e }
+      index = 0
+
+      zf.file.foreach("test/data/file1.txt") do |l|
+        #Ruby replaces \n with \r\n automatically on windows
+        newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l
+        assert_equal(ref[index], newline)
+        index = index.next
+      end
+      assert_equal(ref.size, index)
+    end
+
+    ::Zip::File.open("test/data/generated/zipWithDir.zip") do |zf|
+      ref = []
+      File.foreach("test/data/file1.txt", " ") { |e| ref << e }
+      index = 0
+
+      zf.file.foreach("test/data/file1.txt", " ") do |l|
+        #Ruby replaces \n with \r\n automatically on windows
+        newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l
+        assert_equal(ref[index], newline)
+        index = index.next
+      end
+      assert_equal(ref.size, index)
+    end
+  end
+
+  def test_glob
+    ::Zip::File.open('test/data/globTest.zip') do |zf|
+      {
+        'globTest/foo.txt' => ['globTest/foo.txt'],
+        '*/foo.txt' => ['globTest/foo.txt'],
+        '**/foo.txt' => ['globTest/foo.txt','globTest/foo/bar/baz/foo.txt'],
+        '*/foo/**/*.txt' => ['globTest/foo/bar/baz/foo.txt']
+      }.each do |spec,expected_results|
+        results = zf.glob(spec)
+        assert results.all?{|entry| entry.is_a? ::Zip::Entry }
+
+        result_strings = results.map(&:to_s)
+        missing_matches = expected_results - result_strings
+        extra_matches = result_strings - expected_results
+
+        assert extra_matches.empty?, %Q{spec #{spec.inspect} has extra results #{extra_matches.inspect}}
+        assert missing_matches.empty?, %Q{spec #{spec.inspect} missing results #{missing_matches.inspect}}
+      end
+    end
+
+    ::Zip::File.open('test/data/globTest.zip') do |zf|
+      results = []
+      zf.glob('**/foo.txt') do |match|
+        results << "<#{match.class.name}: #{match.to_s}>"
+      end
+      assert((not results.empty?), 'block not run, or run out of context')
+      assert_equal 2, results.size
+      assert_operator results, :include?, '<Zip::Entry: globTest/foo.txt>'
+      assert_operator results, :include?, '<Zip::Entry: globTest/foo/bar/baz/foo.txt>'
+    end
+  end
+
+  def test_popen
+    if Zip::RUNNING_ON_WINDOWS
+      #This is pretty much projectile vomit but it allows the test to be
+      #run on windows also
+      system_dir = ::File.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '')
+      zipfile_dir = @zip_file.file.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '')
+      assert_equal(system_dir, zipfile_dir)
+    else
+      assert_equal(::File.popen('ls') { |f| f.read },
+                   @zip_file.file.popen('ls') { |f| f.read })
+    end
+  end
+
+# Can be added later
+#  def test_select
+#    fail "implement test"
+#  end
+
+  def test_readlines
+    ::Zip::File.open("test/data/generated/zipWithDir.zip") do |zf|
+      orig_file = ::File.readlines("test/data/file1.txt")
+      zip_file = zf.file.readlines("test/data/file1.txt")
+
+      #Ruby replaces \n with \r\n automatically on windows
+      zip_file.each { |l| l.gsub!(/\r\n/, "\n") } if Zip::RUNNING_ON_WINDOWS
+
+      assert_equal(orig_file, zip_file)
+    end
+  end
+
+  def test_read
+    ::Zip::File.open("test/data/generated/zipWithDir.zip") do |zf|
+      orig_file = ::File.read("test/data/file1.txt")
+
+      #Ruby replaces \n with \r\n automatically on windows
+      zip_file = Zip::RUNNING_ON_WINDOWS ? \
+          zf.file.read("test/data/file1.txt").gsub(/\r\n/, "\n") : zf.file.read("test/data/file1.txt")
+      assert_equal(orig_file, zip_file)
+    end
+  end
+
+end
diff --git a/test/filesystem/file_stat_test.rb b/test/filesystem/file_stat_test.rb
new file mode 100644
index 0000000..5e41192
--- /dev/null
+++ b/test/filesystem/file_stat_test.rb
@@ -0,0 +1,66 @@
+require 'test_helper'
+require 'zip/filesystem'
+
+class ZipFsFileStatTest < MiniTest::Unit::TestCase
+
+  def setup
+    @zip_file = ::Zip::File.new("test/data/zipWithDirs.zip")
+  end
+
+  def teardown
+    @zip_file.close if @zip_file
+  end
+
+  def test_blocks
+    assert_equal(nil, @zip_file.file.stat("file1").blocks)
+  end
+
+  def test_ino
+    assert_equal(0, @zip_file.file.stat("file1").ino)
+  end
+
+  def test_uid
+    assert_equal(0, @zip_file.file.stat("file1").uid)
+  end
+
+  def test_gid
+    assert_equal(0, @zip_file.file.stat("file1").gid)
+  end
+
+  def test_ftype
+    assert_equal("file", @zip_file.file.stat("file1").ftype)
+    assert_equal("directory", @zip_file.file.stat("dir1").ftype)
+  end
+
+  def test_mode
+    assert_equal(0600, @zip_file.file.stat("file1").mode & 0777)
+    assert_equal(0600, @zip_file.file.stat("file1").mode & 0777)
+    assert_equal(0755, @zip_file.file.stat("dir1").mode & 0777)
+    assert_equal(0755, @zip_file.file.stat("dir1").mode & 0777)
+  end
+
+  def test_dev
+    assert_equal(0, @zip_file.file.stat("file1").dev)
+  end
+
+  def test_rdev
+    assert_equal(0, @zip_file.file.stat("file1").rdev)
+  end
+
+  def test_rdev_major
+    assert_equal(0, @zip_file.file.stat("file1").rdev_major)
+  end
+
+  def test_rdev_minor
+    assert_equal(0, @zip_file.file.stat("file1").rdev_minor)
+  end
+
+  def test_nlink
+    assert_equal(1, @zip_file.file.stat("file1").nlink)
+  end
+
+  def test_blksize
+    assert_nil(@zip_file.file.stat("file1").blksize)
+  end
+
+end
diff --git a/test/gentestfiles.rb b/test/gentestfiles.rb
index 2a4e9f0..94a9ddb 100755
--- a/test/gentestfiles.rb
+++ b/test/gentestfiles.rb
@@ -3,66 +3,64 @@
 $VERBOSE = true
 
 class TestFiles
-  RANDOM_ASCII_FILE1  = "data/generated/randomAscii1.txt"
-  RANDOM_ASCII_FILE2  = "data/generated/randomAscii2.txt"
-  RANDOM_ASCII_FILE3  = "data/generated/randomAscii3.txt"
-  RANDOM_BINARY_FILE1 = "data/generated/randomBinary1.bin"
-  RANDOM_BINARY_FILE2 = "data/generated/randomBinary2.bin"
-
-  EMPTY_TEST_DIR      = "data/generated/emptytestdir"
-
-  ASCII_TEST_FILES  = [ RANDOM_ASCII_FILE1, RANDOM_ASCII_FILE2, RANDOM_ASCII_FILE3 ] 
-  BINARY_TEST_FILES = [ RANDOM_BINARY_FILE1, RANDOM_BINARY_FILE2 ]
-  TEST_DIRECTORIES  = [ EMPTY_TEST_DIR ]
-  TEST_FILES        = [ ASCII_TEST_FILES, BINARY_TEST_FILES, EMPTY_TEST_DIR ].flatten!
-
-  def TestFiles.create_test_files(recreate)
-    if (recreate || 
-	! (TEST_FILES.inject(true) { |accum, element| accum && File.exists?(element) }))
-      
-      Dir.mkdir "data/generated" rescue Errno::EEXIST
-
-      ASCII_TEST_FILES.each_with_index do |filename, index|
-        create_random_ascii(filename, 1E4 * (index+1))
-      end
-      
-      BINARY_TEST_FILES.each_with_index do |filename, index|
-        create_random_binary(filename, 1E4 * (index+1))
-      end
+  RANDOM_ASCII_FILE1  = "test/data/generated/randomAscii1.txt"
+  RANDOM_ASCII_FILE2  = "test/data/generated/randomAscii2.txt"
+  RANDOM_ASCII_FILE3  = "test/data/generated/randomAscii3.txt"
+  RANDOM_BINARY_FILE1 = "test/data/generated/randomBinary1.bin"
+  RANDOM_BINARY_FILE2 = "test/data/generated/randomBinary2.bin"
+
+  EMPTY_TEST_DIR = "test/data/generated/emptytestdir"
+
+  ASCII_TEST_FILES = [RANDOM_ASCII_FILE1, RANDOM_ASCII_FILE2, RANDOM_ASCII_FILE3]
+  BINARY_TEST_FILES = [RANDOM_BINARY_FILE1, RANDOM_BINARY_FILE2]
+  TEST_DIRECTORIES = [EMPTY_TEST_DIR]
+  TEST_FILES = [ASCII_TEST_FILES, BINARY_TEST_FILES, EMPTY_TEST_DIR].flatten!
 
-      ensure_dir(EMPTY_TEST_DIR)
+  class << self
+    def create_test_files
+        Dir.mkdir "test/data/generated" unless Dir.exist?('test/data/generated')
+
+        ASCII_TEST_FILES.each_with_index do |filename, index|
+          create_random_ascii(filename, 1E4 * (index+1))
+        end
+
+        BINARY_TEST_FILES.each_with_index do |filename, index|
+          create_random_binary(filename, 1E4 * (index+1))
+        end
+
+        ensure_dir(EMPTY_TEST_DIR)
     end
-  end
 
-  private
-  def TestFiles.create_random_ascii(filename, size)
-    File.open(filename, "wb") do |file|
-      while (file.tell < size)
-        file << rand
+    private
+
+    def create_random_ascii(filename, size)
+      File.open(filename, "wb") do |file|
+        while (file.tell < size)
+          file << rand
+        end
       end
     end
-  end
 
-  def TestFiles.create_random_binary(filename, size)
-    File.open(filename, "wb") do |file|
-      while (file.tell < size)
-        file << [rand].pack("V")
+    def create_random_binary(filename, size)
+      File.open(filename, "wb") do |file|
+        while (file.tell < size)
+          file << [rand].pack("V")
+        end
       end
     end
-  end
 
-  def TestFiles.ensure_dir(name) 
-    if File.exists?(name)
-      return if File.stat(name).directory?
-      File.delete(name)
+    def ensure_dir(name)
+      if File.exist?(name)
+        return if File.stat(name).directory?
+        File.delete(name)
+      end
+      Dir.mkdir(name)
     end
-    Dir.mkdir(name)
-  end
 
+  end
 end
 
 
-
 # For representation and creation of
 # test data
 class TestZipFile
@@ -74,90 +72,63 @@ class TestZipFile
     @comment = comment
   end
 
-  def TestZipFile.create_test_zips(recreate)
-    files = Dir.entries("data/generated")
-    if (recreate || 
-	    ! (files.index(File.basename(TEST_ZIP1.zip_name)) &&
-	       files.index(File.basename(TEST_ZIP2.zip_name)) &&
-	       files.index(File.basename(TEST_ZIP3.zip_name)) &&
-	       files.index(File.basename(TEST_ZIP4.zip_name)) &&
-	       files.index("empty.txt")      &&
-	       files.index("empty_chmod640.txt")      &&
-	       files.index("short.txt")      &&
-	       files.index("longAscii.txt")  &&
-	       files.index("longBinary.bin") ))
-
-      raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless
-          system("/usr/bin/zip #{TEST_ZIP1.zip_name} data/file2.txt")
-      raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless
-          system("/usr/bin/zip #{TEST_ZIP1.zip_name} -d data/file2.txt")
-      
-      File.open("data/generated/empty.txt", "w") {}
-      File.open("data/generated/empty_chmod640.txt", "w") { }
-      ::File.chmod(0640, "data/generated/empty_chmod640.txt")
-      
-      File.open("data/generated/short.txt", "w") { |file| file << "ABCDEF" }
-      ziptestTxt=""
-      File.open("data/file2.txt") { |file| ziptestTxt=file.read }
-      File.open("data/generated/longAscii.txt", "w") do |file|
-        while (file.tell < 1E5)
-          file << ziptestTxt
-        end
+  def TestZipFile.create_test_zips
+    raise "failed to create test zip '#{TEST_ZIP1.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP1.zip_name} test/data/file2.txt")
+    raise "failed to remove entry from '#{TEST_ZIP1.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP1.zip_name} -d test/data/file2.txt")
+
+    File.open("test/data/generated/empty.txt", "w") {}
+    File.open("test/data/generated/empty_chmod640.txt", "w") {}
+    ::File.chmod(0640, "test/data/generated/empty_chmod640.txt")
+
+    File.open("test/data/generated/short.txt", "w") { |file| file << "ABCDEF" }
+    ziptestTxt=""
+    File.open("test/data/file2.txt") { |file| ziptestTxt=file.read }
+    File.open("test/data/generated/longAscii.txt", "w") do |file|
+      while (file.tell < 1E5)
+        file << ziptestTxt
       end
-      
-      testBinaryPattern=""
-      File.open("data/generated/empty.zip") { |file| testBinaryPattern=file.read }
-      testBinaryPattern *= 4
-      
-      File.open("data/generated/longBinary.bin", "wb") do |file|
-        while (file.tell < 6E5)
-          file << testBinaryPattern << rand << "\0"
-        end
+    end
+
+    testBinaryPattern=""
+    File.open("test/data/generated/empty.zip") { |file| testBinaryPattern=file.read }
+    testBinaryPattern *= 4
+
+    File.open("test/data/generated/longBinary.bin", "wb") do |file|
+      while (file.tell < 6E5)
+        file << testBinaryPattern << rand << "\0"
       end
+    end
 
-      raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless
-          system("/usr/bin/zip #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}")
+    raise "failed to create test zip '#{TEST_ZIP2.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP2.zip_name} #{TEST_ZIP2.entry_names.join(' ')}")
 
-      if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
-        raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless
-            system("echo #{TEST_ZIP2.comment}| /usr/bin/zip -z #{TEST_ZIP2.zip_name}\"")
-      else
+    if RUBY_PLATFORM =~ /mswin|mingw|cygwin/
+      raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless system("echo #{TEST_ZIP2.comment}| /usr/bin/zip -z #{TEST_ZIP2.zip_name}\"")
+    else
       # without bash system interprets everything after echo as parameters to
       # echo including | zip -z ...
-        raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless
-            system("bash -c \"echo #{TEST_ZIP2.comment} | /usr/bin/zip -z #{TEST_ZIP2.zip_name}\"")
-      end
+      raise "failed to add comment to test zip '#{TEST_ZIP2.zip_name}'" unless system("bash -c \"echo #{TEST_ZIP2.comment} | /usr/bin/zip -z #{TEST_ZIP2.zip_name}\"")
+    end
 
-      raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless
-          system("/usr/bin/zip #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}")
+    raise "failed to create test zip '#{TEST_ZIP3.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP3.zip_name} #{TEST_ZIP3.entry_names.join(' ')}")
 
-      raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless
-          system("/usr/bin/zip #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}")
-    end
+    raise "failed to create test zip '#{TEST_ZIP4.zip_name}'" unless system("/usr/bin/zip #{TEST_ZIP4.zip_name} #{TEST_ZIP4.entry_names.join(' ')}")
   rescue
     # If there are any Windows developers wanting to use a command line zip.exe
     # to help create the following files, there's a free one available from
     # http://stahlworks.com/dev/index.php?tool=zipunzip
     # that works with the above code
     raise $!.to_s +
-      "\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" +
-      "to create test data. If you don't have it you can download\n"   +
-      "the necessary test files at http://sf.net/projects/rubyzip."
+              "\n\nziptest.rb requires the Info-ZIP program 'zip' in the path\n" +
+              "to create test data. If you don't have it you can download\n" +
+              "the necessary test files at http://sf.net/projects/rubyzip."
   end
 
-  TEST_ZIP1 = TestZipFile.new("data/generated/empty.zip", [])
-  TEST_ZIP2 = TestZipFile.new("data/generated/5entry.zip", %w{ data/generated/longAscii.txt data/generated/empty.txt data/generated/empty_chmod640.txt data/generated/short.txt data/generated/longBinary.bin},
-			      "my zip comment")
-  TEST_ZIP3 = TestZipFile.new("data/generated/test1.zip", %w{ data/file1.txt })
-  TEST_ZIP4 = TestZipFile.new("data/generated/zipWithDir.zip", [ "data/file1.txt", 
-				TestFiles::EMPTY_TEST_DIR])
+  TEST_ZIP1 = TestZipFile.new("test/data/generated/empty.zip", [])
+  TEST_ZIP2 = TestZipFile.new("test/data/generated/5entry.zip", %w{ test/data/generated/longAscii.txt test/data/generated/empty.txt test/data/generated/empty_chmod640.txt test/data/generated/short.txt test/data/generated/longBinary.bin},
+                              "my zip comment")
+  TEST_ZIP3 = TestZipFile.new("test/data/generated/test1.zip", %w{ test/data/file1.txt })
+  TEST_ZIP4 = TestZipFile.new("test/data/generated/zipWithDir.zip", ["test/data/file1.txt",
+                                                                TestFiles::EMPTY_TEST_DIR])
 end
 
 
-END {
-  TestFiles::create_test_files(ARGV.index("recreate") != nil || 
-			     ARGV.index("recreateonly") != nil)
-  TestZipFile::create_test_zips(ARGV.index("recreate") != nil || 
-			      ARGV.index("recreateonly") != nil)
-  exit if ARGV.index("recreateonly") != nil
-}
diff --git a/test/inflater_test.rb b/test/inflater_test.rb
new file mode 100644
index 0000000..765942e
--- /dev/null
+++ b/test/inflater_test.rb
@@ -0,0 +1,14 @@
+require 'test_helper'
+class InflaterTest < MiniTest::Unit::TestCase
+  include DecompressorTests
+
+  def setup
+    super
+    @file = File.new("test/data/file1.txt.deflatedData", "rb")
+    @decompressor = ::Zip::Inflater.new(@file)
+  end
+
+  def teardown
+    @file.close
+  end
+end
diff --git a/test/input_stream_test.rb b/test/input_stream_test.rb
new file mode 100644
index 0000000..c75e6ef
--- /dev/null
+++ b/test/input_stream_test.rb
@@ -0,0 +1,160 @@
+require 'test_helper'
+
+class ZipInputStreamTest < MiniTest::Unit::TestCase
+  include AssertEntry
+
+  def test_new
+    zis = ::Zip::InputStream.new(TestZipFile::TEST_ZIP2.zip_name)
+    assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
+    assert_equal(true, zis.eof?)
+    zis.close
+  end
+
+  def test_openWithBlock
+    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
+        |zis|
+      assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
+      assert_equal(true, zis.eof?)
+    }
+  end
+
+  def test_openWithoutBlock
+    zis = ::Zip::InputStream.open(File.new(TestZipFile::TEST_ZIP2.zip_name, "rb"))
+    assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
+  end
+
+  def test_openBufferWithBlock
+    ::Zip::InputStream.open(File.new(TestZipFile::TEST_ZIP2.zip_name, "rb")) do |zis|
+      assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
+      assert_equal(true, zis.eof?)
+    end
+  end
+
+  def test_open_string_io_without_block
+    string_io = ::StringIO.new(::File.read(TestZipFile::TEST_ZIP2.zip_name))
+    zis = ::Zip::InputStream.open(string_io)
+    assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
+  end
+
+  def test_open_string_io_with_block
+    string_io = ::StringIO.new(::File.read(TestZipFile::TEST_ZIP2.zip_name))
+    ::Zip::InputStream.open(string_io) do |zis|
+      assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
+      assert_equal(true, zis.eof?)
+    end
+  end
+
+  def test_openBufferWithoutBlock
+    zis = ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name)
+    assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
+  end
+
+  def test_incompleteReads
+    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
+        |zis|
+      entry = zis.get_next_entry # longAscii.txt
+      assert_equal(false, zis.eof?)
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
+      assert zis.gets.length > 0
+      assert_equal(false, zis.eof?)
+      entry = zis.get_next_entry # empty.txt
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
+      assert_equal(0, entry.size)
+      assert_equal(nil, zis.gets)
+      assert_equal(true, zis.eof?)
+      entry = zis.get_next_entry # empty_chmod640.txt
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
+      assert_equal(0, entry.size)
+      assert_equal(nil, zis.gets)
+      assert_equal(true, zis.eof?)
+      entry = zis.get_next_entry # short.txt
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
+      assert zis.gets.length > 0
+      entry = zis.get_next_entry # longBinary.bin
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
+      assert zis.gets.length > 0
+    }
+  end
+
+  def test_incomplete_reads_from_string_io
+    string_io = ::StringIO.new(::File.read(TestZipFile::TEST_ZIP2.zip_name))
+    ::Zip::InputStream.open(string_io) do |zis|
+      entry = zis.get_next_entry # longAscii.txt
+      assert_equal(false, zis.eof?)
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
+      assert zis.gets.length > 0
+      assert_equal(false, zis.eof?)
+      entry = zis.get_next_entry # empty.txt
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
+      assert_equal(0, entry.size)
+      assert_equal(nil, zis.gets)
+      assert_equal(true, zis.eof?)
+      entry = zis.get_next_entry # empty_chmod640.txt
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
+      assert_equal(0, entry.size)
+      assert_equal(nil, zis.gets)
+      assert_equal(true, zis.eof?)
+      entry = zis.get_next_entry # short.txt
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
+      assert zis.gets.length > 0
+      entry = zis.get_next_entry # longBinary.bin
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
+      assert zis.gets.length > 0
+    end
+  end
+
+  def test_read_with_number_of_bytes_returns_nil_at_eof
+    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) do |zis|
+      entry = zis.get_next_entry # longAscii.txt
+      zis.read(entry.size)
+      assert_equal(true, zis.eof?)
+      assert_nil(zis.read(1))
+      assert_nil(zis.read(1))
+    end
+  end
+
+  def test_rewind
+    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
+        |zis|
+      e = zis.get_next_entry
+      assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], e.name)
+
+      # Do a little reading
+      buf = ""
+      buf << zis.read(100)
+      assert_equal(100, zis.pos)
+      buf << (zis.gets || "")
+      buf << (zis.gets || "")
+      assert_equal(false, zis.eof?)
+
+      zis.rewind
+
+      buf2 = ""
+      buf2 << zis.read(100)
+      buf2 << (zis.gets || "")
+      buf2 << (zis.gets || "")
+
+      assert_equal(buf, buf2)
+
+      zis.rewind
+      assert_equal(false, zis.eof?)
+      assert_equal(0, zis.pos)
+
+      assert_entry(e.name, zis, e.name)
+    }
+  end
+
+  def test_mix_read_and_gets
+    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
+        |zis|
+      zis.get_next_entry
+      assert_equal("#!/usr/bin/env ruby", zis.gets.chomp)
+      assert_equal(false, zis.eof?)
+      assert_equal("", zis.gets.chomp)
+      assert_equal(false, zis.eof?)
+      assert_equal("$VERBOSE =", zis.read(10))
+      assert_equal(false, zis.eof?)
+    }
+  end
+
+end
diff --git a/test/ioextras/abstract_input_stream_test.rb b/test/ioextras/abstract_input_stream_test.rb
new file mode 100644
index 0000000..e5de6b9
--- /dev/null
+++ b/test/ioextras/abstract_input_stream_test.rb
@@ -0,0 +1,103 @@
+require 'test_helper'
+require 'zip/ioextras'
+
+class AbstractInputStreamTest < MiniTest::Unit::TestCase
+  # AbstractInputStream subclass that provides a read method
+
+  TEST_LINES = ["Hello world#{$/}",
+                "this is the second line#{$/}",
+                "this is the last line"]
+  TEST_STRING = TEST_LINES.join
+  class TestAbstractInputStream
+    include ::Zip::IOExtras::AbstractInputStream
+
+    def initialize(aString)
+      super()
+      @contents = aString
+      @readPointer = 0
+    end
+
+    def sysread(charsToRead, buf = nil)
+      retVal=@contents[@readPointer, charsToRead]
+      @readPointer+=charsToRead
+      return retVal
+    end
+
+    def produce_input
+      sysread(100)
+    end
+
+    def input_finished?
+      @contents[@readPointer] == nil
+    end
+  end
+
+  def setup
+    @io = TestAbstractInputStream.new(TEST_STRING)
+  end
+
+  def test_gets
+    assert_equal(TEST_LINES[0], @io.gets)
+    assert_equal(1, @io.lineno)
+    assert_equal(TEST_LINES[0].length, @io.pos)
+    assert_equal(TEST_LINES[1], @io.gets)
+    assert_equal(2, @io.lineno)
+    assert_equal(TEST_LINES[2], @io.gets)
+    assert_equal(3, @io.lineno)
+    assert_equal(nil, @io.gets)
+    assert_equal(4, @io.lineno)
+  end
+
+  def test_getsMultiCharSeperator
+    assert_equal("Hell", @io.gets("ll"))
+    assert_equal("o world#{$/}this is the second l", @io.gets("d l"))
+  end
+
+  LONG_LINES = [
+      'x'*48 + "\r\n",
+      'y'*49 + "\r\n",
+      'rest',
+  ]
+
+  def test_getsMulitCharSeperator_split
+    io = TestAbstractInputStream.new(LONG_LINES.join)
+    assert_equal(LONG_LINES[0], io.gets("\r\n"))
+    assert_equal(LONG_LINES[1], io.gets("\r\n"))
+    assert_equal(LONG_LINES[2], io.gets("\r\n"))
+  end
+
+  def test_getsWithSepAndIndex
+    io = TestAbstractInputStream.new(LONG_LINES.join)
+    assert_equal('x', io.gets("\r\n", 1))
+    assert_equal('x'*47 + "\r", io.gets("\r\n", 48))
+    assert_equal("\n", io.gets(nil, 1))
+    assert_equal('yy', io.gets(nil, 2))
+  end
+
+  def test_getsWithIndex
+    assert_equal(TEST_LINES[0], @io.gets(100))
+    assert_equal('this', @io.gets(4))
+  end
+
+  def test_each_line
+    lineNumber=0
+    @io.each_line {
+        |line|
+      assert_equal(TEST_LINES[lineNumber], line)
+      lineNumber+=1
+    }
+  end
+
+  def test_readlines
+    assert_equal(TEST_LINES, @io.readlines)
+  end
+
+  def test_readline
+    test_gets
+    begin
+      @io.readline
+      fail "EOFError expected"
+    rescue EOFError
+    end
+  end
+end
diff --git a/test/ioextras/abstract_output_stream_test.rb b/test/ioextras/abstract_output_stream_test.rb
new file mode 100644
index 0000000..a078f7d
--- /dev/null
+++ b/test/ioextras/abstract_output_stream_test.rb
@@ -0,0 +1,106 @@
+require 'test_helper'
+require 'zip/ioextras'
+
+class AbstractOutputStreamTest < MiniTest::Unit::TestCase
+  class TestOutputStream
+    include ::Zip::IOExtras::AbstractOutputStream
+
+    attr_accessor :buffer
+
+    def initialize
+      @buffer = ""
+    end
+
+    def << (data)
+      @buffer << data
+      self
+    end
+  end
+
+  def setup
+    @output_stream = TestOutputStream.new
+
+    @origCommaSep = $,
+    @origOutputSep = $\
+  end
+
+  def teardown
+    $, = @origCommaSep
+    $\ = @origOutputSep
+  end
+
+  def test_write
+    count = @output_stream.write("a little string")
+    assert_equal("a little string", @output_stream.buffer)
+    assert_equal("a little string".length, count)
+
+    count = @output_stream.write(". a little more")
+    assert_equal("a little string. a little more", @output_stream.buffer)
+    assert_equal(". a little more".length, count)
+  end
+
+  def test_print
+    $\ = nil # record separator set to nil
+    @output_stream.print("hello")
+    assert_equal("hello", @output_stream.buffer)
+
+    @output_stream.print(" world.")
+    assert_equal("hello world.", @output_stream.buffer)
+
+    @output_stream.print(" You ok ", "out ", "there?")
+    assert_equal("hello world. You ok out there?", @output_stream.buffer)
+
+    $\ = "\n"
+    @output_stream.print
+    assert_equal("hello world. You ok out there?\n", @output_stream.buffer)
+
+    @output_stream.print("I sure hope so!")
+    assert_equal("hello world. You ok out there?\nI sure hope so!\n", @output_stream.buffer)
+
+    $, = "X"
+    @output_stream.buffer = ""
+    @output_stream.print("monkey", "duck", "zebra")
+    assert_equal("monkeyXduckXzebra\n", @output_stream.buffer)
+
+    $\ = nil
+    @output_stream.buffer = ""
+    @output_stream.print(20)
+    assert_equal("20", @output_stream.buffer)
+  end
+
+  def test_printf
+    @output_stream.printf("%d %04x", 123, 123)
+    assert_equal("123 007b", @output_stream.buffer)
+  end
+
+  def test_putc
+    @output_stream.putc("A")
+    assert_equal("A", @output_stream.buffer)
+    @output_stream.putc(65)
+    assert_equal("AA", @output_stream.buffer)
+  end
+
+  def test_puts
+    @output_stream.puts
+    assert_equal("\n", @output_stream.buffer)
+
+    @output_stream.puts("hello", "world")
+    assert_equal("\nhello\nworld\n", @output_stream.buffer)
+
+    @output_stream.buffer = ""
+    @output_stream.puts("hello\n", "world\n")
+    assert_equal("hello\nworld\n", @output_stream.buffer)
+
+    @output_stream.buffer = ""
+    @output_stream.puts(["hello\n", "world\n"])
+    assert_equal("hello\nworld\n", @output_stream.buffer)
+
+    @output_stream.buffer = ""
+    @output_stream.puts(["hello\n", "world\n"], "bingo")
+    assert_equal("hello\nworld\nbingo\n", @output_stream.buffer)
+
+    @output_stream.buffer = ""
+    @output_stream.puts(16, 20, 50, "hello")
+    assert_equal("16\n20\n50\nhello\n", @output_stream.buffer)
+  end
+end
diff --git a/test/ioextras/fake_io_test.rb b/test/ioextras/fake_io_test.rb
new file mode 100644
index 0000000..856c573
--- /dev/null
+++ b/test/ioextras/fake_io_test.rb
@@ -0,0 +1,18 @@
+require 'test_helper'
+require 'zip/ioextras'
+
+class FakeIOTest < MiniTest::Unit::TestCase
+  class FakeIOUsingClass
+    include ::Zip::IOExtras::FakeIO
+  end
+
+  def test_kind_of?
+    obj = FakeIOUsingClass.new
+
+    assert(obj.kind_of?(Object))
+    assert(obj.kind_of?(FakeIOUsingClass))
+    assert(obj.kind_of?(IO))
+    assert(!obj.kind_of?(Fixnum))
+    assert(!obj.kind_of?(String))
+  end
+end
diff --git a/test/ioextrastest.rb b/test/ioextrastest.rb
deleted file mode 100755
index 103022b..0000000
--- a/test/ioextrastest.rb
+++ /dev/null
@@ -1,234 +0,0 @@
-#!/usr/bin/env ruby
-
-$VERBOSE = true
-
-$: << "../lib"
-
-require 'test/unit'
-require 'zip/ioextras'
-
-include ::Zip::IOExtras
-
-class FakeIOTest < Test::Unit::TestCase
-  class FakeIOUsingClass
-    include FakeIO
-  end
-
-  def test_kind_of?
-    obj = FakeIOUsingClass.new
-    
-    assert(obj.kind_of?(Object))
-    assert(obj.kind_of?(FakeIOUsingClass))
-    assert(obj.kind_of?(IO))
-    assert(!obj.kind_of?(Fixnum))
-    assert(!obj.kind_of?(String))
-  end
-end
-
-class AbstractInputStreamTest < Test::Unit::TestCase
-  # AbstractInputStream subclass that provides a read method
-  
-  TEST_LINES = [ "Hello world#{$/}", 
-    "this is the second line#{$/}", 
-    "this is the last line"]
-  TEST_STRING = TEST_LINES.join
-  class TestAbstractInputStream 
-    include AbstractInputStream
-    def initialize(aString)
-      super()
-      @contents = aString
-      @readPointer = 0
-    end
-
-    def sysread(charsToRead, buf = nil)
-      retVal=@contents[@readPointer, charsToRead]
-      @readPointer+=charsToRead
-      return retVal
-    end
-
-    def produce_input
-      sysread(100)
-    end
-
-    def input_finished?
-      @contents[@readPointer] == nil
-    end
-  end
-
-  def setup
-    @io = TestAbstractInputStream.new(TEST_STRING)
-  end
-  
-  def test_gets
-    assert_equal(TEST_LINES[0], @io.gets)
-    assert_equal(1, @io.lineno)
-    assert_equal(TEST_LINES[0].length, @io.pos)
-    assert_equal(TEST_LINES[1], @io.gets)
-    assert_equal(2, @io.lineno)
-    assert_equal(TEST_LINES[2], @io.gets)
-    assert_equal(3, @io.lineno)
-    assert_equal(nil, @io.gets)
-    assert_equal(4, @io.lineno)
-  end
-
-  def test_getsMultiCharSeperator
-    assert_equal("Hell", @io.gets("ll"))
-    assert_equal("o world#{$/}this is the second l", @io.gets("d l"))
-  end
-
-  LONG_LINES = [
-    'x'*48 + "\r\n",
-    'y'*49 + "\r\n",
-    'rest',
-  ]
-  def test_getsMulitCharSeperator_split
-    io = TestAbstractInputStream.new(LONG_LINES.join)
-    assert_equal(LONG_LINES[0], io.gets("\r\n"))
-    assert_equal(LONG_LINES[1], io.gets("\r\n"))
-    assert_equal(LONG_LINES[2], io.gets("\r\n"))
-  end
-
-  def test_getsWithSepAndIndex
-    io = TestAbstractInputStream.new(LONG_LINES.join)
-    assert_equal('x', io.gets("\r\n", 1))
-    assert_equal('x'*47 + "\r", io.gets("\r\n", 48))
-    assert_equal("\n", io.gets(nil, 1))
-    assert_equal('yy', io.gets(nil, 2))
-  end
-
-  def test_getsWithIndex
-    assert_equal(TEST_LINES[0], @io.gets(100))
-    assert_equal('this', @io.gets(4))
-  end
-
-  def test_each_line
-    lineNumber=0
-    @io.each_line {
-      |line|
-      assert_equal(TEST_LINES[lineNumber], line)
-      lineNumber+=1
-    }
-  end
-
-  def test_readlines
-    assert_equal(TEST_LINES, @io.readlines)
-  end
-
-  def test_readline
-    test_gets
-    begin
-      @io.readline
-      fail "EOFError expected"
-      rescue EOFError
-    end
-  end
-end
-
-class AbstractOutputStreamTest < Test::Unit::TestCase
-  class TestOutputStream
-    include AbstractOutputStream
-
-    attr_accessor :buffer
-
-    def initialize
-      @buffer = ""
-    end
-
-    def << (data)
-      @buffer << data
-      self
-    end
-  end
-
-  def setup
-    @output_stream = TestOutputStream.new
-
-    @origCommaSep = $,
-    @origOutputSep = $\
-  end
-
-  def teardown
-    $, = @origCommaSep
-    $\ = @origOutputSep
-  end
-
-  def test_write
-    count = @output_stream.write("a little string")
-    assert_equal("a little string", @output_stream.buffer)
-    assert_equal("a little string".length, count)
-
-    count = @output_stream.write(". a little more")
-    assert_equal("a little string. a little more", @output_stream.buffer)
-    assert_equal(". a little more".length, count)
-  end
-  
-  def test_print
-    $\ = nil # record separator set to nil
-    @output_stream.print("hello")
-    assert_equal("hello", @output_stream.buffer)
-
-    @output_stream.print(" world.")
-    assert_equal("hello world.", @output_stream.buffer)
-    
-    @output_stream.print(" You ok ",  "out ", "there?")
-    assert_equal("hello world. You ok out there?", @output_stream.buffer)
-
-    $\ = "\n"
-    @output_stream.print
-    assert_equal("hello world. You ok out there?\n", @output_stream.buffer)
-
-    @output_stream.print("I sure hope so!")
-    assert_equal("hello world. You ok out there?\nI sure hope so!\n", @output_stream.buffer)
-
-    $, = "X"
-    @output_stream.buffer = ""
-    @output_stream.print("monkey", "duck", "zebra")
-    assert_equal("monkeyXduckXzebra\n", @output_stream.buffer)
-
-    $\ = nil
-    @output_stream.buffer = ""
-    @output_stream.print(20)
-    assert_equal("20", @output_stream.buffer)
-  end
-  
-  def test_printf
-    @output_stream.printf("%d %04x", 123, 123)
-    assert_equal("123 007b", @output_stream.buffer)
-  end
-  
-  def test_putc
-    @output_stream.putc("A")
-    assert_equal("A", @output_stream.buffer)
-    @output_stream.putc(65)
-    assert_equal("AA", @output_stream.buffer)
-  end
-
-  def test_puts
-    @output_stream.puts
-    assert_equal("\n", @output_stream.buffer)
-
-    @output_stream.puts("hello", "world")
-    assert_equal("\nhello\nworld\n", @output_stream.buffer)
-
-    @output_stream.buffer = ""
-    @output_stream.puts("hello\n", "world\n")
-    assert_equal("hello\nworld\n", @output_stream.buffer)
-    
-    @output_stream.buffer = ""
-    @output_stream.puts(["hello\n", "world\n"])
-    assert_equal("hello\nworld\n", @output_stream.buffer)
-
-    @output_stream.buffer = ""
-    @output_stream.puts(["hello\n", "world\n"], "bingo")
-    assert_equal("hello\nworld\nbingo\n", @output_stream.buffer)
-
-    @output_stream.buffer = ""
-    @output_stream.puts(16, 20, 50, "hello")
-    assert_equal("16\n20\n50\nhello\n", @output_stream.buffer)
-  end
-end
-
-
-# Copyright (C) 2002-2004 Thomas Sondergaard
-# rubyzip is free software; you can redistribute it and/or
-# modify it under the terms of the ruby license.
diff --git a/test/local_entry_test.rb b/test/local_entry_test.rb
new file mode 100644
index 0000000..038bfd9
--- /dev/null
+++ b/test/local_entry_test.rb
@@ -0,0 +1,153 @@
+require 'test_helper'
+
+class ZipLocalEntryTest < MiniTest::Unit::TestCase
+
+  def teardown
+    ::Zip.write_zip64_support = false
+  end
+
+  def test_read_local_entryHeaderOfFirstTestZipEntry
+    ::File.open(TestZipFile::TEST_ZIP3.zip_name, "rb") do |file|
+      entry = ::Zip::Entry.read_local_entry(file)
+
+      assert_equal('', entry.comment)
+      # Differs from windows and unix because of CR LF
+      # assert_equal(480, entry.compressed_size)
+      # assert_equal(0x2a27930f, entry.crc)
+      # extra field is 21 bytes long
+      # probably contains some unix attrutes or something
+      # disabled: assert_equal(nil, entry.extra)
+      assert_equal(::Zip::Entry::DEFLATED, entry.compression_method)
+      assert_equal(TestZipFile::TEST_ZIP3.entry_names[0], entry.name)
+      assert_equal(::File.size(TestZipFile::TEST_ZIP3.entry_names[0]), entry.size)
+      assert(!entry.directory?)
+    end
+  end
+
+  def test_readDateTime
+    ::File.open("test/data/rubycode.zip", "rb") {
+        |file|
+      entry = ::Zip::Entry.read_local_entry(file)
+      assert_equal("zippedruby1.rb", entry.name)
+      assert_equal(::Zip::DOSTime.at(1019261638), entry.time)
+    }
+  end
+
+  def test_read_local_entryFromNonZipFile
+    ::File.open("test/data/file2.txt") {
+        |file|
+      assert_equal(nil, ::Zip::Entry.read_local_entry(file))
+    }
+  end
+
+  def test_read_local_entryFromTruncatedZipFile
+    zipFragment=""
+    ::File.open(TestZipFile::TEST_ZIP2.zip_name) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
+    zipFragment.extend(IOizeString).reset
+    entry = ::Zip::Entry.new
+    entry.read_local_entry(zipFragment)
+    fail "ZipError expected"
+  rescue ::Zip::Error
+  end
+
+  def test_writeEntry
+    entry = ::Zip::Entry.new("file.zip", "entryName", "my little comment",
+                             "thisIsSomeExtraInformation", 100, 987654,
+                             ::Zip::Entry::DEFLATED, 400)
+    write_to_file("localEntryHeader.bin", "centralEntryHeader.bin", entry)
+    entryReadLocal, entryReadCentral = read_from_file("localEntryHeader.bin", "centralEntryHeader.bin")
+    assert(entryReadCentral.extra['Zip64Placeholder'].nil?, 'zip64 placeholder should not be used in central directory')
+    compare_local_entry_headers(entry, entryReadLocal)
+    compare_c_dir_entry_headers(entry, entryReadCentral)
+  end
+
+  def test_writeEntryWithZip64
+    ::Zip.write_zip64_support = true
+    entry = ::Zip::Entry.new("file.zip", "entryName", "my little comment",
+                             "thisIsSomeExtraInformation", 100, 987654,
+                             ::Zip::Entry::DEFLATED, 400)
+    write_to_file("localEntryHeader.bin", "centralEntryHeader.bin", entry)
+    entryReadLocal, entryReadCentral = read_from_file("localEntryHeader.bin", "centralEntryHeader.bin")
+    assert(entryReadLocal.extra['Zip64Placeholder'], 'zip64 placeholder should be used in local file header')
+    entryReadLocal.extra.delete('Zip64Placeholder') # it was removed when writing the c_dir_entry, so remove from compare
+    assert(entryReadCentral.extra['Zip64Placeholder'].nil?, 'zip64 placeholder should not be used in central directory')
+    compare_local_entry_headers(entry, entryReadLocal)
+    compare_c_dir_entry_headers(entry, entryReadCentral)
+  end
+
+  def test_write64Entry
+    ::Zip.write_zip64_support = true
+    entry = ::Zip::Entry.new("bigfile.zip", "entryName", "my little equine",
+                             "malformed extra field because why not",
+                             0x7766554433221100, 0xDEADBEEF, ::Zip::Entry::DEFLATED,
+                             0x9988776655443322)
+    write_to_file("localEntryHeader.bin", "centralEntryHeader.bin", entry)
+    entryReadLocal, entryReadCentral = read_from_file("localEntryHeader.bin", "centralEntryHeader.bin")
+    compare_local_entry_headers(entry, entryReadLocal)
+    compare_c_dir_entry_headers(entry, entryReadCentral)
+  end
+
+  def test_rewriteLocalHeader64
+    ::Zip.write_zip64_support = true
+    buf1 = StringIO.new
+    entry = ::Zip::Entry.new("file.zip", "entryName")
+    entry.write_local_entry(buf1)
+    assert(entry.extra['Zip64'].nil?, "zip64 extra is unnecessarily present")
+
+    buf2 = StringIO.new
+    entry.size = 0x123456789ABCDEF0
+    entry.compressed_size = 0x0123456789ABCDEF
+    entry.write_local_entry(buf2, true)
+    refute_nil(entry.extra['Zip64'])
+    refute_equal(buf1.size, 0)
+    assert_equal(buf1.size, buf2.size) # it can't grow, or we'd clobber file data
+  end
+
+  def test_readLocalOffset
+    entry = ::Zip::Entry.new("file.zip", "entryName")
+    entry.local_header_offset = 12345
+    ::File.open('centralEntryHeader.bin', 'wb') { |f| entry.write_c_dir_entry(f) }
+    read_entry = nil
+    ::File.open('centralEntryHeader.bin', 'rb') { |f| read_entry = ::Zip::Entry.read_c_dir_entry(f) }
+    compare_c_dir_entry_headers(entry, read_entry)
+  end
+
+  def test_read64LocalOffset
+    ::Zip.write_zip64_support = true
+    entry = ::Zip::Entry.new("file.zip", "entryName")
+    entry.local_header_offset = 0x0123456789ABCDEF
+    ::File.open('centralEntryHeader.bin', 'wb') { |f| entry.write_c_dir_entry(f) }
+    read_entry = nil
+    ::File.open('centralEntryHeader.bin', 'rb') { |f| read_entry = ::Zip::Entry.read_c_dir_entry(f) }
+    compare_c_dir_entry_headers(entry, read_entry)
+  end
+
+  private
+  def compare_local_entry_headers(entry1, entry2)
+    assert_equal(entry1.compressed_size, entry2.compressed_size)
+    assert_equal(entry1.crc, entry2.crc)
+    assert_equal(entry1.extra, entry2.extra)
+    assert_equal(entry1.compression_method, entry2.compression_method)
+    assert_equal(entry1.name, entry2.name)
+    assert_equal(entry1.size, entry2.size)
+    assert_equal(entry1.local_header_offset, entry2.local_header_offset)
+  end
+
+  def compare_c_dir_entry_headers(entry1, entry2)
+    compare_local_entry_headers(entry1, entry2)
+    assert_equal(entry1.comment, entry2.comment)
+  end
+
+  def write_to_file(localFileName, centralFileName, entry)
+    ::File.open(localFileName, "wb") { |f| entry.write_local_entry(f) }
+    ::File.open(centralFileName, "wb") { |f| entry.write_c_dir_entry(f) }
+  end
+
+  def read_from_file(localFileName, centralFileName)
+    localEntry = nil
+    cdirEntry = nil
+    ::File.open(localFileName, "rb") { |f| localEntry = ::Zip::Entry.read_local_entry(f) }
+    ::File.open(centralFileName, "rb") { |f| cdirEntry = ::Zip::Entry.read_c_dir_entry(f) }
+    [localEntry, cdirEntry]
+  end
+end
diff --git a/test/output_stream_test.rb b/test/output_stream_test.rb
new file mode 100644
index 0000000..4e5991d
--- /dev/null
+++ b/test/output_stream_test.rb
@@ -0,0 +1,114 @@
+require 'test_helper'
+
+class ZipOutputStreamTest < MiniTest::Unit::TestCase
+  include AssertEntry
+
+  TEST_ZIP = TestZipFile::TEST_ZIP2.clone
+  TEST_ZIP.zip_name = "output.zip"
+
+  def test_new
+    zos = ::Zip::OutputStream.new(TEST_ZIP.zip_name)
+    zos.comment = TEST_ZIP.comment
+    write_test_zip(zos)
+    zos.close
+    assert_test_zip_contents(TEST_ZIP)
+  end
+
+  def test_open
+    ::Zip::OutputStream.open(TEST_ZIP.zip_name) do |zos|
+      zos.comment = TEST_ZIP.comment
+      write_test_zip(zos)
+    end
+    assert_test_zip_contents(TEST_ZIP)
+  end
+
+  def test_write_buffer
+    io = ::StringIO.new('')
+    buffer = ::Zip::OutputStream.write_buffer(io) do |zos|
+      zos.comment = TEST_ZIP.comment
+      write_test_zip(zos)
+    end
+    File.open(TEST_ZIP.zip_name, 'wb') { |f| f.write buffer.string }
+    assert_test_zip_contents(TEST_ZIP)
+  end
+
+  def test_writingToClosedStream
+    assert_i_o_error_in_closed_stream { |zos| zos << "hello world" }
+    assert_i_o_error_in_closed_stream { |zos| zos.puts "hello world" }
+    assert_i_o_error_in_closed_stream { |zos| zos.write "hello world" }
+  end
+
+  def test_cannotOpenFile
+    name = TestFiles::EMPTY_TEST_DIR
+    begin
+      ::Zip::OutputStream.open(name)
+    rescue Exception
+      assert($!.kind_of?(Errno::EISDIR) || # Linux
+                 $!.kind_of?(Errno::EEXIST) || # Windows/cygwin
+                 $!.kind_of?(Errno::EACCES), # Windows
+             "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.class}")
+    end
+  end
+
+  def test_put_next_entry
+    stored_text = "hello world in stored text"
+    entry_name = "file1"
+    comment = "my comment"
+    ::Zip::OutputStream.open(TEST_ZIP.zip_name) do |zos|
+      zos.put_next_entry(entry_name, comment, nil, ::Zip::Entry::STORED)
+      zos << stored_text
+    end
+
+    assert(File.read(TEST_ZIP.zip_name)[stored_text])
+    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+      assert_equal(stored_text, zf.read(entry_name))
+    end
+  end
+
+  def test_put_next_entry_using_zip_entry_creates_entries_with_correct_timestamps
+    file = ::File.open("test/data/file2.txt", "rb")
+    ::Zip::OutputStream.open(TEST_ZIP.zip_name) do |zos|
+      zip_entry = ::Zip::Entry.new(zos, file.path, "", "", 0, 0, ::Zip::Entry::DEFLATED, 0, ::Zip::DOSTime.at(file.mtime))
+      zos.put_next_entry(zip_entry)
+      zos << file.read
+    end
+
+    ::Zip::InputStream::open(TEST_ZIP.zip_name) do |io|
+      while (entry = io.get_next_entry)
+        assert(::Zip::DOSTime.at(file.mtime).dos_equals(::Zip::DOSTime.at(entry.mtime))) # Compare DOS Times, since they are stored with two seconds accuracy
+      end
+    end
+  end
+
+  def test_chained_put_into_next_entry
+    stored_text = "hello world in stored text"
+    stored_text2 = "with chain"
+    entry_name = "file1"
+    comment = "my comment"
+    ::Zip::OutputStream.open(TEST_ZIP.zip_name) do |zos|
+      zos.put_next_entry(entry_name, comment, nil, ::Zip::Entry::STORED)
+      zos << stored_text << stored_text2
+    end
+
+    assert(File.read(TEST_ZIP.zip_name)[stored_text])
+    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+      assert_equal(stored_text + stored_text2, zf.read(entry_name))
+    end
+
+  end
+
+  def assert_i_o_error_in_closed_stream
+    assert_raises(IOError) {
+      zos = ::Zip::OutputStream.new("test_putOnClosedStream.zip")
+      zos.close
+      yield zos
+    }
+  end
+
+  def write_test_zip(zos)
+    TEST_ZIP.entry_names.each do |entryName|
+      zos.put_next_entry(entryName)
+      File.open(entryName, "rb") { |f| zos.write(f.read) }
+    end
+  end
+end
diff --git a/test/pass_thru_compressor_test.rb b/test/pass_thru_compressor_test.rb
new file mode 100644
index 0000000..8fb3263
--- /dev/null
+++ b/test/pass_thru_compressor_test.rb
@@ -0,0 +1,31 @@
+require 'test_helper'
+
+class PassThruCompressorTest < MiniTest::Unit::TestCase
+  include CrcTest
+
+  def test_size
+    File.open("test/dummy.txt", "wb") {
+        |file|
+      compressor = ::Zip::PassThruCompressor.new(file)
+
+      assert_equal(0, compressor.size)
+
+      t1 = "hello world"
+      t2 = ""
+      t3 = "bingo"
+
+      compressor << t1
+      assert_equal(compressor.size, t1.size)
+
+      compressor << t2
+      assert_equal(compressor.size, t1.size + t2.size)
+
+      compressor << t3
+      assert_equal(compressor.size, t1.size + t2.size + t3.size)
+    }
+  end
+
+  def test_crc
+    run_crc_test(::Zip::PassThruCompressor)
+  end
+end
diff --git a/test/pass_thru_decompressor_test.rb b/test/pass_thru_decompressor_test.rb
new file mode 100644
index 0000000..c9217e0
--- /dev/null
+++ b/test/pass_thru_decompressor_test.rb
@@ -0,0 +1,15 @@
+require 'test_helper'
+class PassThruDecompressorTest < MiniTest::Unit::TestCase
+  include DecompressorTests
+
+  def setup
+    super
+    @file = File.new(TEST_FILE)
+    @decompressor = ::Zip::PassThruDecompressor.new(@file, File.size(TEST_FILE))
+  end
+
+  def teardown
+    @file.close
+  end
+end
+
diff --git a/test/settings_test.rb b/test/settings_test.rb
new file mode 100644
index 0000000..95e882f
--- /dev/null
+++ b/test/settings_test.rb
@@ -0,0 +1,71 @@
+require 'test_helper'
+
+class ZipSettingsTest < MiniTest::Unit::TestCase
+  # TODO Refactor out into common test module
+  include CommonZipFileFixture
+  TEST_OUT_NAME = "emptyOutDir"
+
+  def setup
+    super
+
+    Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
+    File.delete(TEST_OUT_NAME) if File.exist? TEST_OUT_NAME
+  end
+
+  def open_zip(&aProc)
+    assert(aProc != nil)
+    ::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
+  end
+
+  def extract_test_dir(&aProc)
+    open_zip {
+        |zf|
+      zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
+    }
+  end
+
+  def test_true_on_exists_proc
+    Zip.on_exists_proc = true
+    File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
+    extract_test_dir
+    assert(File.directory?(TEST_OUT_NAME))
+  end
+
+  def test_false_on_exists_proc
+    Zip.on_exists_proc = false
+    File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
+    assert_raises(Zip::DestinationFileExistsError) { extract_test_dir }
+  end
+
+  def test_false_continue_on_exists_proc
+    Zip.continue_on_exists_proc = false
+
+    assert_raises(::Zip::EntryExistsError) do
+      ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+        zf.add(zf.entries.first.name, "test/data/file2.txt")
+      end
+    end
+  end
+
+  def test_true_continue_on_exists_proc
+    Zip.continue_on_exists_proc = true
+
+    replacedEntry = nil
+
+    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+      replacedEntry = zf.entries.first.name
+      zf.add(replacedEntry, "test/data/file2.txt")
+    end
+
+    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
+      assert_contains(zf, replacedEntry, "test/data/file2.txt")
+    end
+  end
+
+
+  private
+  def assert_contains(zf, entryName, filename = entryName)
+    assert(zf.entries.detect { |e| e.name == entryName } != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
+    assert_entryContents(zf, entryName, filename) if File.exist?(filename)
+  end
+end
diff --git a/test/test_helper.rb b/test/test_helper.rb
new file mode 100644
index 0000000..6e35477
--- /dev/null
+++ b/test/test_helper.rb
@@ -0,0 +1,228 @@
+require 'simplecov'
+require 'minitest/autorun'
+require 'minitest/unit'
+require 'fileutils'
+require 'digest/sha1'
+require 'zip'
+require 'gentestfiles'
+
+TestFiles.create_test_files
+TestZipFile.create_test_zips
+
+::MiniTest::Unit.after_tests do
+  FileUtils.rm_rf('test/data/generated')
+end
+
+module IOizeString
+  attr_reader :tell
+
+  def read(count = nil)
+    @tell ||= 0
+    count = size unless count
+    retVal = slice(@tell, count)
+    @tell += count
+    return retVal
+  end
+
+  def seek(index, offset)
+    @tell ||= 0
+    case offset
+    when IO::SEEK_END
+      newPos = size + index
+    when IO::SEEK_SET
+      newPos = index
+    when IO::SEEK_CUR
+      newPos = @tell + index
+    else
+      raise "Error in test method IOizeString::seek"
+    end
+    if (newPos < 0 || newPos >= size)
+      raise Errno::EINVAL
+    else
+      @tell=newPos
+    end
+  end
+
+  def reset
+    @tell = 0
+  end
+end
+
+module DecompressorTests
+  # expects @refText, @refLines and @decompressor
+
+  TEST_FILE = "test/data/file1.txt"
+
+  def setup
+    @refText = ''
+    File.open(TEST_FILE) { |f| @refText = f.read }
+    @refLines = @refText.split($/)
+  end
+
+  def test_readEverything
+    assert_equal(@refText, @decompressor.sysread)
+  end
+
+  def test_readInChunks
+    chunkSize = 5
+    while (decompressedChunk = @decompressor.sysread(chunkSize))
+      assert_equal(@refText.slice!(0, chunkSize), decompressedChunk)
+    end
+    assert_equal(0, @refText.size)
+  end
+
+  def test_mixingReadsAndProduceInput
+    # Just some preconditions to make sure we have enough data for this test
+    assert(@refText.length > 1000)
+    assert(@refLines.length > 40)
+
+
+    assert_equal(@refText[0...100], @decompressor.sysread(100))
+
+    assert(!@decompressor.input_finished?)
+    buf = @decompressor.produce_input
+    assert_equal(@refText[100...(100+buf.length)], buf)
+  end
+end
+
+
+
+module AssertEntry
+  def assert_next_entry(filename, zis)
+    assert_entry(filename, zis, zis.get_next_entry.name)
+  end
+
+  def assert_entry(filename, zis, entryName)
+    assert_equal(filename, entryName)
+    assert_entryContentsForStream(filename, zis, entryName)
+  end
+
+  def assert_entryContentsForStream(filename, zis, entryName)
+    File.open(filename, "rb") {
+        |file|
+      expected = file.read
+      actual = zis.read
+      if (expected != actual)
+        if ((expected && actual) && (expected.length > 400 || actual.length > 400))
+          zipEntryFilename=entryName+".zipEntry"
+          File.open(zipEntryFilename, "wb") { |entryfile| entryfile << actual }
+          fail("File '#{filename}' is different from '#{zipEntryFilename}'")
+        else
+          assert_equal(expected, actual)
+        end
+      end
+    }
+  end
+
+  def AssertEntry.assert_contents(filename, aString)
+    fileContents = ""
+    File.open(filename, "rb") { |f| fileContents = f.read }
+    if (fileContents != aString)
+      if (fileContents.length > 400 || aString.length > 400)
+        stringFile = filename + ".other"
+        File.open(stringFile, "wb") { |f| f << aString }
+        fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
+      else
+        assert_equal(fileContents, aString)
+      end
+    end
+  end
+
+  def assert_stream_contents(zis, testZipFile)
+    assert(zis != nil)
+    testZipFile.entry_names.each do |entryName|
+      assert_next_entry(entryName, zis)
+    end
+    assert_equal(nil, zis.get_next_entry)
+  end
+
+  def assert_test_zip_contents(testZipFile)
+    ::Zip::InputStream.open(testZipFile.zip_name) do |zis|
+      assert_stream_contents(zis, testZipFile)
+    end
+  end
+
+  def assert_entryContents(zipFile, entryName, filename = entryName.to_s)
+    zis = zipFile.get_input_stream(entryName)
+    assert_entryContentsForStream(filename, zis, entryName)
+  ensure
+    zis.close if zis
+  end
+end
+
+
+module CrcTest
+
+  class TestOutputStream
+    include ::Zip::IOExtras::AbstractOutputStream
+
+    attr_accessor :buffer
+
+    def initialize
+      @buffer = ""
+    end
+
+    def << (data)
+      @buffer << data
+      self
+    end
+  end
+
+  def run_crc_test(compressorClass)
+    str = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
+    fakeOut = TestOutputStream.new
+
+    deflater = compressorClass.new(fakeOut)
+    deflater << str
+    assert_equal(0x919920fc, deflater.crc)
+  end
+end
+
+
+module Enumerable
+  def compare_enumerables(otherEnumerable)
+    otherAsArray = otherEnumerable.to_a
+    each_with_index {
+        |element, index|
+      return false unless yield(element, otherAsArray[index])
+    }
+    return self.size == otherAsArray.size
+  end
+end
+
+
+module CommonZipFileFixture
+  include AssertEntry
+
+  EMPTY_FILENAME = "emptyZipFile.zip"
+
+  TEST_ZIP = TestZipFile::TEST_ZIP2.clone
+  TEST_ZIP.zip_name = "test/data/generated/5entry_copy.zip"
+
+  def setup
+    File.delete(EMPTY_FILENAME) if File.exist?(EMPTY_FILENAME)
+    FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
+  end
+end
+
+
+module ExtraAssertions
+
+  def assert_forwarded(anObject, method, retVal, *expectedArgs)
+    callArgs = nil
+    setCallArgsProc = proc { |args| callArgs = args }
+    anObject.instance_eval <<-"end_eval"
+      alias #{method}_org #{method}
+      def #{method}(*args)
+        ObjectSpace._id2ref(#{setCallArgsProc.object_id}).call(args)
+        ObjectSpace._id2ref(#{retVal.object_id})
+        end
+    end_eval
+
+    assert_equal(retVal, yield) # Invoke test
+    assert_equal(expectedArgs, callArgs)
+  ensure
+    anObject.instance_eval "undef #{method}; alias #{method} #{method}_org"
+  end
+
+end
diff --git a/test/unicode_file_names_and_comments.rb b/test/unicode_file_names_and_comments.rb
new file mode 100644
index 0000000..4738d25
--- /dev/null
+++ b/test/unicode_file_names_and_comments.rb
@@ -0,0 +1,38 @@
+require 'test_helper'
+
+class ZipUnicodeFileNamesAndComments < MiniTest::Unit::TestCase
+
+  FILENAME = File.join(File.dirname(__FILE__), "test1.zip")
+
+  def test_unicode
+    file_entrys = ["текстовыйфайл.txt", "Résumé.txt", "슬레이어스휘.txt"]
+    directory_entrys = ["папка/текстовыйфайл.txt", "Résumé/Résumé.txt", "슬레이어스휘/슬레이어스휘.txt"]
+    stream = ::Zip::OutputStream.open(FILENAME) do |io|
+      file_entrys.each do |filename|
+        io.put_next_entry(filename)
+        io.write(filename)
+      end
+      directory_entrys.each do |filepath|
+        io.put_next_entry(filepath)
+        io.write(filepath)
+      end
+    end
+    assert(!stream.nil?)
+    ::Zip::InputStream.open(FILENAME) do |io|
+      file_entrys.each do |filename|
+        entry = io.get_next_entry
+        entry_name = entry.name
+        entry_name = entry_name.force_encoding("UTF-8") if RUBY_VERSION >= '1.9'
+        assert(filename == entry_name)
+      end
+      directory_entrys.each do |filepath|
+        entry = io.get_next_entry
+        entry_name = entry.name
+        entry_name = entry_name.force_encoding("UTF-8") if RUBY_VERSION >= '1.9'
+        assert(filepath == entry_name)
+      end
+    end
+    ::File.unlink(FILENAME)
+  end
+
+end
diff --git a/test/zip64_full_test.rb b/test/zip64_full_test.rb
index f713fdf..1679b47 100644
--- a/test/zip64_full_test.rb
+++ b/test/zip64_full_test.rb
@@ -1,46 +1,49 @@
-require 'test/unit'
-require 'fileutils'
-require 'zip'
-
-Dir.chdir File.join(File.dirname(__FILE__))
-$VERBOSE = true
+if ENV['FULL_ZIP64_TEST']
+  require 'minitest/autorun'
+  require 'minitest/unit'
+  require 'fileutils'
+  require 'zip'
 
 # test zip64 support for real, by actually exceeding the 32-bit size/offset limits
 # this test does not, of course, run with the normal unit tests! ;)
 
-class Zip64FullTest < Test::Unit::TestCase
-  def prepareTestFile(test_filename)
-    File.delete(test_filename) if File.exists?(test_filename)
-    return test_filename
-  end
-
-  def test_largeZipFile
-    first_text = 'starting out small'
-    last_text = 'this tests files starting after 4GB in the archive'
-    test_filename = prepareTestFile('huge.zip')
-    Zip::OutputStream.open(test_filename) do |io|
-      io.put_next_entry('first_file.txt')
-      io.write(first_text)
-
-      # write just over 4GB (stored, so the zip file exceeds 4GB)
-      buf = 'blah' * 16384
-      io.put_next_entry('huge_file', nil, nil, Zip::Entry::STORED)
-      65537.times { io.write(buf) }
-
-      io.put_next_entry('last_file.txt')
-      io.write(last_text)
+  class Zip64FullTest < MiniTest::Unit::TestCase
+    def prepareTestFile(test_filename)
+      ::File.delete(test_filename) if ::File.exist?(test_filename)
+      return test_filename
     end
 
-    Zip::File.open(test_filename) do |zf|
-      assert_equal %w(first_file.txt huge_file last_file.txt), zf.entries.map(&:name)
-      assert_equal first_text, zf.read('first_file.txt')
-      assert_equal last_text, zf.read('last_file.txt')
+    def test_largeZipFile
+      ::Zip.write_zip64_support = true
+      first_text = 'starting out small'
+      last_text = 'this tests files starting after 4GB in the archive'
+      test_filename = prepareTestFile('huge.zip')
+      ::Zip::OutputStream.open(test_filename) do |io|
+        io.put_next_entry('first_file.txt')
+        io.write(first_text)
+
+        # write just over 4GB (stored, so the zip file exceeds 4GB)
+        buf = 'blah' * 16384
+        io.put_next_entry('huge_file', nil, nil, ::Zip::Entry::STORED)
+        65537.times { io.write(buf) }
+
+        io.put_next_entry('last_file.txt')
+        io.write(last_text)
+      end
+
+      ::Zip::File.open(test_filename) do |zf|
+        assert_equal %w(first_file.txt huge_file last_file.txt), zf.entries.map(&:name)
+        assert_equal first_text, zf.read('first_file.txt')
+        assert_equal last_text, zf.read('last_file.txt')
+      end
+
+      # note: if this fails, be sure you have UnZip version 6.0 or newer
+      # as this is the first version to support zip64 extensions
+      # but some OSes (*cough* OSX) still bundle a 5.xx release
+      assert system("unzip -t #{test_filename}"), "third-party zip validation failed"
     end
 
-    # note: if this fails, be sure you have UnZip version 6.0 or newer
-    # as this is the first version to support zip64 extensions
-    # but some OSes (*cough* OSX) still bundle a 5.xx release
-    assert system("unzip -t #{test_filename}"), "third-party zip validation failed"
   end
 
 end
+
diff --git a/test/zip64_support_test.rb b/test/zip64_support_test.rb
new file mode 100644
index 0000000..5f317cb
--- /dev/null
+++ b/test/zip64_support_test.rb
@@ -0,0 +1,15 @@
+require 'test_helper'
+
+class Zip64SupportTest < MiniTest::Unit::TestCase
+  TEST_FILE = File.join(File.dirname(__FILE__), 'data', 'zip64-sample.zip')
+
+  def test_open_zip64_file
+    zip_file = ::Zip::File.open(TEST_FILE)
+    assert(!zip_file.nil?)
+    assert(zip_file.entries.count == 2)
+    test_rb = zip_file.entries.find { |x| x.name == 'test.rb' }
+    assert(test_rb.size == 482)
+    assert(test_rb.compressed_size == 229)
+  end
+
+end
diff --git a/test/zipfilesystemtest.rb b/test/zipfilesystemtest.rb
deleted file mode 100755
index d62e72f..0000000
--- a/test/zipfilesystemtest.rb
+++ /dev/null
@@ -1,893 +0,0 @@
-#!/usr/bin/env ruby
-
-$VERBOSE = true
-
-$: << "../lib"
-
-require 'zip/filesystem'
-require 'test/unit'
-require 'fileutils'
-
-require 'digest/sha1'
-
-module ExtraAssertions
-
-  def assert_forwarded(anObject, method, retVal, *expectedArgs)
-    callArgs = nil
-    setCallArgsProc = proc { |args| callArgs = args }
-    anObject.instance_eval <<-"end_eval"
-      alias #{method}_org #{method}
-      def #{method}(*args)
-        ObjectSpace._id2ref(#{setCallArgsProc.object_id}).call(args)
-        ObjectSpace._id2ref(#{retVal.object_id})
-        end
-    end_eval
-
-    assert_equal(retVal, yield) # Invoke test
-    assert_equal(expectedArgs, callArgs)
-  ensure
-    anObject.instance_eval "undef #{method}; alias #{method} #{method}_org"
-  end
-
-end
-
-include Zip
-
-class ZipFsFileNonmutatingTest < Test::Unit::TestCase
-  def setup
-    @zipsha = Digest::SHA1.file("data/zipWithDirs.zip")
-    @zipFile = ::Zip::File.new("data/zipWithDirs.zip")
-  end
-
-  def teardown
-    @zipFile.close if @zipFile
-    assert_equal(@zipsha, Digest::SHA1.file("data/zipWithDirs.zip"))
-  end
-
-  def test_umask
-    assert_equal(::File.umask, @zipFile.file.umask)
-    @zipFile.file.umask(0006)
-  end
-
-  def test_exists?
-    assert(! @zipFile.file.exists?("notAFile"))
-    assert(@zipFile.file.exists?("file1"))
-    assert(@zipFile.file.exists?("dir1"))
-    assert(@zipFile.file.exists?("dir1/"))
-    assert(@zipFile.file.exists?("dir1/file12"))
-    assert(@zipFile.file.exist?("dir1/file12")) # notice, tests exist? alias of exists? !
-
-    @zipFile.dir.chdir "dir1/"
-    assert(!@zipFile.file.exists?("file1"))
-    assert(@zipFile.file.exists?("file12"))
-  end
-
-  def test_open_read
-    blockCalled = false
-    @zipFile.file.open("file1", "r") {
-      |f|
-      blockCalled = true
-      assert_equal("this is the entry 'file1' in my test archive!", 
-        f.readline.chomp)
-    }
-    assert(blockCalled)
-
-    blockCalled = false
-    @zipFile.file.open("file1", "rb") { # test binary flag is ignored
-      |f|
-      blockCalled = true
-      assert_equal("this is the entry 'file1' in my test archive!", 
-        f.readline.chomp)
-    }
-    assert(blockCalled)
-
-    blockCalled = false
-    @zipFile.dir.chdir "dir2"
-    @zipFile.file.open("file21", "r") {
-      |f|
-      blockCalled = true
-      assert_equal("this is the entry 'dir2/file21' in my test archive!", 
-        f.readline.chomp)
-    }
-    assert(blockCalled)
-    @zipFile.dir.chdir "/"
-
-    assert_raise(Errno::ENOENT) {
-      @zipFile.file.open("noSuchEntry")
-    }
-
-    begin
-      is = @zipFile.file.open("file1")
-      assert_equal("this is the entry 'file1' in my test archive!", 
-        is.readline.chomp)
-    ensure
-      is.close if is
-    end
-  end
-
-  def test_new
-    begin
-      is = @zipFile.file.new("file1")
-      assert_equal("this is the entry 'file1' in my test archive!", 
-        is.readline.chomp)
-    ensure
-      is.close if is
-    end
-    begin
-      is = @zipFile.file.new("file1") {
-  fail "should not call block"
-      }
-    ensure
-      is.close if is
-    end
-  end
-
-  def test_symlink
-    assert_raise(NotImplementedError) {
-      @zipFile.file.symlink("file1", "aSymlink")
-    }
-  end
-
-  def test_size
-    assert_raise(Errno::ENOENT) { @zipFile.file.size("notAFile") }
-    assert_equal(72, @zipFile.file.size("file1"))
-    assert_equal(0, @zipFile.file.size("dir2/dir21"))
-
-    assert_equal(72, @zipFile.file.stat("file1").size)
-    assert_equal(0, @zipFile.file.stat("dir2/dir21").size)
-  end
-
-  def test_size?
-    assert_equal(nil, @zipFile.file.size?("notAFile"))
-    assert_equal(72, @zipFile.file.size?("file1"))
-    assert_equal(nil, @zipFile.file.size?("dir2/dir21"))
-
-    assert_equal(72, @zipFile.file.stat("file1").size?)
-    assert_equal(nil, @zipFile.file.stat("dir2/dir21").size?)
-  end
-
-
-  def test_file?
-    assert(@zipFile.file.file?("file1"))
-    assert(@zipFile.file.file?("dir2/file21"))
-    assert(! @zipFile.file.file?("dir1"))
-    assert(! @zipFile.file.file?("dir1/dir11"))
-
-    assert(@zipFile.file.stat("file1").file?)
-    assert(@zipFile.file.stat("dir2/file21").file?)
-    assert(! @zipFile.file.stat("dir1").file?)
-    assert(! @zipFile.file.stat("dir1/dir11").file?)
-  end
-
-  include ExtraAssertions
-
-  def test_dirname
-    assert_forwarded(File, :dirname, "retVal", "a/b/c/d") { 
-      @zipFile.file.dirname("a/b/c/d")
-    }
-  end
-
-  def test_basename
-    assert_forwarded(File, :basename, "retVal", "a/b/c/d") { 
-      @zipFile.file.basename("a/b/c/d")
-    }
-  end
-
-  def test_split
-    assert_forwarded(File, :split, "retVal", "a/b/c/d") { 
-      @zipFile.file.split("a/b/c/d")
-    }
-  end
-
-  def test_join
-    assert_equal("a/b/c", @zipFile.file.join("a/b", "c"))
-    assert_equal("a/b/c/d", @zipFile.file.join("a/b", "c/d"))
-    assert_equal("/c/d", @zipFile.file.join("", "c/d"))
-    assert_equal("a/b/c/d", @zipFile.file.join("a", "b", "c", "d"))
-  end
-
-  def test_utime
-    t_now = DOSTime.now
-    t_bak = @zipFile.file.mtime("file1")
-    @zipFile.file.utime(t_now, "file1")
-    assert_equal(t_now, @zipFile.file.mtime("file1"))
-    @zipFile.file.utime(t_bak, "file1")
-    assert_equal(t_bak, @zipFile.file.mtime("file1"))
-  end
-
-
-  def assert_always_false(operation)
-    assert(! @zipFile.file.send(operation, "noSuchFile"))
-    assert(! @zipFile.file.send(operation, "file1"))
-    assert(! @zipFile.file.send(operation, "dir1"))
-    assert(! @zipFile.file.stat("file1").send(operation))
-    assert(! @zipFile.file.stat("dir1").send(operation))
-  end
-
-  def assert_true_if_entry_exists(operation)
-    assert(! @zipFile.file.send(operation, "noSuchFile"))
-    assert(@zipFile.file.send(operation, "file1"))
-    assert(@zipFile.file.send(operation, "dir1"))
-    assert(@zipFile.file.stat("file1").send(operation))
-    assert(@zipFile.file.stat("dir1").send(operation))
-  end
-
-  def test_pipe?
-    assert_always_false(:pipe?)
-  end
-
-  def test_blockdev?
-    assert_always_false(:blockdev?)
-  end
-
-  def test_symlink?
-    assert_always_false(:symlink?)
-  end
-
-  def test_socket?
-    assert_always_false(:socket?)
-  end
-
-  def test_chardev?
-    assert_always_false(:chardev?)
-  end
-
-  def test_truncate
-    assert_raise(StandardError, "truncate not supported") {
-      @zipFile.file.truncate("file1", 100)
-    }
-  end
-
-  def assert_e_n_o_e_n_t(operation, args = ["NoSuchFile"])
-    assert_raise(Errno::ENOENT) {
-      @zipFile.file.send(operation, *args)
-    }
-  end
-
-  def test_ftype
-    assert_e_n_o_e_n_t(:ftype)
-    assert_equal("file", @zipFile.file.ftype("file1"))
-    assert_equal("directory", @zipFile.file.ftype("dir1/dir11"))
-    assert_equal("directory", @zipFile.file.ftype("dir1/dir11/"))
-  end
-
-  def test_link
-    assert_raise(NotImplementedError) {
-      @zipFile.file.link("file1", "someOtherString")
-    }
-  end
-
-  def test_directory?
-    assert(! @zipFile.file.directory?("notAFile"))
-    assert(! @zipFile.file.directory?("file1"))
-    assert(! @zipFile.file.directory?("dir1/file11"))
-    assert(@zipFile.file.directory?("dir1"))
-    assert(@zipFile.file.directory?("dir1/"))
-    assert(@zipFile.file.directory?("dir2/dir21"))
-
-    assert(! @zipFile.file.stat("file1").directory?)
-    assert(! @zipFile.file.stat("dir1/file11").directory?)
-    assert(@zipFile.file.stat("dir1").directory?)
-    assert(@zipFile.file.stat("dir1/").directory?)
-    assert(@zipFile.file.stat("dir2/dir21").directory?)
-  end
-
-  def test_chown
-    assert_equal(2, @zipFile.file.chown(1,2, "dir1", "file1"))
-    assert_equal(1, @zipFile.file.stat("dir1").uid)
-    assert_equal(2, @zipFile.file.stat("dir1").gid)
-    assert_equal(2, @zipFile.file.chown(nil, nil, "dir1", "file1"))
-  end
-
-  def test_zero?
-    assert(! @zipFile.file.zero?("notAFile"))
-    assert(! @zipFile.file.zero?("file1"))
-    assert(@zipFile.file.zero?("dir1"))
-    blockCalled = false
-    ::Zip::File.open("data/generated/5entry.zip") {
-      |zf|
-      blockCalled = true
-      assert(zf.file.zero?("data/generated/empty.txt"))
-    }
-    assert(blockCalled)
-
-    assert(! @zipFile.file.stat("file1").zero?)
-    assert(@zipFile.file.stat("dir1").zero?)
-    blockCalled = false
-    ::Zip::File.open("data/generated/5entry.zip") {
-      |zf|
-      blockCalled = true
-      assert(zf.file.stat("data/generated/empty.txt").zero?)
-    }
-    assert(blockCalled)
-  end
-
-  def test_expand_path
-    ::Zip::File.open("data/zipWithDirs.zip") {
-      |zf|
-      assert_equal("/", zf.file.expand_path("."))
-      zf.dir.chdir "dir1"
-      assert_equal("/dir1", zf.file.expand_path("."))
-      assert_equal("/dir1/file12", zf.file.expand_path("file12"))
-      assert_equal("/", zf.file.expand_path(".."))
-      assert_equal("/dir2/dir21", zf.file.expand_path("../dir2/dir21"))
-    }
-  end
-
-  def test_mtime
-    assert_equal(DOSTime.at(1027694306),
-      @zipFile.file.mtime("dir2/file21"))
-    assert_equal(DOSTime.at(1027690863),
-      @zipFile.file.mtime("dir2/dir21"))
-    assert_raise(Errno::ENOENT) {
-      @zipFile.file.mtime("noSuchEntry")
-    }
-
-    assert_equal(DOSTime.at(1027694306),
-      @zipFile.file.stat("dir2/file21").mtime)
-    assert_equal(DOSTime.at(1027690863),
-      @zipFile.file.stat("dir2/dir21").mtime)
-  end
-
-  def test_ctime
-    assert_nil(@zipFile.file.ctime("file1"))
-    assert_nil(@zipFile.file.stat("file1").ctime)
-  end
-
-  def test_atime
-    assert_nil(@zipFile.file.atime("file1"))
-    assert_nil(@zipFile.file.stat("file1").atime)
-  end
-
-  def test_readable?
-    assert(! @zipFile.file.readable?("noSuchFile"))
-    assert(@zipFile.file.readable?("file1"))
-    assert(@zipFile.file.readable?("dir1"))
-    assert(@zipFile.file.stat("file1").readable?)
-    assert(@zipFile.file.stat("dir1").readable?)
-  end
-
-  def test_readable_real?
-    assert(! @zipFile.file.readable_real?("noSuchFile"))
-    assert(@zipFile.file.readable_real?("file1"))
-    assert(@zipFile.file.readable_real?("dir1"))
-    assert(@zipFile.file.stat("file1").readable_real?)
-    assert(@zipFile.file.stat("dir1").readable_real?)
-  end
-
-  def test_writable?
-    assert(! @zipFile.file.writable?("noSuchFile"))
-    assert(@zipFile.file.writable?("file1"))
-    assert(@zipFile.file.writable?("dir1"))
-    assert(@zipFile.file.stat("file1").writable?)
-    assert(@zipFile.file.stat("dir1").writable?)
-  end
-
-  def test_writable_real?
-    assert(! @zipFile.file.writable_real?("noSuchFile"))
-    assert(@zipFile.file.writable_real?("file1"))
-    assert(@zipFile.file.writable_real?("dir1"))
-    assert(@zipFile.file.stat("file1").writable_real?)
-    assert(@zipFile.file.stat("dir1").writable_real?)
-  end
-
-  def test_executable?
-    assert(! @zipFile.file.executable?("noSuchFile"))
-    assert(! @zipFile.file.executable?("file1"))
-    assert(@zipFile.file.executable?("dir1"))
-    assert(! @zipFile.file.stat("file1").executable?)
-    assert(@zipFile.file.stat("dir1").executable?)
-  end
-
-  def test_executable_real?
-    assert(! @zipFile.file.executable_real?("noSuchFile"))
-    assert(! @zipFile.file.executable_real?("file1"))
-    assert(@zipFile.file.executable_real?("dir1"))
-    assert(! @zipFile.file.stat("file1").executable_real?)
-    assert(@zipFile.file.stat("dir1").executable_real?)
-  end
-
-  def test_owned?
-    assert_true_if_entry_exists(:owned?)
-  end
-
-  def test_grpowned?
-    assert_true_if_entry_exists(:grpowned?)
-  end
-
-  def test_setgid?
-    assert_always_false(:setgid?)
-  end
-
-  def test_setuid?
-    assert_always_false(:setgid?)
-  end
-
-  def test_sticky?
-    assert_always_false(:sticky?)
-  end
-
-  def test_readlink
-    assert_raise(NotImplementedError) {
-      @zipFile.file.readlink("someString")
-    }
-  end
-
-  def test_stat
-    s = @zipFile.file.stat("file1")
-    assert(s.kind_of?(File::Stat)) # It pretends
-    assert_raise(Errno::ENOENT, "No such file or directory - noSuchFile") {
-      @zipFile.file.stat("noSuchFile")
-    }
-  end
-
-  def test_lstat
-    assert(@zipFile.file.lstat("file1").file?)
-  end
-
-  def test_pipe
-    assert_raise(NotImplementedError) {
-      @zipFile.file.pipe
-    }
-  end
-
-  def test_foreach
-    ::Zip::File.open("data/generated/zipWithDir.zip") do |zf|
-      ref = []
-      File.foreach("data/file1.txt") { |e| ref << e }
-      index = 0
-
-      zf.file.foreach("data/file1.txt") do |l|
-        #Ruby replaces \n with \r\n automatically on windows
-        newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l
-        assert_equal(ref[index], newline)
-        index = index.next
-      end
-      assert_equal(ref.size, index)
-    end
-
-    ::Zip::File.open("data/generated/zipWithDir.zip") do |zf|
-      ref = []
-      File.foreach("data/file1.txt", " ") { |e| ref << e }
-      index = 0
-
-      zf.file.foreach("data/file1.txt", " ") do |l|
-        #Ruby replaces \n with \r\n automatically on windows
-        newline = Zip::RUNNING_ON_WINDOWS ? l.gsub(/\r\n/, "\n") : l
-        assert_equal(ref[index], newline)
-        index = index.next
-      end
-      assert_equal(ref.size, index)
-    end
-  end
-
-  def test_glob
-    ::Zip::File.open('data/globTest.zip') do |zf|
-      {
-        'globTest/foo.txt' => ['globTest/foo.txt'],
-        '*/foo.txt' => ['globTest/foo.txt'],
-        '**/foo.txt' => ['globTest/foo.txt','globTest/foo/bar/baz/foo.txt'],
-        '*/foo/**/*.txt' => ['globTest/foo/bar/baz/foo.txt']
-      }.each do |spec,expected_results|
-        results = zf.glob(spec)
-        assert results.all?{|entry| entry.is_a? ::Zip::Entry }
-
-        result_strings = results.map(&:to_s)
-        missing_matches = expected_results - result_strings
-        extra_matches = result_strings - expected_results
-
-        assert extra_matches.empty?, %Q{spec #{spec.inspect} has extra results #{extra_matches.inspect}}
-        assert missing_matches.empty?, %Q{spec #{spec.inspect} missing results #{missing_matches.inspect}}
-      end
-    end
-
-    ::Zip::File.open('data/globTest.zip') do |zf|
-      results = []
-      zf.glob('**/foo.txt') do |match|
-        results << "<#{match.class.name}: #{match.to_s}>"
-      end
-      assert((not results.empty?), 'block not run, or run out of context')
-      assert_equal 2, results.size
-      assert_operator results, :include?, '<Zip::Entry: globTest/foo.txt>'
-      assert_operator results, :include?, '<Zip::Entry: globTest/foo/bar/baz/foo.txt>'
-    end
-  end
-
-  def test_popen
-    if Zip::RUNNING_ON_WINDOWS
-      #This is pretty much projectile vomit but it allows the test to be
-      #run on windows also
-      system_dir = ::File.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '')
-      zipfile_dir = @zipFile.file.popen('dir') { |f| f.read }.gsub(/Dir\(s\).*$/, '')
-      assert_equal(system_dir, zipfile_dir)
-    else
-      assert_equal(::File.popen('ls') { |f| f.read },
-                   @zipFile.file.popen('ls') { |f| f.read })
-    end
-  end
-
-# Can be added later
-#  def test_select
-#    fail "implement test"
-#  end
-
-  def test_readlines
-    ::Zip::File.open("data/generated/zipWithDir.zip") do |zf|
-      orig_file = ::File.readlines("data/file1.txt")
-      zip_file = zf.file.readlines("data/file1.txt")
-
-      #Ruby replaces \n with \r\n automatically on windows
-      zip_file.each { |l| l.gsub!(/\r\n/, "\n") } if Zip::RUNNING_ON_WINDOWS
-
-      assert_equal(orig_file, zip_file)
-    end
-  end
-
-  def test_read
-    ::Zip::File.open("data/generated/zipWithDir.zip") do |zf|
-      orig_file = ::File.read("data/file1.txt")
-
-      #Ruby replaces \n with \r\n automatically on windows
-      zip_file = Zip::RUNNING_ON_WINDOWS ? \
-          zf.file.read("data/file1.txt").gsub(/\r\n/, "\n") : zf.file.read("data/file1.txt")
-      assert_equal(orig_file, zip_file)
-    end
-  end
-
-end
-
-class ZipFsFileStatTest < Test::Unit::TestCase
-
-  def setup
-    @zipFile = ::Zip::File.new("data/zipWithDirs.zip")
-  end
-
-  def teardown
-    @zipFile.close if @zipFile
-  end
-
-  def test_blocks
-    assert_equal(nil, @zipFile.file.stat("file1").blocks)
-  end
-
-  def test_ino
-    assert_equal(0, @zipFile.file.stat("file1").ino)
-  end
-
-  def test_uid
-    assert_equal(0, @zipFile.file.stat("file1").uid)
-  end
-
-  def test_gid
-    assert_equal(0, @zipFile.file.stat("file1").gid)
-  end
-
-  def test_ftype
-    assert_equal("file", @zipFile.file.stat("file1").ftype)
-    assert_equal("directory", @zipFile.file.stat("dir1").ftype)
-  end
-
-  def test_mode
-    assert_equal(0600, @zipFile.file.stat("file1").mode & 0777)
-    assert_equal(0600, @zipFile.file.stat("file1").mode & 0777)
-    assert_equal(0755, @zipFile.file.stat("dir1").mode & 0777)
-    assert_equal(0755, @zipFile.file.stat("dir1").mode & 0777)
-  end
-
-  def test_dev
-    assert_equal(0, @zipFile.file.stat("file1").dev)
-  end
-
-  def test_rdev
-    assert_equal(0, @zipFile.file.stat("file1").rdev)
-  end
-
-  def test_rdev_major
-    assert_equal(0, @zipFile.file.stat("file1").rdev_major)
-  end
-
-  def test_rdev_minor
-    assert_equal(0, @zipFile.file.stat("file1").rdev_minor)
-  end
-
-  def test_nlink
-    assert_equal(1, @zipFile.file.stat("file1").nlink)
-  end
-
-  def test_blksize
-    assert_nil(@zipFile.file.stat("file1").blksize)
-  end
-
-end
-
-class ZipFsFileMutatingTest < Test::Unit::TestCase
-  TEST_ZIP = "zipWithDirs_copy.zip"
-  def setup
-    FileUtils.cp("data/zipWithDirs.zip", TEST_ZIP)
-  end
-
-  def teardown
-  end
-
-  def test_delete
-    do_test_delete_or_unlink(:delete)
-  end
-
-  def test_unlink
-    do_test_delete_or_unlink(:unlink)
-  end
-
-  def test_open_write
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-
-      zf.file.open("test_open_write_entry", "w") {
-        |f|
-        f.write "This is what I'm writing"
-      }
-      assert_equal("This is what I'm writing",
-                    zf.file.read("test_open_write_entry"))
-
-      # Test with existing entry
-      zf.file.open("file1", "wb") { #also check that 'b' option is ignored
-        |f|
-        f.write "This is what I'm writing too"
-      }
-      assert_equal("This is what I'm writing too",
-                    zf.file.read("file1"))
-    }
-  end
-
-  def test_rename
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-      assert_raise(Errno::ENOENT, "") { 
-        zf.file.rename("NoSuchFile", "bimse")
-      }
-      zf.file.rename("file1", "newNameForFile1")
-    }
-
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-      assert(! zf.file.exists?("file1"))
-      assert(zf.file.exists?("newNameForFile1"))
-    }
-  end
-
-  def test_chmod
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-
-      zf.file.chmod(0765, "file1")
-    }
-
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-      assert_equal(0100765,  zf.file.stat("file1").mode)
-    }
-  end
-
-  def do_test_delete_or_unlink(symbol)
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-      assert(zf.file.exists?("dir2/dir21/dir221/file2221"))
-      zf.file.send(symbol, "dir2/dir21/dir221/file2221")
-      assert(! zf.file.exists?("dir2/dir21/dir221/file2221"))
-
-      assert(zf.file.exists?("dir1/file11"))
-      assert(zf.file.exists?("dir1/file12"))
-      zf.file.send(symbol, "dir1/file11", "dir1/file12")
-      assert(! zf.file.exists?("dir1/file11"))
-      assert(! zf.file.exists?("dir1/file12"))
-
-      assert_raise(Errno::ENOENT) { zf.file.send(symbol, "noSuchFile") }
-      assert_raise(Errno::EISDIR) { zf.file.send(symbol, "dir1/dir11") }
-      assert_raise(Errno::EISDIR) { zf.file.send(symbol, "dir1/dir11/") }
-    }
-
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-      assert(! zf.file.exists?("dir2/dir21/dir221/file2221"))
-      assert(! zf.file.exists?("dir1/file11"))
-      assert(! zf.file.exists?("dir1/file12"))
-
-      assert(zf.file.exists?("dir1/dir11"))
-      assert(zf.file.exists?("dir1/dir11/"))
-    }
-  end
-
-end
-
-class ZipFsDirectoryTest < Test::Unit::TestCase
-  TEST_ZIP = "zipWithDirs_copy.zip"
-
-  def setup
-    FileUtils.cp("data/zipWithDirs.zip", TEST_ZIP)
-  end
-
-  def test_delete
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-      assert_raise(Errno::ENOENT, "No such file or directory - NoSuchFile.txt") {
-        zf.dir.delete("NoSuchFile.txt")
-      }
-      assert_raise(Errno::EINVAL, "Invalid argument - file1") {
-        zf.dir.delete("file1")
-      }
-      assert(zf.file.exists?("dir1"))
-      zf.dir.delete("dir1")
-      assert(! zf.file.exists?("dir1"))
-    }
-  end
-
-  def test_mkdir
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-      assert_raise(Errno::EEXIST, "File exists - dir1") { 
-        zf.dir.mkdir("file1") 
-      }
-      assert_raise(Errno::EEXIST, "File exists - dir1") { 
-        zf.dir.mkdir("dir1") 
-      }
-      assert(!zf.file.exists?("newDir"))
-      zf.dir.mkdir("newDir")
-      assert(zf.file.directory?("newDir"))
-      assert(!zf.file.exists?("newDir2"))
-      zf.dir.mkdir("newDir2", 3485)
-      assert(zf.file.directory?("newDir2"))
-    }
-  end
-
-  def test_pwd_chdir_entries
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-      assert_equal("/", zf.dir.pwd)
-
-      assert_raise(Errno::ENOENT, "No such file or directory - no such dir") {
-        zf.dir.chdir "no such dir"
-      }
-
-      assert_raise(Errno::EINVAL, "Invalid argument - file1") {
-        zf.dir.chdir "file1"
-      }
-
-      assert_equal(["dir1", "dir2", "file1"].sort, zf.dir.entries(".").sort)
-      zf.dir.chdir "dir1"
-      assert_equal("/dir1", zf.dir.pwd)
-      assert_equal(["dir11", "file11", "file12"], zf.dir.entries(".").sort)
-
-      zf.dir.chdir "../dir2/dir21"
-      assert_equal("/dir2/dir21", zf.dir.pwd)
-      assert_equal(["dir221"].sort, zf.dir.entries(".").sort)
-    }
-  end
-
-  def test_foreach
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-
-      blockCalled = false
-      assert_raise(Errno::ENOENT, "No such file or directory - noSuchDir") {
-        zf.dir.foreach("noSuchDir") { |e| blockCalled = true }
-      }
-      assert(! blockCalled)
-
-      assert_raise(Errno::ENOTDIR, "Not a directory - file1") {
-        zf.dir.foreach("file1") { |e| blockCalled = true }
-      }
-      assert(! blockCalled)
-
-      entries = []
-      zf.dir.foreach(".") { |e| entries << e }
-      assert_equal(["dir1", "dir2", "file1"].sort, entries.sort)
-
-      entries = []
-      zf.dir.foreach("dir1") { |e| entries << e }
-      assert_equal(["dir11", "file11", "file12"], entries.sort)
-    }
-  end
-
-  def test_chroot
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-      assert_raise(NotImplementedError) {
-        zf.dir.chroot
-      }
-    }
-  end
-
-  # Globbing not supported yet
-  #def test_glob
-  #  # test alias []-operator too
-  #  fail "implement test"
-  #end
-
-  def test_open_new
-    ::Zip::File.open(TEST_ZIP) {
-      |zf|
-
-      assert_raise(Errno::ENOTDIR, "Not a directory - file1") {
-        zf.dir.new("file1")
-      }
-
-      assert_raise(Errno::ENOENT, "No such file or directory - noSuchFile") {
-        zf.dir.new("noSuchFile")
-      }
-
-      d = zf.dir.new(".")
-      assert_equal(["file1", "dir1", "dir2"].sort, d.entries.sort)
-      d.close
-
-      zf.dir.open("dir1") {
-        |dir|
-        assert_equal(["dir11", "file11", "file12"].sort, dir.entries.sort)
-      }
-    }
-  end
-
-end
-
-class ZipFsDirIteratorTest < Test::Unit::TestCase
-
-  FILENAME_ARRAY = [ "f1", "f2", "f3", "f4", "f5", "f6"  ]
-
-  def setup
-    @dirIt = ::Zip::FileSystem::ZipFsDirIterator.new(FILENAME_ARRAY)
-  end
-
-  def test_close
-    @dirIt.close
-    assert_raise(IOError, "closed directory") {
-      @dirIt.each { |e| p e }
-    }
-    assert_raise(IOError, "closed directory") {
-      @dirIt.read
-    }
-    assert_raise(IOError, "closed directory") {
-      @dirIt.rewind
-    }
-    assert_raise(IOError, "closed directory") {
-      @dirIt.seek(0)
-    }
-    assert_raise(IOError, "closed directory") {
-      @dirIt.tell
-    }
-
-  end
-
-  def test_each 
-    # Tested through Enumerable.entries
-    assert_equal(FILENAME_ARRAY, @dirIt.entries)
-  end
-
-  def test_read
-    FILENAME_ARRAY.size.times {
-      |i|
-      assert_equal(FILENAME_ARRAY[i], @dirIt.read)
-    }
-  end
-
-  def test_rewind
-    @dirIt.read
-    @dirIt.read
-    assert_equal(FILENAME_ARRAY[2], @dirIt.read)
-    @dirIt.rewind
-    assert_equal(FILENAME_ARRAY[0], @dirIt.read)
-  end
-
-  def test_tell_seek
-    @dirIt.read
-    @dirIt.read
-    pos = @dirIt.tell
-    valAtPos = @dirIt.read
-    @dirIt.read
-    @dirIt.seek(pos)
-    assert_equal(valAtPos, @dirIt.read)
-  end
-
-end
-
-
-# Copyright (C) 2002, 2003 Thomas Sondergaard
-# rubyzip is free software; you can redistribute it and/or
-# modify it under the terms of the ruby license.
diff --git a/test/ziptest.rb b/test/ziptest.rb
deleted file mode 100755
index f17a810..0000000
--- a/test/ziptest.rb
+++ /dev/null
@@ -1,2075 +0,0 @@
-#!/usr/bin/env ruby
-# encoding: utf-8
-
-$VERBOSE = true
-
-$: << "../lib"
-
-require 'test/unit'
-require 'fileutils'
-require 'zip'
-require 'stringio'
-require 'gentestfiles'
-
-class ZipEntryTest < Test::Unit::TestCase
-  TEST_ZIPFILE           = "someZipFile.zip"
-  TEST_COMMENT           = "a comment"
-  TEST_COMPRESSED_SIZE   = 1234
-  TEST_CRC               = 325324
-  TEST_EXTRA             = "Some data here"
-  TEST_COMPRESSIONMETHOD = ::Zip::Entry::DEFLATED
-  TEST_NAME              = "entry name"
-  TEST_SIZE              = 8432
-  TEST_ISDIRECTORY       = false
-  TEST_TIME              = Time.now
-
-  def test_constructorAndGetters
-    entry = ::Zip::Entry.new(TEST_ZIPFILE,
-                             TEST_NAME,
-                             TEST_COMMENT,
-                             TEST_EXTRA,
-                             TEST_COMPRESSED_SIZE,
-                             TEST_CRC,
-                             TEST_COMPRESSIONMETHOD,
-                             TEST_SIZE,
-                             TEST_TIME)
-
-    assert_equal(TEST_COMMENT, entry.comment)
-    assert_equal(TEST_COMPRESSED_SIZE, entry.compressed_size)
-    assert_equal(TEST_CRC, entry.crc)
-    assert_instance_of(::Zip::ExtraField, entry.extra)
-    assert_equal(TEST_COMPRESSIONMETHOD, entry.compression_method)
-    assert_equal(TEST_NAME, entry.name)
-    assert_equal(TEST_SIZE, entry.size)
-    assert_equal(TEST_TIME, entry.time)
-  end
-
-  def test_is_directoryAndIsFile
-    assert(::Zip::Entry.new(TEST_ZIPFILE, "hello").file?)
-    assert(!::Zip::Entry.new(TEST_ZIPFILE, "hello").directory?)
-
-    assert(::Zip::Entry.new(TEST_ZIPFILE, "dir/hello").file?)
-    assert(!::Zip::Entry.new(TEST_ZIPFILE, "dir/hello").directory?)
-
-    assert(::Zip::Entry.new(TEST_ZIPFILE, "hello/").directory?)
-    assert(!::Zip::Entry.new(TEST_ZIPFILE, "hello/").file?)
-
-    assert(::Zip::Entry.new(TEST_ZIPFILE, "dir/hello/").directory?)
-    assert(!::Zip::Entry.new(TEST_ZIPFILE, "dir/hello/").file?)
-  end
-
-  def test_equality
-    entry1 = ::Zip::Entry.new("file.zip", "name", "isNotCompared",
-                              "something extra", 123, 1234,
-                              ::Zip::Entry::DEFLATED, 10000)
-    entry2 = ::Zip::Entry.new("file.zip", "name", "isNotComparedXXX",
-                              "something extra", 123, 1234,
-                              ::Zip::Entry::DEFLATED, 10000)
-    entry3 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
-                              "something extra", 123, 1234,
-                              ::Zip::Entry::DEFLATED, 10000)
-    entry4 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
-                              "something extraXX", 123, 1234,
-                              ::Zip::Entry::DEFLATED, 10000)
-    entry5 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
-                              "something extraXX", 12, 1234,
-                              ::Zip::Entry::DEFLATED, 10000)
-    entry6 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
-                              "something extraXX", 12, 123,
-                              ::Zip::Entry::DEFLATED, 10000)
-    entry7 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
-                              "something extraXX", 12, 123,
-                              ::Zip::Entry::STORED, 10000)
-    entry8 = ::Zip::Entry.new("file.zip", "name2", "isNotComparedXXX",
-                              "something extraXX", 12, 123,
-                              ::Zip::Entry::STORED, 100000)
-
-    assert_equal(entry1, entry1)
-    assert_equal(entry1, entry2)
-
-    assert(entry2 != entry3)
-    assert(entry3 != entry4)
-    assert(entry4 != entry5)
-    assert(entry5 != entry6)
-    assert(entry6 != entry7)
-    assert(entry7 != entry8)
-
-    assert(entry7 != "hello")
-    assert(entry7 != 12)
-  end
-
-  def test_compare
-    assert_equal(0, (::Zip::Entry.new("zf.zip", "a") <=> ::Zip::Entry.new("zf.zip", "a")))
-    assert_equal(1, (::Zip::Entry.new("zf.zip", "b") <=> ::Zip::Entry.new("zf.zip", "a")))
-    assert_equal(-1, (::Zip::Entry.new("zf.zip", "a") <=> ::Zip::Entry.new("zf.zip", "b")))
-
-    entries = [
-      ::Zip::Entry.new("zf.zip", "5"),
-      ::Zip::Entry.new("zf.zip", "1"),
-      ::Zip::Entry.new("zf.zip", "3"),
-      ::Zip::Entry.new("zf.zip", "4"),
-      ::Zip::Entry.new("zf.zip", "0"),
-      ::Zip::Entry.new("zf.zip", "2")
-    ]
-
-    entries.sort!
-    assert_equal("0", entries[0].to_s)
-    assert_equal("1", entries[1].to_s)
-    assert_equal("2", entries[2].to_s)
-    assert_equal("3", entries[3].to_s)
-    assert_equal("4", entries[4].to_s)
-    assert_equal("5", entries[5].to_s)
-  end
-
-  def test_parentAsString
-    entry1 = ::Zip::Entry.new("zf.zip", "aa")
-    entry2 = ::Zip::Entry.new("zf.zip", "aa/")
-    entry3 = ::Zip::Entry.new("zf.zip", "aa/bb")
-    entry4 = ::Zip::Entry.new("zf.zip", "aa/bb/")
-    entry5 = ::Zip::Entry.new("zf.zip", "aa/bb/cc")
-    entry6 = ::Zip::Entry.new("zf.zip", "aa/bb/cc/")
-
-    assert_equal(nil, entry1.parent_as_string)
-    assert_equal(nil, entry2.parent_as_string)
-    assert_equal("aa/", entry3.parent_as_string)
-    assert_equal("aa/", entry4.parent_as_string)
-    assert_equal("aa/bb/", entry5.parent_as_string)
-    assert_equal("aa/bb/", entry6.parent_as_string)
-  end
-
-  def test_entry_name_cannot_start_with_slash
-    assert_raise(ZipEntryNameError) { ::Zip::Entry.new("zf.zip", "/hej/der") }
-  end
-end
-
-module IOizeString
-  attr_reader :tell
-
-  def read(count = nil)
-    @tell ||= 0
-    count = size unless count
-    retVal = slice(@tell, count)
-    @tell  += count
-    return retVal
-  end
-
-  def seek(index, offset)
-    @tell ||= 0
-    case offset
-    when IO::SEEK_END
-      newPos = size + index
-    when IO::SEEK_SET
-      newPos = index
-    when IO::SEEK_CUR
-      newPos = @tell + index
-    else
-      raise "Error in test method IOizeString::seek"
-    end
-    if (newPos < 0 || newPos >= size)
-      raise Errno::EINVAL
-    else
-      @tell=newPos
-    end
-  end
-
-  def reset
-    @tell = 0
-  end
-end
-
-class ZipLocalEntryTest < Test::Unit::TestCase
-  def test_read_local_entryHeaderOfFirstTestZipEntry
-    ::File.open(TestZipFile::TEST_ZIP3.zip_name, "rb") {
-      |file|
-      entry = ::Zip::Entry.read_local_entry(file)
-
-      assert_equal('', entry.comment)
-      # Differs from windows and unix because of CR LF
-      # assert_equal(480, entry.compressed_size)
-      # assert_equal(0x2a27930f, entry.crc)
-      # extra field is 21 bytes long
-      # probably contains some unix attrutes or something
-      # disabled: assert_equal(nil, entry.extra)
-      assert_equal(::Zip::Entry::DEFLATED, entry.compression_method)
-      assert_equal(TestZipFile::TEST_ZIP3.entry_names[0], entry.name)
-      assert_equal(::File.size(TestZipFile::TEST_ZIP3.entry_names[0]), entry.size)
-      assert(!entry.directory?)
-    }
-  end
-
-  def test_readDateTime
-    ::File.open("data/rubycode.zip", "rb") {
-      |file|
-      entry = ::Zip::Entry.read_local_entry(file)
-      assert_equal("zippedruby1.rb", entry.name)
-      assert_equal(::Zip::DOSTime.at(1019261638), entry.time)
-    }
-  end
-
-  def test_read_local_entryFromNonZipFile
-    ::File.open("data/file2.txt") {
-      |file|
-      assert_equal(nil, ::Zip::Entry.read_local_entry(file))
-    }
-  end
-
-  def test_read_local_entryFromTruncatedZipFile
-    zipFragment=""
-    ::File.open(TestZipFile::TEST_ZIP2.zip_name) { |f| zipFragment = f.read(12) } # local header is at least 30 bytes
-    zipFragment.extend(IOizeString).reset
-    entry = ::Zip::Entry.new
-    entry.read_local_entry(zipFragment)
-    fail "ZipError expected"
-  rescue ZipError
-  end
-
-  def test_writeEntry
-    entry = ::Zip::Entry.new("file.zip", "entryName", "my little comment",
-                             "thisIsSomeExtraInformation", 100, 987654,
-                             ::Zip::Entry::DEFLATED, 400)
-    write_to_file("localEntryHeader.bin", "centralEntryHeader.bin", entry)
-    entryReadLocal, entryReadCentral = read_from_file("localEntryHeader.bin", "centralEntryHeader.bin")
-    assert(entryReadLocal.extra['Zip64Placeholder'], 'zip64 placeholder should be used in local file header')
-    entryReadLocal.extra.delete('Zip64Placeholder') # it was removed when writing the c_dir_entry, so remove from compare
-    assert(entryReadCentral.extra['Zip64Placeholder'].nil?, 'zip64 placeholder should not be used in central directory')
-    compare_local_entry_headers(entry, entryReadLocal)
-    compare_c_dir_entry_headers(entry, entryReadCentral)
-  end
-
-  def test_write64Entry
-    entry = ::Zip::Entry.new("bigfile.zip", "entryName", "my little equine",
-                             "malformed extra field because why not",
-                             0x7766554433221100, 0xDEADBEEF, ::Zip::Entry::DEFLATED,
-                             0x9988776655443322)
-    write_to_file("localEntryHeader.bin", "centralEntryHeader.bin", entry)
-    entryReadLocal, entryReadCentral = read_from_file("localEntryHeader.bin", "centralEntryHeader.bin")
-    compare_local_entry_headers(entry, entryReadLocal)
-    compare_c_dir_entry_headers(entry, entryReadCentral)
-  end
-
-  def test_rewriteLocalHeader64
-    buf1 = StringIO.new
-    entry = ::Zip::Entry.new("file.zip", "entryName")
-    entry.write_local_entry(buf1)
-    assert(entry.extra['Zip64'].nil?, "zip64 extra is unnecessarily present")
-
-    buf2 = StringIO.new
-    entry.size = 0x123456789ABCDEF0
-    entry.compressed_size = 0x0123456789ABCDEF
-    entry.write_local_entry(buf2, true)
-    assert_not_nil(entry.extra['Zip64'])
-
-    assert_not_equal(buf1.size, 0)
-    assert_equal(buf1.size, buf2.size) # it can't grow, or we'd clobber file data
-  end
-
-  def test_readLocalOffset
-    entry = ::Zip::Entry.new("file.zip", "entryName")
-    entry.local_header_offset = 12345
-    ::File.open('centralEntryHeader.bin', 'wb') { |f| entry.write_c_dir_entry(f) }
-    read_entry = nil
-    ::File.open('centralEntryHeader.bin', 'rb') { |f| read_entry = ::Zip::Entry.read_c_dir_entry(f) }
-    compare_c_dir_entry_headers(entry, read_entry)
-  end
-
-  def test_read64LocalOffset
-    entry = ::Zip::Entry.new("file.zip", "entryName")
-    entry.local_header_offset = 0x0123456789ABCDEF
-    ::File.open('centralEntryHeader.bin', 'wb') { |f| entry.write_c_dir_entry(f) }
-    read_entry = nil
-    ::File.open('centralEntryHeader.bin', 'rb') { |f| read_entry = ::Zip::Entry.read_c_dir_entry(f) }
-    compare_c_dir_entry_headers(entry, read_entry)
-  end
-
-  private
-  def compare_local_entry_headers(entry1, entry2)
-    assert_equal(entry1.compressed_size, entry2.compressed_size)
-    assert_equal(entry1.crc, entry2.crc)
-    assert_equal(entry1.extra, entry2.extra)
-    assert_equal(entry1.compression_method, entry2.compression_method)
-    assert_equal(entry1.name, entry2.name)
-    assert_equal(entry1.size, entry2.size)
-    assert_equal(entry1.local_header_offset, entry2.local_header_offset)
-  end
-
-  def compare_c_dir_entry_headers(entry1, entry2)
-    compare_local_entry_headers(entry1, entry2)
-    assert_equal(entry1.comment, entry2.comment)
-  end
-
-  def write_to_file(localFileName, centralFileName, entry)
-    ::File.open(localFileName, "wb") { |f| entry.write_local_entry(f) }
-    ::File.open(centralFileName, "wb") { |f| entry.write_c_dir_entry(f) }
-  end
-
-  def read_from_file(localFileName, centralFileName)
-    localEntry = nil
-    cdirEntry  = nil
-    ::File.open(localFileName, "rb") { |f| localEntry = ::Zip::Entry.read_local_entry(f) }
-    ::File.open(centralFileName, "rb") { |f| cdirEntry = ::Zip::Entry.read_c_dir_entry(f) }
-    [localEntry, cdirEntry]
-  end
-end
-
-
-module DecompressorTests
-  # expects @refText, @refLines and @decompressor
-
-  TEST_FILE="data/file1.txt"
-
-  def setup
-    @refText=""
-    File.open(TEST_FILE) { |f| @refText = f.read }
-    @refLines = @refText.split($/)
-  end
-
-  def test_readEverything
-    assert_equal(@refText, @decompressor.sysread)
-  end
-
-  def test_readInChunks
-    chunkSize = 5
-    while (decompressedChunk = @decompressor.sysread(chunkSize))
-      assert_equal(@refText.slice!(0, chunkSize), decompressedChunk)
-    end
-    assert_equal(0, @refText.size)
-  end
-
-  def test_mixingReadsAndProduceInput
-    # Just some preconditions to make sure we have enough data for this test
-    assert(@refText.length > 1000)
-    assert(@refLines.length > 40)
-
-
-    assert_equal(@refText[0...100], @decompressor.sysread(100))
-
-    assert(!@decompressor.input_finished?)
-    buf = @decompressor.produce_input
-    assert_equal(@refText[100...(100+buf.length)], buf)
-  end
-end
-
-class InflaterTest < Test::Unit::TestCase
-  include DecompressorTests
-
-  def setup
-    super
-    @file         = File.new("data/file1.txt.deflatedData", "rb")
-    @decompressor = Inflater.new(@file)
-  end
-
-  def teardown
-    @file.close
-  end
-end
-
-
-class PassThruDecompressorTest < Test::Unit::TestCase
-  include DecompressorTests
-
-  def setup
-    super
-    @file         = File.new(TEST_FILE)
-    @decompressor = PassThruDecompressor.new(@file, File.size(TEST_FILE))
-  end
-
-  def teardown
-    @file.close
-  end
-end
-
-
-module AssertEntry
-  def assert_next_entry(filename, zis)
-    assert_entry(filename, zis, zis.get_next_entry.name)
-  end
-
-  def assert_entry(filename, zis, entryName)
-    assert_equal(filename, entryName)
-    assert_entryContentsForStream(filename, zis, entryName)
-  end
-
-  def assert_entryContentsForStream(filename, zis, entryName)
-    File.open(filename, "rb") {
-      |file|
-      expected = file.read
-      actual   = zis.read
-      if (expected != actual)
-        if ((expected && actual) && (expected.length > 400 || actual.length > 400))
-          zipEntryFilename=entryName+".zipEntry"
-          File.open(zipEntryFilename, "wb") { |entryfile| entryfile << actual }
-          fail("File '#{filename}' is different from '#{zipEntryFilename}'")
-        else
-          assert_equal(expected, actual)
-        end
-      end
-    }
-  end
-
-  def AssertEntry.assert_contents(filename, aString)
-    fileContents = ""
-    File.open(filename, "rb") { |f| fileContents = f.read }
-    if (fileContents != aString)
-      if (fileContents.length > 400 || aString.length > 400)
-        stringFile = filename + ".other"
-        File.open(stringFile, "wb") { |f| f << aString }
-        fail("File '#{filename}' is different from contents of string stored in '#{stringFile}'")
-      else
-        assert_equal(fileContents, aString)
-      end
-    end
-  end
-
-  def assert_stream_contents(zis, testZipFile)
-    assert(zis != nil)
-    testZipFile.entry_names.each do |entryName|
-      assert_next_entry(entryName, zis)
-    end
-    assert_equal(nil, zis.get_next_entry)
-  end
-
-  def assert_test_zip_contents(testZipFile)
-    ::Zip::InputStream.open(testZipFile.zip_name) do |zis|
-      assert_stream_contents(zis, testZipFile)
-    end
-  end
-
-  def assert_entryContents(zipFile, entryName, filename = entryName.to_s)
-    zis = zipFile.get_input_stream(entryName)
-    assert_entryContentsForStream(filename, zis, entryName)
-  ensure
-    zis.close if zis
-  end
-end
-
-
-class ZipInputStreamTest < Test::Unit::TestCase
-  include AssertEntry
-
-  def test_new
-    zis = ::Zip::InputStream.new(TestZipFile::TEST_ZIP2.zip_name)
-    assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
-    assert_equal(true, zis.eof?)
-    zis.close
-  end
-
-  def test_openWithBlock
-    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
-      |zis|
-      assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
-      assert_equal(true, zis.eof?)
-    }
-  end
-
-  def test_openWithoutBlock
-    zis = ::Zip::InputStream.open(File.new(TestZipFile::TEST_ZIP2.zip_name, "rb"))
-    assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
-  end
-
-  def test_openBufferWithBlock
-    ::Zip::InputStream.open(File.new(TestZipFile::TEST_ZIP2.zip_name, "rb")) do |zis|
-      assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
-      assert_equal(true, zis.eof?)
-    end
-  end
-
-  def test_open_string_io_without_block
-    string_io = ::StringIO.new(::File.read(TestZipFile::TEST_ZIP2.zip_name))
-    zis = ::Zip::InputStream.open(string_io)
-    assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
-  end
-
-  def test_open_string_io_with_block
-    string_io = ::StringIO.new(::File.read(TestZipFile::TEST_ZIP2.zip_name))
-    ::Zip::InputStream.open(string_io) do |zis|
-      assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
-      assert_equal(true, zis.eof?)
-    end
-  end
-
-  def test_openBufferWithoutBlock
-    zis = ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name)
-    assert_stream_contents(zis, TestZipFile::TEST_ZIP2)
-  end
-
-  def test_incompleteReads
-    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
-      |zis|
-      entry = zis.get_next_entry # longAscii.txt
-      assert_equal(false, zis.eof?)
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
-      assert zis.gets.length > 0
-      assert_equal(false, zis.eof?)
-      entry = zis.get_next_entry # empty.txt
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
-      assert_equal(0, entry.size)
-      assert_equal(nil, zis.gets)
-      assert_equal(true, zis.eof?)
-      entry = zis.get_next_entry # empty_chmod640.txt
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
-      assert_equal(0, entry.size)
-      assert_equal(nil, zis.gets)
-      assert_equal(true, zis.eof?)
-      entry = zis.get_next_entry # short.txt
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
-      assert zis.gets.length > 0
-      entry = zis.get_next_entry # longBinary.bin
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
-      assert zis.gets.length > 0
-    }
-  end
-
-  def test_incomplete_reads_from_string_io
-    string_io = ::StringIO.new(::File.read(TestZipFile::TEST_ZIP2.zip_name))
-    ::Zip::InputStream.open(string_io) do |zis|
-      entry = zis.get_next_entry # longAscii.txt
-      assert_equal(false, zis.eof?)
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], entry.name)
-      assert zis.gets.length > 0
-      assert_equal(false, zis.eof?)
-      entry = zis.get_next_entry # empty.txt
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[1], entry.name)
-      assert_equal(0, entry.size)
-      assert_equal(nil, zis.gets)
-      assert_equal(true, zis.eof?)
-      entry = zis.get_next_entry # empty_chmod640.txt
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[2], entry.name)
-      assert_equal(0, entry.size)
-      assert_equal(nil, zis.gets)
-      assert_equal(true, zis.eof?)
-      entry = zis.get_next_entry # short.txt
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[3], entry.name)
-      assert zis.gets.length > 0
-      entry = zis.get_next_entry # longBinary.bin
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[4], entry.name)
-      assert zis.gets.length > 0
-    end
-  end
-
-  def test_read_with_number_of_bytes_returns_nil_at_eof
-    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) do |zis|
-      entry = zis.get_next_entry # longAscii.txt
-      zis.read(entry.size)
-      assert_equal(true, zis.eof?)
-      assert_nil(zis.read(1))
-      assert_nil(zis.read(1))
-    end
-  end
-
-  def test_rewind
-    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
-      |zis|
-      e = zis.get_next_entry
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names[0], e.name)
-
-      # Do a little reading
-      buf = ""
-      buf << zis.read(100)
-      assert_equal(100, zis.pos)
-      buf << (zis.gets || "")
-      buf << (zis.gets || "")
-      assert_equal(false, zis.eof?)
-
-      zis.rewind
-
-      buf2 = ""
-      buf2 << zis.read(100)
-      buf2 << (zis.gets || "")
-      buf2 << (zis.gets || "")
-
-      assert_equal(buf, buf2)
-
-      zis.rewind
-      assert_equal(false, zis.eof?)
-      assert_equal(0, zis.pos)
-
-      assert_entry(e.name, zis, e.name)
-    }
-  end
-
-  def test_mix_read_and_gets
-    ::Zip::InputStream.open(TestZipFile::TEST_ZIP2.zip_name) {
-      |zis|
-      zis.get_next_entry
-      assert_equal("#!/usr/bin/env ruby", zis.gets.chomp)
-      assert_equal(false, zis.eof?)
-      assert_equal("", zis.gets.chomp)
-      assert_equal(false, zis.eof?)
-      assert_equal("$VERBOSE =", zis.read(10))
-      assert_equal(false, zis.eof?)
-    }
-  end
-
-end
-
-
-module CrcTest
-
-  class TestOutputStream
-    include ::Zip::IOExtras::AbstractOutputStream
-
-    attr_accessor :buffer
-
-    def initialize
-      @buffer = ""
-    end
-
-    def << (data)
-      @buffer << data
-      self
-    end
-  end
-
-  def run_crc_test(compressorClass)
-    str     = "Here's a nice little text to compute the crc for! Ho hum, it is nice nice nice nice indeed."
-    fakeOut = TestOutputStream.new
-
-    deflater = compressorClass.new(fakeOut)
-    deflater << str
-    assert_equal(0x919920fc, deflater.crc)
-  end
-end
-
-
-class PassThruCompressorTest < Test::Unit::TestCase
-  include CrcTest
-
-  def test_size
-    File.open("dummy.txt", "wb") {
-      |file|
-      compressor = PassThruCompressor.new(file)
-
-      assert_equal(0, compressor.size)
-
-      t1 = "hello world"
-      t2 = ""
-      t3 = "bingo"
-
-      compressor << t1
-      assert_equal(compressor.size, t1.size)
-
-      compressor << t2
-      assert_equal(compressor.size, t1.size + t2.size)
-
-      compressor << t3
-      assert_equal(compressor.size, t1.size + t2.size + t3.size)
-    }
-  end
-
-  def test_crc
-    run_crc_test(PassThruCompressor)
-  end
-end
-
-class DeflaterTest < Test::Unit::TestCase
-  include CrcTest
-
-  def test_outputOperator
-    txt = load_file("data/file2.txt")
-    deflate(txt, "deflatertest.bin")
-    inflatedTxt = inflate("deflatertest.bin")
-    assert_equal(txt, inflatedTxt)
-  end
-
-  private
-  def load_file(fileName)
-    txt = nil
-    File.open(fileName, "rb") { |f| txt = f.read }
-  end
-
-  def deflate(data, fileName)
-    File.open(fileName, "wb") {
-      |file|
-      deflater = Deflater.new(file)
-      deflater << data
-      deflater.finish
-      assert_equal(deflater.size, data.size)
-      file << "trailing data for zlib with -MAX_WBITS"
-    }
-  end
-
-  def inflate(fileName)
-    txt = nil
-    File.open(fileName, "rb") {
-      |file|
-      inflater = Inflater.new(file)
-      txt      = inflater.sysread
-    }
-  end
-
-  def test_crc
-    run_crc_test(Deflater)
-  end
-end
-
-class ZipOutputStreamTest < Test::Unit::TestCase
-  include AssertEntry
-
-  TEST_ZIP          = TestZipFile::TEST_ZIP2.clone
-  TEST_ZIP.zip_name = "output.zip"
-
-  def test_new
-    zos         = ::Zip::OutputStream.new(TEST_ZIP.zip_name)
-    zos.comment = TEST_ZIP.comment
-    write_test_zip(zos)
-    zos.close
-    assert_test_zip_contents(TEST_ZIP)
-  end
-
-  def test_open
-    ::Zip::OutputStream.open(TEST_ZIP.zip_name) do |zos|
-      zos.comment = TEST_ZIP.comment
-      write_test_zip(zos)
-    end
-    assert_test_zip_contents(TEST_ZIP)
-  end
-
-  def test_write_buffer
-    buffer = ::Zip::OutputStream.write_buffer do |zos|
-      zos.comment = TEST_ZIP.comment
-      write_test_zip(zos)
-    end
-    File.open(TEST_ZIP.zip_name, 'wb') { |f| f.write buffer.string }
-    assert_test_zip_contents(TEST_ZIP)
-  end
-
-  def test_writingToClosedStream
-    assert_i_o_error_in_closed_stream { |zos| zos << "hello world" }
-    assert_i_o_error_in_closed_stream { |zos| zos.puts "hello world" }
-    assert_i_o_error_in_closed_stream { |zos| zos.write "hello world" }
-  end
-
-  def test_cannotOpenFile
-    name = TestFiles::EMPTY_TEST_DIR
-    begin
-      ::Zip::OutputStream.open(name)
-    rescue Exception
-      assert($!.kind_of?(Errno::EISDIR) || # Linux
-               $!.kind_of?(Errno::EEXIST) || # Windows/cygwin
-               $!.kind_of?(Errno::EACCES), # Windows
-        "Expected Errno::EISDIR (or on win/cygwin: Errno::EEXIST), but was: #{$!.class}")
-    end
-  end
-
-  def test_put_next_entry
-    stored_text = "hello world in stored text"
-    entry_name  = "file1"
-    comment     = "my comment"
-    ::Zip::OutputStream.open(TEST_ZIP.zip_name) do |zos|
-      zos.put_next_entry(entry_name, comment, nil, ::Zip::Entry::STORED)
-      zos << stored_text
-    end
-
-    assert(File.read(TEST_ZIP.zip_name)[stored_text])
-    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
-      assert_equal(stored_text, zf.read(entry_name))
-    end
-  end
-
-  def test_put_next_entry_using_zip_entry_creates_entries_with_correct_timestamps
-    file = ::File.open("data/file2.txt", "rb")
-    ::Zip::OutputStream.open(TEST_ZIP.zip_name) do |zos|
-      zip_entry = ::Zip::Entry.new(zos, file.path, "", "", 0, 0, ::Zip::Entry::DEFLATED, 0, ::Zip::DOSTime.at(file.mtime))
-      zos.put_next_entry(zip_entry)
-      zos << file.read
-    end
-
-    ::Zip::InputStream::open(TEST_ZIP.zip_name) do |io|
-      while (entry = io.get_next_entry)
-        assert(::Zip::DOSTime.at(file.mtime).dos_equals(::Zip::DOSTime.at(entry.mtime))) # Compare DOS Times, since they are stored with two seconds accuracy
-      end
-    end
-  end
-
-  def assert_i_o_error_in_closed_stream
-    assert_raise(IOError) {
-      zos = ::Zip::OutputStream.new("test_putOnClosedStream.zip")
-      zos.close
-      yield zos
-    }
-  end
-
-  def write_test_zip(zos)
-    TEST_ZIP.entry_names.each do |entryName|
-      zos.put_next_entry(entryName)
-      File.open(entryName, "rb") { |f| zos.write(f.read) }
-    end
-  end
-end
-
-
-module Enumerable
-  def compare_enumerables(otherEnumerable)
-    otherAsArray = otherEnumerable.to_a
-    each_with_index {
-      |element, index|
-      return false unless yield(element, otherAsArray[index])
-    }
-    return self.size == otherAsArray.size
-  end
-end
-
-
-class ZipCentralDirectoryEntryTest < Test::Unit::TestCase
-
-  def test_read_from_stream
-    File.open("data/testDirectory.bin", "rb") {
-      |file|
-      entry = ::Zip::Entry.read_c_dir_entry(file)
-
-      assert_equal("longAscii.txt", entry.name)
-      assert_equal(::Zip::Entry::DEFLATED, entry.compression_method)
-      assert_equal(106490, entry.size)
-      assert_equal(3784, entry.compressed_size)
-      assert_equal(0xfcd1799c, entry.crc)
-      assert_equal("", entry.comment)
-
-      entry = ::Zip::Entry.read_c_dir_entry(file)
-      assert_equal("empty.txt", entry.name)
-      assert_equal(::Zip::Entry::STORED, entry.compression_method)
-      assert_equal(0, entry.size)
-      assert_equal(0, entry.compressed_size)
-      assert_equal(0x0, entry.crc)
-      assert_equal("", entry.comment)
-
-      entry = ::Zip::Entry.read_c_dir_entry(file)
-      assert_equal("short.txt", entry.name)
-      assert_equal(::Zip::Entry::STORED, entry.compression_method)
-      assert_equal(6, entry.size)
-      assert_equal(6, entry.compressed_size)
-      assert_equal(0xbb76fe69, entry.crc)
-      assert_equal("", entry.comment)
-
-      entry = ::Zip::Entry.read_c_dir_entry(file)
-      assert_equal("longBinary.bin", entry.name)
-      assert_equal(::Zip::Entry::DEFLATED, entry.compression_method)
-      assert_equal(1000024, entry.size)
-      assert_equal(70847, entry.compressed_size)
-      assert_equal(0x10da7d59, entry.crc)
-      assert_equal('', entry.comment)
-
-      entry = ::Zip::Entry.read_c_dir_entry(file)
-      assert_equal(nil, entry)
-# Fields that are not check by this test:
-#          version made by                 2 bytes
-#          version needed to extract       2 bytes
-#          general purpose bit flag        2 bytes
-#          last mod file time              2 bytes
-#          last mod file date              2 bytes
-#          compressed size                 4 bytes
-#          uncompressed size               4 bytes
-#          disk number start               2 bytes
-#          internal file attributes        2 bytes
-#          external file attributes        4 bytes
-#          relative offset of local header 4 bytes
-
-#          file name (variable size)
-#          extra field (variable size)
-#          file comment (variable size)
-
-    }
-  end
-
-  def test_ReadEntryFromTruncatedZipFile
-    fragment=""
-    File.open("data/testDirectory.bin") { |f| fragment = f.read(12) } # cdir entry header is at least 46 bytes
-    fragment.extend(IOizeString)
-    entry = ::Zip::Entry.new
-    entry.read_c_dir_entry(fragment)
-    fail "ZipError expected"
-  rescue ZipError
-  end
-
-end
-
-
-class ZipEntrySetTest < Test::Unit::TestCase
-  ZIP_ENTRIES = [
-    ::Zip::Entry.new("zipfile.zip", "name1", "comment1"),
-    ::Zip::Entry.new("zipfile.zip", "name3", "comment1"),
-    ::Zip::Entry.new("zipfile.zip", "name2", "comment1"),
-    ::Zip::Entry.new("zipfile.zip", "name4", "comment1"),
-    ::Zip::Entry.new("zipfile.zip", "name5", "comment1"),
-    ::Zip::Entry.new("zipfile.zip", "name6", "comment1")
-  ]
-
-  def setup
-    @zipEntrySet = ::Zip::EntrySet.new(ZIP_ENTRIES)
-  end
-
-  def test_include
-    assert(@zipEntrySet.include?(ZIP_ENTRIES.first))
-    assert(!@zipEntrySet.include?(::Zip::Entry.new("different.zip", "different", "aComment")))
-  end
-
-  def test_size
-    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
-    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.length)
-    @zipEntrySet << ::Zip::Entry.new("a", "b", "c")
-    assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.length)
-  end
-
-  def test_add
-    zes    = ::Zip::EntrySet.new
-    entry1 = ::Zip::Entry.new("zf.zip", "name1")
-    entry2 = ::Zip::Entry.new("zf.zip", "name2")
-    zes << entry1
-    assert(zes.include?(entry1))
-    zes.push(entry2)
-    assert(zes.include?(entry2))
-  end
-
-  def test_delete
-    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
-    entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
-    assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
-    assert_equal(ZIP_ENTRIES.first, entry)
-
-    entry = @zipEntrySet.delete(ZIP_ENTRIES.first)
-    assert_equal(ZIP_ENTRIES.size - 1, @zipEntrySet.size)
-    assert_nil(entry)
-  end
-
-  def test_each
-    # Used each instead each_with_index due the bug in jRuby
-    count = 0
-    @zipEntrySet.each do |entry|
-      assert(ZIP_ENTRIES.include?(entry))
-      count += 1
-    end
-    assert_equal(ZIP_ENTRIES.size, count)
-  end
-
-  def test_entries
-    assert_equal(ZIP_ENTRIES, @zipEntrySet.entries)
-  end
-
-  def test_entries_with_sort
-    ::Zip.sort_entries = true
-    assert_equal(ZIP_ENTRIES.sort, @zipEntrySet.entries)
-    ::Zip.sort_entries = false
-    assert_equal(ZIP_ENTRIES, @zipEntrySet.entries)
-  end
-
-  def test_compound
-    newEntry = ::Zip::Entry.new("zf.zip", "new entry", "new entry's comment")
-    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
-    @zipEntrySet << newEntry
-    assert_equal(ZIP_ENTRIES.size + 1, @zipEntrySet.size)
-    assert(@zipEntrySet.include?(newEntry))
-
-    @zipEntrySet.delete(newEntry)
-    assert_equal(ZIP_ENTRIES.size, @zipEntrySet.size)
-  end
-
-  def test_dup
-    copy = @zipEntrySet.dup
-    assert_equal(@zipEntrySet, copy)
-
-    # demonstrate that this is a deep copy
-    copy.entries[0].name = "a totally different name"
-    assert(@zipEntrySet != copy)
-  end
-
-  def test_parent
-    entries  = [
-      ::Zip::Entry.new("zf.zip", "a/"),
-      ::Zip::Entry.new("zf.zip", "a/b/"),
-      ::Zip::Entry.new("zf.zip", "a/b/c/")
-    ]
-    entrySet = ::Zip::EntrySet.new(entries)
-
-    assert_equal(nil, entrySet.parent(entries[0]))
-    assert_equal(entries[0], entrySet.parent(entries[1]))
-    assert_equal(entries[1], entrySet.parent(entries[2]))
-  end
-
-  def test_glob
-    res = @zipEntrySet.glob('name[2-4]')
-    assert_equal(3, res.size)
-    assert_equal(ZIP_ENTRIES[1, 3].sort, res.sort)
-  end
-
-  def test_glob2
-    entries  = [
-      ::Zip::Entry.new("zf.zip", "a/"),
-      ::Zip::Entry.new("zf.zip", "a/b/b1"),
-      ::Zip::Entry.new("zf.zip", "a/b/c/"),
-      ::Zip::Entry.new("zf.zip", "a/b/c/c1")
-    ]
-    entrySet = ::Zip::EntrySet.new(entries)
-
-    assert_equal(entries[0, 1], entrySet.glob("*"))
-#    assert_equal(entries[FIXME], entrySet.glob("**"))
-#    res = entrySet.glob('a*')
-#    assert_equal(entries.size, res.size)
-#    assert_equal(entrySet.map { |e| e.name }, res.map { |e| e.name })
-  end
-end
-
-
-class ZipCentralDirectoryTest < Test::Unit::TestCase
-
-  def test_read_from_stream
-    ::File.open(TestZipFile::TEST_ZIP2.zip_name, "rb") {
-      |zipFile|
-      cdir = ::Zip::CentralDirectory.read_from_stream(zipFile)
-
-      assert_equal(TestZipFile::TEST_ZIP2.entry_names.size, cdir.size)
-      assert(cdir.entries.sort.compare_enumerables(TestZipFile::TEST_ZIP2.entry_names.sort) {
-        |cdirEntry, testEntryName|
-        cdirEntry.name == testEntryName
-      })
-      assert_equal(TestZipFile::TEST_ZIP2.comment, cdir.comment)
-    }
-  end
-
-  def test_readFromInvalidStream
-    File.open("data/file2.txt", "rb") {
-      |zipFile|
-      cdir = ::Zip::CentralDirectory.new
-      cdir.read_from_stream(zipFile)
-    }
-    fail "ZipError expected!"
-  rescue ZipError
-  end
-
-  def test_ReadFromTruncatedZipFile
-    fragment=""
-    File.open("data/testDirectory.bin", "rb") { |f| fragment = f.read }
-    fragment.slice!(12) # removed part of first cdir entry. eocd structure still complete
-    fragment.extend(IOizeString)
-    entry = ::Zip::CentralDirectory.new
-    entry.read_from_stream(fragment)
-    fail "ZipError expected"
-  rescue ZipError
-  end
-
-  def test_write_to_stream
-    entries = [::Zip::Entry.new("file.zip", "flimse", "myComment", "somethingExtra"),
-               ::Zip::Entry.new("file.zip", "secondEntryName"),
-               ::Zip::Entry.new("file.zip", "lastEntry.txt", "Has a comment too")]
-    cdir    = ::Zip::CentralDirectory.new(entries, "my zip comment")
-    File.open("cdirtest.bin", "wb") { |f| cdir.write_to_stream(f) }
-    cdirReadback = ::Zip::CentralDirectory.new
-    File.open("cdirtest.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
-
-    assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
-  end
-
-  def test_write64_to_stream
-    entries = [::Zip::Entry.new("file.zip", "file1-little", "comment1", "", 200, 101, ::Zip::Entry::STORED, 200),
-               ::Zip::Entry.new("file.zip", "file2-big", "comment2", "", 18000000000, 102, ::Zip::Entry::DEFLATED, 20000000000),
-               ::Zip::Entry.new("file.zip", "file3-alsobig", "comment3", "", 15000000000, 103, ::Zip::Entry::DEFLATED, 21000000000),
-               ::Zip::Entry.new("file.zip", "file4-little", "comment4", "", 100, 104, ::Zip::Entry::DEFLATED, 121)]
-    [0, 250, 18000000300, 33000000350].each_with_index do |offset, index|
-      entries[index].local_header_offset = offset
-    end
-    cdir = ::Zip::CentralDirectory.new(entries, "zip comment")
-    File.open("cdir64test.bin", "wb") { |f| cdir.write_to_stream(f) }
-    cdirReadback = ::Zip::CentralDirectory.new
-    File.open("cdir64test.bin", "rb") { |f| cdirReadback.read_from_stream(f) }
-
-    assert_equal(cdir.entries.sort, cdirReadback.entries.sort)
-    assert_equal(VERSION_NEEDED_TO_EXTRACT_ZIP64, cdirReadback.instance_variable_get(:@version_needed_for_extract))
-  end
-
-  def test_equality
-    cdir1 = ::Zip::CentralDirectory.new([::Zip::Entry.new("file.zip", "flimse", nil,
-                                                          "somethingExtra"),
-                                         ::Zip::Entry.new("file.zip", "secondEntryName"),
-                                         ::Zip::Entry.new("file.zip", "lastEntry.txt")],
-                                        "my zip comment")
-    cdir2 = ::Zip::CentralDirectory.new([::Zip::Entry.new("file.zip", "flimse", nil,
-                                                          "somethingExtra"),
-                                         ::Zip::Entry.new("file.zip", "secondEntryName"),
-                                         ::Zip::Entry.new("file.zip", "lastEntry.txt")],
-                                        "my zip comment")
-    cdir3 = ::Zip::CentralDirectory.new([::Zip::Entry.new("file.zip", "flimse", nil,
-                                                          "somethingExtra"),
-                                         ::Zip::Entry.new("file.zip", "secondEntryName"),
-                                         ::Zip::Entry.new("file.zip", "lastEntry.txt")],
-                                        "comment?")
-    cdir4 = ::Zip::CentralDirectory.new([::Zip::Entry.new("file.zip", "flimse", nil,
-                                                          "somethingExtra"),
-                                         ::Zip::Entry.new("file.zip", "lastEntry.txt")],
-                                        "comment?")
-    assert_equal(cdir1, cdir1)
-    assert_equal(cdir1, cdir2)
-
-    assert(cdir1 != cdir3)
-    assert(cdir2 != cdir3)
-    assert(cdir2 != cdir3)
-    assert(cdir3 != cdir4)
-
-    assert(cdir3 != "hello")
-  end
-end
-
-
-class BasicZipFileTest < Test::Unit::TestCase
-  include AssertEntry
-
-  def setup
-    @zipFile           = ::Zip::File.new(TestZipFile::TEST_ZIP2.zip_name)
-    @testEntryNameIndex=0
-  end
-
-  def test_entries
-    assert_equal(TestZipFile::TEST_ZIP2.entry_names.sort,
-                 @zipFile.entries.entries.sort.map { |e| e.name })
-  end
-
-  def test_each
-    count   = 0
-    visited = {}
-    @zipFile.each {
-      |entry|
-      assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
-      assert(!visited.include?(entry.name))
-      visited[entry.name] = nil
-      count               = count.succ
-    }
-    assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
-  end
-
-  def test_foreach
-    count   = 0
-    visited = {}
-    ::Zip::File.foreach(TestZipFile::TEST_ZIP2.zip_name) {
-      |entry|
-      assert(TestZipFile::TEST_ZIP2.entry_names.include?(entry.name))
-      assert(!visited.include?(entry.name))
-      visited[entry.name] = nil
-      count               = count.succ
-    }
-    assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
-  end
-
-  def test_get_input_stream
-    count   = 0
-    visited = {}
-    @zipFile.each do |entry|
-      assert_entry(entry.name, @zipFile.get_input_stream(entry), entry.name)
-      assert(!visited.include?(entry.name))
-      visited[entry.name] = nil
-      count               = count.succ
-    end
-    assert_equal(TestZipFile::TEST_ZIP2.entry_names.length, count)
-  end
-
-  def test_get_input_streamBlock
-    fileAndEntryName = @zipFile.entries.first.name
-    @zipFile.get_input_stream(fileAndEntryName) {
-      |zis|
-      assert_entryContentsForStream(fileAndEntryName,
-                                    zis,
-                                    fileAndEntryName)
-    }
-  end
-
-
-end
-
-module CommonZipFileFixture
-  include AssertEntry
-
-  EMPTY_FILENAME = "emptyZipFile.zip"
-
-  TEST_ZIP          = TestZipFile::TEST_ZIP2.clone
-  TEST_ZIP.zip_name = "5entry_copy.zip"
-
-  def setup
-    File.delete(EMPTY_FILENAME) if File.exists?(EMPTY_FILENAME)
-    FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
-  end
-end
-
-class ZipFileTest < Test::Unit::TestCase
-  include CommonZipFileFixture
-
-  def test_createFromScratchToBuffer
-    comment = "a short comment"
-
-    buffer = ::Zip::File.add_buffer do |zf|
-      zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
-      zf.mkdir("dir1")
-      zf.comment = comment
-    end
-
-    ::File.open(EMPTY_FILENAME, 'wb') { |file| file.write buffer.string }
-    # Not sure if the following line was just accidentally left in, but
-    # it's not related to the tests and breaks on windows
-    `cp #{EMPTY_FILENAME} ~/test.zip` unless Zip::RUNNING_ON_WINDOWS
-
-    zfRead = ::Zip::File.new(EMPTY_FILENAME)
-    assert_equal(comment, zfRead.comment)
-    assert_equal(2, zfRead.entries.length)
-  end
-
-  def test_createFromScratch
-    comment = "a short comment"
-
-    zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE)
-    zf.get_output_stream("myFile") { |os| os.write "myFile contains just this" }
-    zf.mkdir("dir1")
-    zf.comment = comment
-    zf.close
-
-    zfRead = ::Zip::File.new(EMPTY_FILENAME)
-    assert_equal(comment, zfRead.comment)
-    assert_equal(2, zfRead.entries.length)
-  end
-
-  def test_get_output_stream
-    entryCount = nil
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      entryCount = zf.size
-      zf.get_output_stream('newEntry.txt') {
-        |os|
-        os.write "Putting stuff in newEntry.txt"
-      }
-      assert_equal(entryCount+1, zf.size)
-      assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
-
-      zf.get_output_stream(zf.get_entry('data/generated/empty.txt')) {
-        |os|
-        os.write "Putting stuff in data/generated/empty.txt"
-      }
-      assert_equal(entryCount+1, zf.size)
-      assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
-
-      custom_entry_args = [ZipEntryTest::TEST_COMMENT, ZipEntryTest::TEST_EXTRA, ZipEntryTest::TEST_COMPRESSED_SIZE, ZipEntryTest::TEST_CRC, ::Zip::Entry::STORED, ZipEntryTest::TEST_SIZE, ZipEntryTest::TEST_TIME]
-      zf.get_output_stream('entry_with_custom_args.txt', nil, *custom_entry_args) {
-        |os|
-        os.write "Some data"
-      }
-      assert_equal(entryCount+2, zf.size)
-      entry = zf.get_entry('entry_with_custom_args.txt')
-      assert_equal(custom_entry_args[0], entry.comment)
-      assert_equal(custom_entry_args[2], entry.compressed_size)
-      assert_equal(custom_entry_args[3], entry.crc)
-      assert_equal(custom_entry_args[4], entry.compression_method)
-      assert_equal(custom_entry_args[5], entry.size)
-      assert_equal(custom_entry_args[6], entry.time)
-
-      zf.get_output_stream('entry.bin') {
-        |os|
-        os.write(::File.open('data/generated/5entry.zip', 'rb').read)
-      }
-    }
-
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      assert_equal(entryCount+3, zf.size)
-      assert_equal("Putting stuff in newEntry.txt", zf.read("newEntry.txt"))
-      assert_equal("Putting stuff in data/generated/empty.txt", zf.read("data/generated/empty.txt"))
-      assert_equal(File.open('data/generated/5entry.zip', 'rb').read, zf.read("entry.bin"))
-    }
-  end
-
-  def test_add
-    srcFile   = "data/file2.txt"
-    entryName = "newEntryName.rb"
-    assert(::File.exists?(srcFile))
-    zf = ::Zip::File.new(EMPTY_FILENAME, ::Zip::File::CREATE)
-    zf.add(entryName, srcFile)
-    zf.close
-
-    zfRead = ::Zip::File.new(EMPTY_FILENAME)
-    assert_equal("", zfRead.comment)
-    assert_equal(1, zfRead.entries.length)
-    assert_equal(entryName, zfRead.entries.first.name)
-    AssertEntry.assert_contents(srcFile,
-                                zfRead.get_input_stream(entryName) { |zis| zis.read })
-  end
-
-  def test_recover_permissions_after_add_files_to_archive
-    srcZip = TEST_ZIP.zip_name
-    ::File.chmod(0664, srcZip)
-    srcFile   = "data/file2.txt"
-    entryName = "newEntryName.rb"
-    assert_equal(::File.stat(srcZip).mode, 0100664)
-    assert(::File.exists?(srcZip))
-    zf = ::Zip::File.new(srcZip, ::Zip::File::CREATE)
-    zf.add(entryName, srcFile)
-    zf.close
-    assert_equal(::File.stat(srcZip).mode, 0100664)
-  end
-
-  def test_addExistingEntryName
-    assert_raise(ZipEntryExistsError) {
-      ::Zip::File.open(TEST_ZIP.zip_name) {
-        |zf|
-        zf.add(zf.entries.first.name, "data/file2.txt")
-      }
-    }
-  end
-
-  def test_addExistingEntryNameReplace
-    gotCalled     = false
-    replacedEntry = nil
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      replacedEntry = zf.entries.first.name
-      zf.add(replacedEntry, "data/file2.txt") { gotCalled = true; true }
-    }
-    assert(gotCalled)
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      assert_contains(zf, replacedEntry, "data/file2.txt")
-    }
-  end
-
-  def test_addDirectory
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      zf.add(TestFiles::EMPTY_TEST_DIR, TestFiles::EMPTY_TEST_DIR)
-    }
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      dirEntry = zf.entries.detect { |e| e.name == TestFiles::EMPTY_TEST_DIR+"/" }
-      assert(dirEntry.directory?)
-    }
-  end
-
-  def test_remove
-    entryToRemove, *remainingEntries = TEST_ZIP.entry_names
-
-    FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
-
-    zf = ::Zip::File.new(TEST_ZIP.zip_name)
-    assert(zf.entries.map { |e| e.name }.include?(entryToRemove))
-    zf.remove(entryToRemove)
-    assert(!zf.entries.map { |e| e.name }.include?(entryToRemove))
-    assert_equal(zf.entries.map { |x| x.name }.sort, remainingEntries.sort)
-    zf.close
-
-    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
-    assert(!zfRead.entries.map { |e| e.name }.include?(entryToRemove))
-    assert_equal(zfRead.entries.map { |x| x.name }.sort, remainingEntries.sort)
-    zfRead.close
-  end
-
-  def test_rename
-    entryToRename, * = TEST_ZIP.entry_names
-
-    zf = ::Zip::File.new(TEST_ZIP.zip_name)
-    assert(zf.entries.map { |e| e.name }.include?(entryToRename))
-
-    contents = zf.read(entryToRename)
-    newName  = "changed entry name"
-    assert(!zf.entries.map { |e| e.name }.include?(newName))
-
-    zf.rename(entryToRename, newName)
-    assert(zf.entries.map { |e| e.name }.include?(newName))
-
-    assert_equal(contents, zf.read(newName))
-
-    zf.close
-
-    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
-    assert(zfRead.entries.map { |e| e.name }.include?(newName))
-    assert_equal(contents, zfRead.read(newName))
-    zfRead.close
-  end
-
-  def test_rename_with_each
-    zf_name = 'test_rename_zip.zip'
-    if ::File.exist?(zf_name)
-      ::File.unlink(zf_name)
-    end
-    arr = []
-    arr_renamed = []
-    ::Zip::File.open(zf_name, ::Zip::File::CREATE) do |zf|
-      zf.mkdir('test')
-      arr << 'test/'
-      arr_renamed << 'Ztest/'
-      %w(a b c d).each do |f|
-        zf.get_output_stream("test/#{f}") {|file| file.puts 'aaaa'}
-        arr << "test/#{f}"
-        arr_renamed << "Ztest/#{f}"
-      end
-    end
-    zf = ::Zip::File.open(zf_name)
-    assert_equal(zf.entries.map(&:name), arr)
-    zf.close
-    Zip::File.open(zf_name, "wb") do |z|
-      z.each do |f|
-        z.rename(f, "Z#{f.name}")
-      end
-    end
-    zf = ::Zip::File.open(zf_name)
-    assert_equal(zf.entries.map(&:name), arr_renamed)
-    zf.close
-    if ::File.exist?(zf_name)
-      ::File.unlink(zf_name)
-    end
-  end
-
-  def test_renameToExistingEntry
-    oldEntries = nil
-    ::Zip::File.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
-
-    assert_raise(ZipEntryExistsError) do
-      ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
-        zf.rename(zf.entries[0], zf.entries[1].name)
-      end
-    end
-
-    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
-      assert_equal(oldEntries.sort.map { |e| e.name }, zf.entries.sort.map { |e| e.name })
-    end
-  end
-
-  def test_renameToExistingEntryOverwrite
-    oldEntries = nil
-    ::Zip::File.open(TEST_ZIP.zip_name) { |zf| oldEntries = zf.entries }
-
-    gotCalled        = false
-    renamedEntryName = nil
-    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
-      renamedEntryName = zf.entries[0].name
-      zf.rename(zf.entries[0], zf.entries[1].name) { gotCalled = true; true }
-    end
-
-    assert(gotCalled)
-    oldEntries.delete_if { |e| e.name == renamedEntryName }
-    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
-      assert_equal(oldEntries.sort.map { |e| e.name },
-                   zf.entries.sort.map { |e| e.name })
-    end
-  end
-
-  def test_renameNonEntry
-    nonEntry     = "bogusEntry"
-    target_entry = "target_entryName"
-    zf           = ::Zip::File.new(TEST_ZIP.zip_name)
-    assert(!zf.entries.include?(nonEntry))
-    assert_raise(Errno::ENOENT) {
-      zf.rename(nonEntry, target_entry)
-    }
-    zf.commit
-    assert(!zf.entries.include?(target_entry))
-  ensure
-    zf.close
-  end
-
-  def test_renameEntryToExistingEntry
-    entry1, entry2, * = TEST_ZIP.entry_names
-    zf                = ::Zip::File.new(TEST_ZIP.zip_name)
-    assert_raise(ZipEntryExistsError) {
-      zf.rename(entry1, entry2)
-    }
-  ensure
-    zf.close
-  end
-
-  def test_replace
-    entryToReplace      = TEST_ZIP.entry_names[2]
-    newEntrySrcFilename = "data/file2.txt"
-    zf                  = ::Zip::File.new(TEST_ZIP.zip_name)
-    zf.replace(entryToReplace, newEntrySrcFilename)
-
-    zf.close
-    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
-    AssertEntry::assert_contents(newEntrySrcFilename,
-                                 zfRead.get_input_stream(entryToReplace) { |is| is.read })
-    AssertEntry::assert_contents(TEST_ZIP.entry_names[0],
-                                 zfRead.get_input_stream(TEST_ZIP.entry_names[0]) { |is| is.read })
-    AssertEntry::assert_contents(TEST_ZIP.entry_names[1],
-                                 zfRead.get_input_stream(TEST_ZIP.entry_names[1]) { |is| is.read })
-    AssertEntry::assert_contents(TEST_ZIP.entry_names[3],
-                                 zfRead.get_input_stream(TEST_ZIP.entry_names[3]) { |is| is.read })
-    zfRead.close
-  end
-
-  def test_replaceNonEntry
-    entryToReplace = "nonExistingEntryname"
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      assert_raise(Errno::ENOENT) {
-        zf.replace(entryToReplace, "data/file2.txt")
-      }
-    }
-  end
-
-  def test_commit
-    newName = "renamedFirst"
-    zf      = ::Zip::File.new(TEST_ZIP.zip_name)
-    oldName = zf.entries.first
-    zf.rename(oldName, newName)
-    zf.commit
-
-    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
-    assert(zfRead.entries.detect { |e| e.name == newName } != nil)
-    assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
-    zfRead.close
-
-    zf.close
-  end
-
-  def test_write_buffer
-    newName = "renamedFirst"
-    zf      = ::Zip::File.new(TEST_ZIP.zip_name)
-    oldName = zf.entries.first
-    zf.rename(oldName, newName)
-    buffer = zf.write_buffer
-    File.open(TEST_ZIP.zip_name, 'wb') { |f| f.write buffer.string }
-    zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
-    assert(zfRead.entries.detect { |e| e.name == newName } != nil)
-    assert(zfRead.entries.detect { |e| e.name == oldName } == nil)
-    zfRead.close
-
-    zf.close
-  end
-
-  # This test tests that after commit, you
-  # can delete the file you used to add the entry to the zip file
-  # with
-  def test_commitUseZipEntry
-    FileUtils.cp(TestFiles::RANDOM_ASCII_FILE1, "okToDelete.txt")
-    zf = ::Zip::File.open(TEST_ZIP.zip_name)
-    zf.add("okToDelete.txt", "okToDelete.txt")
-    assert_contains(zf, "okToDelete.txt")
-    zf.commit
-    File.rename("okToDelete.txt", "okToDeleteMoved.txt")
-    assert_contains(zf, "okToDelete.txt", "okToDeleteMoved.txt")
-  end
-
-#  def test_close
-#    zf = ZipFile.new(TEST_ZIP.zip_name)
-#    zf.close
-#    assert_raise(IOError) {
-#      zf.extract(TEST_ZIP.entry_names.first, "hullubullu")
-#    }
-#  end
-
-  def test_compound1
-    renamedName        = "renamedName"
-    originalEntries    = []
-    filename_to_remove = ''
-    begin
-      zf              = ::Zip::File.new(TEST_ZIP.zip_name)
-      originalEntries = zf.entries.dup
-
-      assert_not_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
-      zf.add(TestFiles::RANDOM_ASCII_FILE1,
-             TestFiles::RANDOM_ASCII_FILE1)
-      assert_contains(zf, TestFiles::RANDOM_ASCII_FILE1)
-
-      entry_to_rename = zf.entries.find { |entry| entry.name.match('longAscii') }
-      zf.rename(entry_to_rename, renamedName)
-      assert_contains(zf, renamedName)
-
-      TestFiles::BINARY_TEST_FILES.each {
-        |filename|
-        zf.add(filename, filename)
-        assert_contains(zf, filename)
-      }
-
-      assert_contains(zf, originalEntries.last.to_s)
-      filename_to_remove = originalEntries.map(&:to_s).find { |name| name.match('longBinary') }
-      zf.remove(filename_to_remove)
-      assert_not_contains(zf, filename_to_remove)
-
-    ensure
-      zf.close
-    end
-    begin
-      zfRead = ::Zip::File.new(TEST_ZIP.zip_name)
-      assert_contains(zfRead, TestFiles::RANDOM_ASCII_FILE1)
-      assert_contains(zfRead, renamedName)
-      TestFiles::BINARY_TEST_FILES.each {
-        |filename|
-        assert_contains(zfRead, filename)
-      }
-      assert_not_contains(zfRead, filename_to_remove)
-    ensure
-      zfRead.close
-    end
-  end
-
-  def test_compound2
-    begin
-      zf              = ::Zip::File.new(TEST_ZIP.zip_name)
-      originalEntries = zf.entries.dup
-
-      originalEntries.each {
-        |entry|
-        zf.remove(entry)
-        assert_not_contains(zf, entry)
-      }
-      assert(zf.entries.empty?)
-
-      TestFiles::ASCII_TEST_FILES.each {
-        |filename|
-        zf.add(filename, filename)
-        assert_contains(zf, filename)
-      }
-      assert_equal(zf.entries.sort.map { |e| e.name }, TestFiles::ASCII_TEST_FILES)
-
-      zf.rename(TestFiles::ASCII_TEST_FILES[0], "newName")
-      assert_not_contains(zf, TestFiles::ASCII_TEST_FILES[0])
-      assert_contains(zf, "newName")
-    ensure
-      zf.close
-    end
-    begin
-      zfRead         = ::Zip::File.new(TEST_ZIP.zip_name)
-      asciiTestFiles = TestFiles::ASCII_TEST_FILES.dup
-      asciiTestFiles.shift
-      asciiTestFiles.each {
-        |filename|
-        assert_contains(zf, filename)
-      }
-
-      assert_contains(zf, "newName")
-    ensure
-      zfRead.close
-    end
-  end
-
-  def test_changeComment
-    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
-      zf.comment = "my changed comment"
-    end
-    zfRead = ::Zip::File.open(TEST_ZIP.zip_name)
-    assert_equal("my changed comment", zfRead.comment)
-  end
-
-  def test_preserve_file_order
-    entryNames = nil
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      entryNames = zf.entries.map { |e| e.to_s }
-      zf.get_output_stream("a.txt") { |os| os.write "this is a.txt" }
-      zf.get_output_stream("z.txt") { |os| os.write "this is z.txt" }
-      zf.get_output_stream("k.txt") { |os| os.write "this is k.txt" }
-      entryNames << "a.txt" << "z.txt" << "k.txt"
-    }
-
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      assert_equal(entryNames, zf.entries.map { |e| e.to_s })
-      entries = zf.entries.sort_by { |e| e.name }.reverse
-      entries.each {
-        |e|
-        zf.remove e
-        zf.get_output_stream(e) { |os| os.write "foo" }
-      }
-      entryNames = entries.map { |e| e.to_s }
-    }
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      assert_equal(entryNames, zf.entries.map { |e| e.to_s })
-    }
-  end
-
-  private
-  def assert_contains(zf, entryName, filename = entryName)
-    assert(zf.entries.detect { |e| e.name == entryName } != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
-    assert_entryContents(zf, entryName, filename) if File.exists?(filename)
-  end
-
-  def assert_not_contains(zf, entryName)
-    assert(zf.entries.detect { |e| e.name == entryName } == nil, "entry #{entryName} in #{zf.entries.join(', ')} in zip file #{zf}")
-  end
-end
-
-class ZipFileSplitTest < Test::Unit::TestCase
-  TEST_ZIP            = TestZipFile::TEST_ZIP2.clone
-  TEST_ZIP.zip_name   = "large_zip_file.zip"
-  EXTRACTED_FILENAME  = "extEntry"
-  UNSPLITTED_FILENAME = "unsplitted.zip"
-  ENTRY_TO_EXTRACT    = TEST_ZIP.entry_names.first
-
-  def setup
-    FileUtils.cp(TestZipFile::TEST_ZIP2.zip_name, TEST_ZIP.zip_name)
-  end
-
-  def teardown
-    File.delete(TEST_ZIP.zip_name)
-    File.delete(UNSPLITTED_FILENAME) if File.exists?(UNSPLITTED_FILENAME)
-
-    Dir["#{TEST_ZIP.zip_name}.*"].each do |zip_file_name|
-      File.delete(zip_file_name) if File.exists?(zip_file_name)
-    end
-  end
-
-  def test_split_method_respond
-    assert_respond_to ::Zip::File, :split, "Does not have split class method"
-  end
-
-  def test_split
-    result = ::Zip::File.split(TEST_ZIP.zip_name, 65536, false)
-
-    unless result.nil?
-      Dir["#{TEST_ZIP.zip_name}.*"].sort.each_with_index do |zip_file_name, index|
-        File.open(zip_file_name, 'rb') do |zip_file|
-          zip_file.read([::Zip::File::SPLIT_SIGNATURE].pack('V').size) if index == 0
-          File.open(UNSPLITTED_FILENAME, 'ab') do |file|
-            file << zip_file.read
-          end
-        end
-      end
-
-      ::Zip::File.open(UNSPLITTED_FILENAME) do |zf|
-        zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
-
-        assert(File.exists?(EXTRACTED_FILENAME))
-        AssertEntry::assert_contents(EXTRACTED_FILENAME,
-                                     zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
-
-
-        File.unlink(EXTRACTED_FILENAME)
-
-        entry = zf.get_entry(ENTRY_TO_EXTRACT)
-        entry.extract(EXTRACTED_FILENAME)
-
-        assert(File.exists?(EXTRACTED_FILENAME))
-        AssertEntry::assert_contents(EXTRACTED_FILENAME,
-                                     entry.get_input_stream() { |is| is.read })
-
-      end
-    end
-  end
-end
-
-class ZipFileExtractTest < Test::Unit::TestCase
-  include CommonZipFileFixture
-  EXTRACTED_FILENAME                   = "extEntry"
-  ENTRY_TO_EXTRACT, *REMAINING_ENTRIES = TEST_ZIP.entry_names.reverse
-
-  def setup
-    super
-    ::File.delete(EXTRACTED_FILENAME) if ::File.exists?(EXTRACTED_FILENAME)
-  end
-
-  def test_extract
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      zf.extract(ENTRY_TO_EXTRACT, EXTRACTED_FILENAME)
-
-      assert(File.exists?(EXTRACTED_FILENAME))
-      AssertEntry::assert_contents(EXTRACTED_FILENAME,
-                                   zf.get_input_stream(ENTRY_TO_EXTRACT) { |is| is.read })
-
-
-      ::File.unlink(EXTRACTED_FILENAME)
-
-      entry = zf.get_entry(ENTRY_TO_EXTRACT)
-      entry.extract(EXTRACTED_FILENAME)
-
-      assert(File.exists?(EXTRACTED_FILENAME))
-      AssertEntry::assert_contents(EXTRACTED_FILENAME,
-                                   entry.get_input_stream() { |is| is.read })
-
-    }
-  end
-
-  def test_extractExists
-    writtenText = "written text"
-    ::File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
-
-    assert_raise(ZipDestinationFileExistsError) {
-      ::Zip::File.open(TEST_ZIP.zip_name) { |zf|
-        zf.extract(zf.entries.first, EXTRACTED_FILENAME)
-      }
-    }
-    File.open(EXTRACTED_FILENAME, "r") { |f|
-      assert_equal(writtenText, f.read)
-    }
-  end
-
-  def test_extractExistsOverwrite
-    writtenText = "written text"
-    ::File.open(EXTRACTED_FILENAME, "w") { |f| f.write(writtenText) }
-
-    gotCalledCorrectly = false
-    ::Zip::File.open(TEST_ZIP.zip_name) {
-      |zf|
-      zf.extract(zf.entries.first, EXTRACTED_FILENAME) {
-        |entry, extractLoc|
-        gotCalledCorrectly = zf.entries.first == entry &&
-          extractLoc == EXTRACTED_FILENAME
-        true
-      }
-    }
-
-    assert(gotCalledCorrectly)
-    ::File.open(EXTRACTED_FILENAME, "r") {
-      |f|
-      assert(writtenText != f.read)
-    }
-  end
-
-  def test_extractNonEntry
-    zf = ::Zip::File.new(TEST_ZIP.zip_name)
-    assert_raise(Errno::ENOENT) { zf.extract("nonExistingEntry", "nonExistingEntry") }
-  ensure
-    zf.close if zf
-  end
-
-  def test_extractNonEntry2
-    outFile = "outfile"
-    assert_raise(Errno::ENOENT) {
-      zf       = ::Zip::File.new(TEST_ZIP.zip_name)
-      nonEntry = "hotdog-diddelidoo"
-      assert(!zf.entries.include?(nonEntry))
-      zf.extract(nonEntry, outFile)
-      zf.close
-    }
-    assert(!File.exists?(outFile))
-  end
-
-end
-
-class ZipFileExtractDirectoryTest < Test::Unit::TestCase
-  include CommonZipFileFixture
-  TEST_OUT_NAME = "emptyOutDir"
-
-  def open_zip(&aProc)
-    assert(aProc != nil)
-    ::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
-  end
-
-  def extract_test_dir(&aProc)
-    open_zip {
-      |zf|
-      zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
-    }
-  end
-
-  def setup
-    super
-
-    Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
-    File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
-  end
-
-  def test_extractDirectory
-    extract_test_dir
-    assert(File.directory?(TEST_OUT_NAME))
-  end
-
-  def test_extractDirectoryExistsAsDir
-    Dir.mkdir TEST_OUT_NAME
-    extract_test_dir
-    assert(File.directory?(TEST_OUT_NAME))
-  end
-
-  def test_extractDirectoryExistsAsFile
-    File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
-    assert_raise(ZipDestinationFileExistsError) { extract_test_dir }
-  end
-
-  def test_extractDirectoryExistsAsFileOverwrite
-    File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
-    gotCalled = false
-    extract_test_dir {
-      |entry, destPath|
-      gotCalled = true
-      assert_equal(TEST_OUT_NAME, destPath)
-      assert(entry.directory?)
-      true
-    }
-    assert(gotCalled)
-    assert(File.directory?(TEST_OUT_NAME))
-  end
-end
-
-class ZipExtraFieldTest < Test::Unit::TestCase
-  def test_new
-    extra_pure    = ::Zip::ExtraField.new("")
-    extra_withstr = ::Zip::ExtraField.new("foo")
-    assert_instance_of(::Zip::ExtraField, extra_pure)
-    assert_instance_of(::Zip::ExtraField, extra_withstr)
-  end
-
-  def test_unknownfield
-    extra = ::Zip::ExtraField.new("foo")
-    assert_equal(extra["Unknown"], "foo")
-    extra.merge("a")
-    assert_equal(extra["Unknown"], "fooa")
-    extra.merge("barbaz")
-    assert_equal(extra.to_s, "fooabarbaz")
-  end
-
-
-  def test_merge
-    str    = "UT\x5\0\x3\250$\r at Ux\0\0"
-    extra1 = ::Zip::ExtraField.new("")
-    extra2 = ::Zip::ExtraField.new(str)
-    assert(!extra1.member?("UniversalTime"))
-    assert(extra2.member?("UniversalTime"))
-    extra1.merge(str)
-    assert_equal(extra1["UniversalTime"].mtime, extra2["UniversalTime"].mtime)
-  end
-
-  def test_length
-    str   = "UT\x5\0\x3\250$\r at Ux\0\0Te\0\0testit"
-    extra = ::Zip::ExtraField.new(str)
-    assert_equal(extra.local_size, extra.to_local_bin.size)
-    assert_equal(extra.c_dir_size, extra.to_c_dir_bin.size)
-    extra.merge("foo")
-    assert_equal(extra.local_size, extra.to_local_bin.size)
-    assert_equal(extra.c_dir_size, extra.to_c_dir_bin.size)
-  end
-
-
-  def test_to_s
-    str   = "UT\x5\0\x3\250$\r at Ux\0\0Te\0\0testit"
-    extra = ::Zip::ExtraField.new(str)
-    assert_instance_of(String, extra.to_s)
-
-    s = extra.to_s
-    extra.merge("foo")
-    assert_equal(s.length + 3, extra.to_s.length)
-  end
-
-  def test_equality
-    str    = "UT\x5\0\x3\250$\r@"
-    extra1 = ::Zip::ExtraField.new(str)
-    extra2 = ::Zip::ExtraField.new(str)
-    extra3 = ::Zip::ExtraField.new(str)
-    assert_equal(extra1, extra2)
-
-    extra2["UniversalTime"].mtime = ::Zip::DOSTime.now
-    assert(extra1 != extra2)
-
-    extra3.create("IUnix")
-    assert(extra1 != extra3)
-
-    extra1.create("IUnix")
-    assert_equal(extra1, extra3)
-  end
-
-end
-
-class ZipUnicodeFileNamesAndComments < Test::Unit::TestCase
-
-  FILENAME = File.join(File.dirname(__FILE__), "test1.zip")
-
-  def test_unicode
-    file_entrys      = ["текстовыйфайл.txt", "Résumé.txt", "슬레이어스휘.txt"]
-    directory_entrys = ["папка/текстовыйфайл.txt", "Résumé/Résumé.txt", "슬레이어스휘/슬레이어스휘.txt"]
-    stream           = ::Zip::OutputStream.open(FILENAME) do |io|
-      file_entrys.each do |filename|
-        io.put_next_entry(filename)
-        io.write(filename)
-      end
-      directory_entrys.each do |filepath|
-        io.put_next_entry(filepath)
-        io.write(filepath)
-      end
-    end
-    assert(!stream.nil?)
-    ::Zip::InputStream.open(FILENAME) do |io|
-      file_entrys.each do |filename|
-        entry      = io.get_next_entry
-        entry_name = entry.name
-        entry_name = entry_name.force_encoding("UTF-8") if RUBY_VERSION >= '1.9'
-        assert(filename == entry_name)
-      end
-      directory_entrys.each do |filepath|
-        entry      = io.get_next_entry
-        entry_name = entry.name
-        entry_name = entry_name.force_encoding("UTF-8") if RUBY_VERSION >= '1.9'
-        assert(filepath == entry_name)
-      end
-    end
-    ::File.unlink(FILENAME)
-  end
-
-end
-
-
-class Zip64SupportTest < Test::Unit::TestCase
-  TEST_FILE = File.join(File.dirname(__FILE__), 'data', 'zip64-sample.zip')
-
-  def test_open_zip64_file
-    zip_file = ::Zip::File.open(TEST_FILE)
-    assert(!zip_file.nil?)
-    assert(zip_file.entries.count == 2)
-    test_rb = zip_file.entries.find{|x| x.name == 'test.rb'}
-    assert(test_rb.size == 482)
-    assert(test_rb.compressed_size == 229)
-  end
-
-end
-
-class ZipSettingsTest < Test::Unit::TestCase
-  # TODO Refactor out into common test module
-  include CommonZipFileFixture
-  TEST_OUT_NAME = "emptyOutDir"
-
-  def setup
-    super
-
-    Dir.rmdir(TEST_OUT_NAME) if File.directory? TEST_OUT_NAME
-    File.delete(TEST_OUT_NAME) if File.exists? TEST_OUT_NAME
-  end
-
-  def open_zip(&aProc)
-    assert(aProc != nil)
-    ::Zip::File.open(TestZipFile::TEST_ZIP4.zip_name, &aProc)
-  end
-
-  def extract_test_dir(&aProc)
-    open_zip {
-      |zf|
-      zf.extract(TestFiles::EMPTY_TEST_DIR, TEST_OUT_NAME, &aProc)
-    }
-  end
-
-  def test_true_on_exists_proc
-    Zip.on_exists_proc = true
-    File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
-    extract_test_dir
-    assert(File.directory?(TEST_OUT_NAME))
-  end
-
-  def test_false_on_exists_proc
-    Zip.on_exists_proc = false
-    File.open(TEST_OUT_NAME, "w") { |f| f.puts "something" }
-    assert_raise(Zip::ZipDestinationFileExistsError) { extract_test_dir }
-  end
-
-  def test_false_continue_on_exists_proc
-    Zip.continue_on_exists_proc = false
-
-    assert_raise(ZipEntryExistsError) do
-      ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
-        zf.add(zf.entries.first.name, "data/file2.txt")
-      end
-    end
-  end
-
-  def test_true_continue_on_exists_proc
-    Zip.continue_on_exists_proc = true
-
-    replacedEntry = nil
-
-    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
-      replacedEntry = zf.entries.first.name
-      zf.add(replacedEntry, "data/file2.txt")
-    end
-
-    ::Zip::File.open(TEST_ZIP.zip_name) do |zf|
-      assert_contains(zf, replacedEntry, "data/file2.txt")
-    end
-  end
-
-  private
-  def assert_contains(zf, entryName, filename = entryName)
-    assert(zf.entries.detect { |e| e.name == entryName } != nil, "entry #{entryName} not in #{zf.entries.join(', ')} in zip file #{zf}")
-    assert_entryContents(zf, entryName, filename) if File.exists?(filename)
-  end
-end
-
-
-# Copyright (C) 2002-2005 Thomas Sondergaard
-# rubyzip is free software; you can redistribute it and/or
-# modify it under the terms of the ruby license.
diff --git a/testAllRubies.sh b/testAllRubies.sh
deleted file mode 100755
index a23177f..0000000
--- a/testAllRubies.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-for i in ree 1.8.7 1.9.2 1.9.3; do
-  git clean -nfx
-  rvm $i do rake
-done

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-zip.git



More information about the Pkg-ruby-extras-commits mailing list