Index: src/org/jruby/RubyZlib.java
===================================================================
--- src/org/jruby/RubyZlib.java	(revision 8313)
+++ src/org/jruby/RubyZlib.java	(working copy)
@@ -589,8 +589,8 @@
         @JRubyClass(name="Zlib::GzipFile::LengthError", parent="Zlib::GzipFile::Error")
         public static class LengthError extends Error {}
 
-        private static IRubyObject wrap(ThreadContext context, RubyGzipFile instance, 
-                IRubyObject io, Block block) throws IOException {
+        private static IRubyObject wrapBlock(ThreadContext context, RubyGzipFile instance, 
+                Block block) throws IOException {
             if (block.isGiven()) {
                 try {
                     block.yield(context, instance);
@@ -601,7 +601,7 @@
                 }
             }
             
-            return io;
+            return instance;
         }
         
         @JRubyMethod(name = "wrap", required = 1, frame = true, meta = true)
@@ -616,7 +616,7 @@
                 instance = RubyGzipReader.newInstance(recv, new IRubyObject[] { io }, block);
             }
 
-            return wrap(context, instance, io, block);
+            return wrapBlock(context, instance, block);
         }
         
         protected static final ObjectAllocator GZIPFILE_ALLOCATOR = new ObjectAllocator() {
@@ -741,9 +741,8 @@
         public static IRubyObject open(final ThreadContext context, IRubyObject recv, IRubyObject filename, Block block) throws IOException {
             Ruby runtime = recv.getRuntime();
             IRubyObject io = RuntimeHelpers.invoke(context, runtime.getFile(), "open", filename, runtime.newString("rb"));
-            RubyGzipFile instance = newInstance(recv, new IRubyObject[]{io}, Block.NULL_BLOCK);
-
-            return RubyGzipFile.wrap(context, instance, io, block);
+            RubyGzipReader gzio = newInstance(recv, new IRubyObject[]{io}, block);
+            return RubyGzipFile.wrapBlock(context, gzio, block);
         }
 
         public RubyGzipReader(Ruby runtime, RubyClass type) {
@@ -803,6 +802,11 @@
                 result.append((byte)ce);
                 ce = io.read();
             }
+            // io.available() only returns 0 after EOF is encountered
+            // so we need to differentiate between the empty string and EOF
+            if (0 == result.length()) {
+              return getRuntime().getNil();
+            }
             line++;
             result.append(sep);
             return RubyString.newString(getRuntime(),result);
@@ -881,7 +885,7 @@
         }
 
         private boolean isEof() throws IOException {
-            return ((GZIPInputStream)io).available() != 1;
+            return ((GZIPInputStream)io).available() == 0;
         }
 
         @JRubyMethod(name = "close")
@@ -920,13 +924,17 @@
             if (args.length > 0 && !args[0].isNil()) {
                 sep = args[0].convertToString().getByteList();
             }
-
-            while (!isEof()) {
-                block.yield(context, internalSepGets(sep));
+            for (IRubyObject result = internalSepGets(sep); !result.isNil(); result = internalSepGets(sep)) {
+                block.yield(context, result);
             }
             
             return getRuntime().getNil();
         }
+
+        @JRubyMethod(name = "each_line", optional = 1, frame = true)
+        public IRubyObject each_line(ThreadContext context, IRubyObject[] args, Block block) throws IOException {
+          return each(context, args, block);
+        }
     
         @JRubyMethod(name = "ungetc", required = 1)
         public IRubyObject ungetc(IRubyObject arg) {
@@ -940,12 +948,12 @@
             if (args.length != 0 && args[0].isNil()) {
                 array.add(read(new IRubyObject[0]));
             } else {
-                ByteList seperator = ((RubyString)getRuntime().getGlobalVariables().get("$/")).getByteList();
+                ByteList sep = ((RubyString)getRuntime().getGlobalVariables().get("$/")).getByteList();
                 if (args.length > 0) {
-                    seperator = args[0].convertToString().getByteList();
+                    sep = args[0].convertToString().getByteList();
                 }
-                while (!isEof()) {
-                    array.add(internalSepGets(seperator));
+                for (IRubyObject result = internalSepGets(sep); !result.isNil(); result = internalSepGets(sep)) {
+                    array.add(result);
                 }
             }
             return getRuntime().newArray(array);
@@ -993,9 +1001,8 @@
             }
 
             IRubyObject io = RuntimeHelpers.invoke(context, runtime.getFile(), "open", args[0], runtime.newString("wb"));
-            RubyGzipFile instance = newGzipWriter(recv, new IRubyObject[]{io, level, strategy}, Block.NULL_BLOCK);
-            
-            return RubyGzipFile.wrap(context, instance, io, block);
+            RubyGzipWriter gzio = newGzipWriter(recv, new IRubyObject[]{io, level, strategy}, block);
+            return RubyGzipFile.wrapBlock(context, gzio, block);
         }
 
         public RubyGzipWriter(Ruby runtime, RubyClass type) {
Index: test/test_zlib.rb
===================================================================
--- test/test_zlib.rb	(revision 8313)
+++ test/test_zlib.rb	(working copy)
@@ -44,14 +44,29 @@
 
   def test_gzip_reader_writer
     @filename = "____temp_zlib_file";
+    
     Zlib::GzipWriter.open(@filename) { |z| z.puts 'HEH' }
-    Zlib::GzipReader.open(@filename) { |z| assert_equal("HEH\n", z.gets) }
+    Zlib::GzipReader.open(@filename) do |z|
+      assert_equal("HEH\n", z.gets)
+      assert_nil z.getc
+      assert z.eof?
+    end
+    File.unlink(@filename)
+    
+    Zlib::GzipWriter.open(@filename) { |z| z.write "HEH\n" }
+    Zlib::GzipReader.open(@filename) do |z|
+      assert_equal("HEH\n", z.gets)
+      assert_nil z.getc
+      assert z.eof?
+    end
+    File.unlink(@filename)
+    
 
     z = Zlib::GzipWriter.open(@filename)
     z.puts 'HOH'
     z.puts 'foo|bar'
     z.close
-
+    
     z = Zlib::GzipReader.open(@filename)
     assert_equal("HOH\n", z.gets)
     assert_equal("foo|", z.gets("|"))
@@ -111,6 +126,36 @@
 
     gin = Zlib::GzipReader.new(content)
     assert_equal("hello\n", gin.gets)
+    assert_equal("world\n", gin.gets)
+    assert_nil gin.gets
+    assert gin.eof?
     gin.close
   end
+  
+  def test_each_line_no_block
+    @filename = "____temp_zlib_file";
+    Zlib::GzipWriter.open(@filename) { |io| io.write "hello\nworld\n" }
+    lines = []
+    z = Zlib::GzipReader.open(@filename)
+    z.each_line do |line|
+      lines << line
+    end
+    z.close
+    
+    assert_equal(2, lines.size, lines.inspect)
+    assert_equal("hello\n", lines.first)
+    assert_equal("world\n", lines.last)
+  end
+  
+  def test_each_line_block
+    @filename = "____temp_zlib_file";
+    Zlib::GzipWriter.open(@filename) { |io| io.write "hello\nworld\n" }
+    lines = []
+    Zlib::GzipReader.open(@filename) do |z|
+      z.each_line do |line|
+        lines << line
+      end
+    end
+    assert_equal(2, lines.size, lines.inspect)
+  end
 end

