diff --git a/.bundle/config b/.bundle/config
new file mode 100644
index 0000000..5fa58dd
--- /dev/null
+++ b/.bundle/config
@@ -0,0 +1,2 @@
+---
+BUNDLE_WITHOUT: extras
diff --git a/.travis.yml b/.travis.yml
index 270d13e..d24a104 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,11 @@
 language: ruby
 script: "bundle exec rspec"
 bundler_args: "--without extras"
+before_install:
+  - gem update --system
+  - gem update bundler
+  - gem cleanup bundler
 rvm:
-  - "2.1.0"
-  - "1.9.3"
-  - "jruby-19mode"
+  - 2.4
+  - 2.3
+  - 2.2
diff --git a/debian/changelog b/debian/changelog
index cda3015..5f25e4f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-ruby-iniparse (1.4.2-2) UNRELEASED; urgency=medium
+ruby-iniparse (1.4.4-1) UNRELEASED; urgency=medium
 
   [ Antonio Terceiro ]
   * Remove myself from Uploaders:
@@ -6,7 +6,11 @@ ruby-iniparse (1.4.2-2) UNRELEASED; urgency=medium
   [ Utkarsh Gupta ]
   * Add salsa-ci.yml
 
- -- Utkarsh Gupta <guptautkarsh2102@gmail.com>  Tue, 13 Aug 2019 05:43:03 +0530
+  [ Debian Janitor ]
+  * New upstream release.
+  * Drop patch 0001-Port-test-suite-to-RSpec-3.patch, present upstream.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Thu, 12 Sep 2019 22:22:07 +0000
 
 ruby-iniparse (1.4.2-1) unstable; urgency=medium
 
diff --git a/debian/patches/0001-Port-test-suite-to-RSpec-3.patch b/debian/patches/0001-Port-test-suite-to-RSpec-3.patch
deleted file mode 100644
index 3b88719..0000000
--- a/debian/patches/0001-Port-test-suite-to-RSpec-3.patch
+++ /dev/null
@@ -1,2352 +0,0 @@
-From: Antonio Terceiro <terceiro@debian.org>
-Date: Sun, 5 Jun 2016 10:27:34 -0300
-Subject: Port test suite to RSpec 3
-
-transpec did all the work
----
- iniparse.gemspec                              |   2 +-
- spec/document_spec.rb                         |  44 +++---
- spec/fixture_spec.rb                          | 105 +++++++-------
- spec/generator/method_missing_spec.rb         |  26 ++--
- spec/generator/with_section_blocks_spec.rb    |  80 +++++------
- spec/generator/without_section_blocks_spec.rb |  32 ++---
- spec/iniparse_spec.rb                         |   8 +-
- spec/line_collection_spec.rb                  |  76 +++++-----
- spec/lines_spec.rb                            | 200 +++++++++++++-------------
- spec/parser/document_parsing_spec.rb          |  50 +++----
- spec/parser/line_parsing_spec.rb              | 130 ++++++++---------
- spec/spec_helper.rb                           |   4 +-
- spec/spec_helper_spec.rb                      |  76 +++++-----
- 13 files changed, 417 insertions(+), 416 deletions(-)
-
-diff --git a/iniparse.gemspec b/iniparse.gemspec
-index 7fec34d..bb54bb9 100644
---- a/iniparse.gemspec
-+++ b/iniparse.gemspec
-@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
-   s.extra_rdoc_files  = %w(LICENSE README.rdoc)
- 
-   # Dependencies.
--  s.add_development_dependency('rspec', '~> 2.14')
-+  s.add_development_dependency('rspec', '~> 3.4')
- 
-   # = MANIFEST =
-   s.files = %w[
-diff --git a/spec/document_spec.rb b/spec/document_spec.rb
-index 353a7d8..24081f5 100644
---- a/spec/document_spec.rb
-+++ b/spec/document_spec.rb
-@@ -3,28 +3,28 @@ require 'spec_helper'
- describe "IniParse::Document" do
-   it 'should have a +lines+ reader' do
-     methods = IniParse::Document.instance_methods.map { |m| m.to_sym }
--    methods.should include(:lines)
-+    expect(methods).to include(:lines)
-   end
- 
-   it 'should not have a +lines+ writer' do
-     methods = IniParse::Document.instance_methods.map { |m| m.to_sym }
--    methods.should_not include(:lines=)
-+    expect(methods).not_to include(:lines=)
-   end
- 
-   it 'should delegate #[] to +lines+' do
-     doc = IniParse::Document.new
--    doc.lines.should_receive(:[]).with('key')
-+    expect(doc.lines).to receive(:[]).with('key')
-     doc['key']
-   end
- 
-   it 'should call #each to +lines+' do
-     doc = IniParse::Document.new
--    doc.lines.should_receive(:each)
-+    expect(doc.lines).to receive(:each)
-     doc.each { |l| }
-   end
- 
-   it 'should be enumerable' do
--    IniParse::Document.included_modules.should include(Enumerable)
-+    expect(IniParse::Document.included_modules).to include(Enumerable)
- 
-     sections = [
-       IniParse::Lines::Section.new('first section'),
-@@ -34,7 +34,7 @@ describe "IniParse::Document" do
-     doc = IniParse::Document.new
-     doc.lines << sections[0] << sections[1]
- 
--    doc.map { |line| line }.should == sections
-+    expect(doc.map { |line| line }).to eq(sections)
-   end
- 
-   describe '#has_section?' do
-@@ -45,12 +45,12 @@ describe "IniParse::Document" do
-     end
- 
-     it 'should return true if a section with the given key exists' do
--      @doc.should have_section('first section')
--      @doc.should have_section('another section')
-+      expect(@doc).to have_section('first section')
-+      expect(@doc).to have_section('another section')
-     end
- 
-     it 'should return true if no section with the given key exists' do
--      @doc.should_not have_section('second section')
-+      expect(@doc).not_to have_section('second section')
-     end
-   end
- 
-@@ -70,22 +70,22 @@ describe "IniParse::Document" do
-     end
- 
-     it 'removes the section given a key' do
--      lambda { document.delete('first') }.
--        should change { document['first'] }.to(nil)
-+      expect { document.delete('first') }.
-+        to change { document['first'] }.to(nil)
-     end
- 
-     it 'removes the section given a Section' do
--      lambda { document.delete(document['first']) }.
--        should change { document['first'] }.to(nil)
-+      expect { document.delete(document['first']) }.
-+        to change { document['first'] }.to(nil)
-     end
- 
-     it 'removes the lines' do
--      lambda { document.delete('first') }.
--        should change { document.to_ini.match(/alpha/) }.to(nil)
-+      expect { document.delete('first') }.
-+        to change { document.to_ini.match(/alpha/) }.to(nil)
-     end
- 
-     it 'returns the document' do
--      document.delete('first').should eql(document)
-+      expect(document.delete('first')).to eql(document)
-     end
-   end
- 
-@@ -122,31 +122,31 @@ describe "IniParse::Document" do
-     describe 'when no path is given to save' do
-       it 'should save the INI document if a path was given when initialized' do
-         doc = IniParse::Document.new('/a/path/to/a/file.ini')
--        File.should_receive(:open).with('/a/path/to/a/file.ini', 'w')
-+        expect(File).to receive(:open).with('/a/path/to/a/file.ini', 'w')
-         doc.save
-       end
- 
-       it 'should raise IniParseError if no path was given when initialized' do
--        lambda { IniParse::Document.new.save }.should \
-+        expect { IniParse::Document.new.save }.to \
-           raise_error(IniParse::IniParseError)
-       end
-     end
- 
-     describe 'when a path is given to save' do
-       it "should update the document's +path+" do
--        File.stub(:open).and_return(true)
-+        allow(File).to receive(:open).and_return(true)
-         doc = IniParse::Document.new('/a/path/to/a/file.ini')
-         doc.save('/a/new/path.ini')
--        doc.path.should == '/a/new/path.ini'
-+        expect(doc.path).to eq('/a/new/path.ini')
-       end
- 
-       it 'should save the INI document to the given path' do
--        File.should_receive(:open).with('/a/new/path.ini', 'w')
-+        expect(File).to receive(:open).with('/a/new/path.ini', 'w')
-         IniParse::Document.new('/a/path/to/a/file.ini').save('/a/new/path.ini')
-       end
- 
-       it 'should raise IniParseError if no path was given when initialized' do
--        lambda { IniParse::Document.new.save }.should \
-+        expect { IniParse::Document.new.save }.to \
-           raise_error(IniParse::IniParseError)
-       end
-     end
-diff --git a/spec/fixture_spec.rb b/spec/fixture_spec.rb
-index 81eab3c..0c3c8e4 100644
---- a/spec/fixture_spec.rb
-+++ b/spec/fixture_spec.rb
-@@ -7,16 +7,16 @@ describe "IniParse" do
-     end
- 
-     it 'should parse without any errors' do
--      lambda { IniParse.parse(@fixture) }.should_not raise_error
-+      expect { IniParse.parse(@fixture) }.not_to raise_error
-     end
- 
-     it 'should have the correct sections' do
--      IniParse.parse(fixture('openttd.ini')).lines.keys.should == [
-+      expect(IniParse.parse(fixture('openttd.ini')).lines.keys).to eq([
-         'misc', 'music', 'difficulty', 'game_creation', 'vehicle',
-         'construction', 'station', 'economy', 'pf', 'order', 'gui', 'ai',
-         'locale', 'network', 'currency', 'servers', 'bans', 'news_display',
-         'version', 'preset-J', 'newgrf', 'newgrf-static'
--      ]
-+      ])
-     end
- 
-     it 'should have the correct options' do
-@@ -24,7 +24,7 @@ describe "IniParse" do
-       doc     = IniParse.parse(@fixture)
-       section = doc['misc']
- 
--      section.lines.keys.should == [
-+      expect(section.lines.keys).to eq([
-         'display_opt', 'news_ticker_sound', 'fullscreen', 'language',
-         'resolution', 'screenshot_format', 'savegame_format',
-         'rightclick_emulate', 'small_font', 'medium_font', 'large_font',
-@@ -32,26 +32,26 @@ describe "IniParse" do
-         'large_aa', 'sprite_cache_size', 'player_face',
-         'transparency_options', 'transparency_locks', 'invisibility_options',
-         'keyboard', 'keyboard_caps'
--      ]
-+      ])
- 
-       # Test some of the options.
--      section['display_opt'].should == 'SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|FULL_DETAIL|WAYPOINTS'
--      section['news_ticker_sound'].should be_false
--      section['language'].should == 'english_US.lng'
--      section['resolution'].should == '1680,936'
--      section['large_size'].should == 16
-+      expect(section['display_opt']).to eq('SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|FULL_DETAIL|WAYPOINTS')
-+      expect(section['news_ticker_sound']).to be_falsey
-+      expect(section['language']).to eq('english_US.lng')
-+      expect(section['resolution']).to eq('1680,936')
-+      expect(section['large_size']).to eq(16)
- 
-       # Test some other options.
--      doc['currency']['suffix'].should == '" credits"'
--      doc['news_display']['production_nobody'].should == 'summarized'
--      doc['version']['version_number'].should == '070039B0'
-+      expect(doc['currency']['suffix']).to eq('" credits"')
-+      expect(doc['news_display']['production_nobody']).to eq('summarized')
-+      expect(doc['version']['version_number']).to eq('070039B0')
- 
--      doc['preset-J']['gcf/1_other/BlackCC/mauvetoblackw.grf'].should be_nil
--      doc['preset-J']['gcf/1_other/OpenGFX/OpenGFX_-_newFaces_v0.1.grf'].should be_nil
-+      expect(doc['preset-J']['gcf/1_other/BlackCC/mauvetoblackw.grf']).to be_nil
-+      expect(doc['preset-J']['gcf/1_other/OpenGFX/OpenGFX_-_newFaces_v0.1.grf']).to be_nil
-     end
- 
-     it 'should be identical to the original when calling #to_ini' do
--      IniParse.parse(@fixture).to_ini.should == @fixture
-+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
-     end
-   end
- 
-@@ -61,14 +61,14 @@ describe "IniParse" do
-     end
- 
-     it 'should parse without any errors' do
--      lambda { IniParse.parse(@fixture) }.should_not raise_error
-+      expect { IniParse.parse(@fixture) }.not_to raise_error
-     end
- 
-     it 'should have the correct sections' do
--      IniParse.parse(fixture('race07.ini')).lines.keys.should == [
-+      expect(IniParse.parse(fixture('race07.ini')).lines.keys).to eq([
-         'Header', 'Race', 'Slot010', 'Slot016', 'Slot013', 'Slot018',
-         'Slot002', 'END'
--      ]
-+      ])
-     end
- 
-     it 'should have the correct options' do
-@@ -76,24 +76,24 @@ describe "IniParse" do
-       doc     = IniParse.parse(@fixture)
-       section = doc['Slot010']
- 
--      section.lines.keys.should == [
-+      expect(section.lines.keys).to eq([
-         'Driver', 'SteamUser', 'SteamId', 'Vehicle', 'Team', 'QualTime',
-         'Laps', 'Lap', 'LapDistanceTravelled', 'BestLap', 'RaceTime'
--      ]
-+      ])
- 
-       # Test some of the options.
--      section['Driver'].should == 'Mark Voss'
--      section['SteamUser'].should == 'mvoss'
--      section['SteamId'].should == 1865369
--      section['Vehicle'].should == 'Chevrolet Lacetti 2007'
--      section['Team'].should == 'TEMPLATE_TEAM'
--      section['QualTime'].should == '1:37.839'
--      section['Laps'].should == 13
--      section['LapDistanceTravelled'].should == 3857.750244
--      section['BestLap'].should == '1:38.031'
--      section['RaceTime'].should == '0:21:38.988'
--
--      section['Lap'].should == [
-+      expect(section['Driver']).to eq('Mark Voss')
-+      expect(section['SteamUser']).to eq('mvoss')
-+      expect(section['SteamId']).to eq(1865369)
-+      expect(section['Vehicle']).to eq('Chevrolet Lacetti 2007')
-+      expect(section['Team']).to eq('TEMPLATE_TEAM')
-+      expect(section['QualTime']).to eq('1:37.839')
-+      expect(section['Laps']).to eq(13)
-+      expect(section['LapDistanceTravelled']).to eq(3857.750244)
-+      expect(section['BestLap']).to eq('1:38.031')
-+      expect(section['RaceTime']).to eq('0:21:38.988')
-+
-+      expect(section['Lap']).to eq([
-         '(0, -1.000, 1:48.697)',   '(1, 89.397, 1:39.455)',
-         '(2, 198.095, 1:38.060)',  '(3, 297.550, 1:38.632)',
-         '(4, 395.610, 1:38.031)',  '(5, 494.242, 1:39.562)',
-@@ -101,20 +101,19 @@ describe "IniParse" do
-         '(8, 791.785, 1:39.889)',  '(9, 890.151, 1:39.420)',
-         '(10, 990.040, 1:39.401)', '(11, 1089.460, 1:39.506)',
-         '(12, 1188.862, 1:40.017)'
--      ]
-+      ])
- 
--      doc['Header']['Version'].should == '1.1.1.14'
--      doc['Header']['TimeString'].should == '2008/09/13 23:26:32'
--      doc['Header']['Aids'].should == '0,0,0,0,0,1,1,0,0'
-+      expect(doc['Header']['Version']).to eq('1.1.1.14')
-+      expect(doc['Header']['TimeString']).to eq('2008/09/13 23:26:32')
-+      expect(doc['Header']['Aids']).to eq('0,0,0,0,0,1,1,0,0')
- 
--      doc['Race']['AIDB'].should == 'GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW'
--      doc['Race']['Race Length'].should == 0.1
-+      expect(doc['Race']['AIDB']).to eq('GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW')
-+      expect(doc['Race']['Race Length']).to eq(0.1)
-     end
- 
-     it 'should be identical to the original when calling #to_ini' do
--      pending('awaiting presevation (or lack) of whitespace around =') do
--        IniParse.parse(@fixture).to_ini.should == @fixture
--      end
-+      pending('awaiting presevation (or lack) of whitespace around =')
-+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
-     end
-   end
- 
-@@ -124,13 +123,13 @@ describe "IniParse" do
-     end
- 
-     it 'should parse without any errors' do
--      lambda { IniParse.parse(@fixture) }.should_not raise_error
-+      expect { IniParse.parse(@fixture) }.not_to raise_error
-     end
- 
-     it 'should have the correct sections' do
--      IniParse.parse(@fixture).lines.keys.should == [
-+      expect(IniParse.parse(@fixture).lines.keys).to eq([
-         'global', 'printers'
--      ]
-+      ])
-     end
- 
-     it 'should have the correct options' do
-@@ -138,7 +137,7 @@ describe "IniParse" do
-       doc     = IniParse.parse(@fixture)
-       section = doc['global']
- 
--      section.lines.keys.should == [
-+      expect(section.lines.keys).to eq([
-         'debug pid', 'log level', 'server string', 'printcap name',
-         'printing', 'encrypt passwords', 'use spnego', 'passdb backend',
-         'idmap domains', 'idmap config default: default',
-@@ -152,15 +151,15 @@ describe "IniParse" do
-         'usershare allow full config', 'com.apple:filter shares by access',
-         'obey pam restrictions', 'acl check permissions',
-         'name resolve order', 'include'
--      ]
-+      ])
- 
--      section['display charset'].should == 'UTF-8-MAC'
--      section['vfs objects'].should == 'darwinacl,darwin_streams'
--      section['usershare path'].should == '/var/samba/shares'
-+      expect(section['display charset']).to eq('UTF-8-MAC')
-+      expect(section['vfs objects']).to eq('darwinacl,darwin_streams')
-+      expect(section['usershare path']).to eq('/var/samba/shares')
-     end
- 
-     it 'should be identical to the original when calling #to_ini' do
--      IniParse.parse(@fixture).to_ini.should == @fixture
-+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
-     end
-   end
- 
-@@ -170,7 +169,7 @@ describe "IniParse" do
-     end
- 
-     it 'should be identical to the original when calling #to_ini' do
--      IniParse.parse(@fixture).to_ini.should == @fixture
-+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
-     end
-   end
- 
-@@ -180,7 +179,7 @@ describe "IniParse" do
-     end
- 
-     it 'should be identical to the original when calling #to_ini' do
--      IniParse.parse(@fixture).to_ini.should == @fixture
-+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
-     end
-   end
- end
-diff --git a/spec/generator/method_missing_spec.rb b/spec/generator/method_missing_spec.rb
-index 9fc1540..9370cb1 100644
---- a/spec/generator/method_missing_spec.rb
-+++ b/spec/generator/method_missing_spec.rb
-@@ -23,23 +23,23 @@ describe 'When generating a document using Generator with section blocks using m
-       IniParse::Generator.gen do |doc|
-         doc.a_section do |section|
-           %w( option comment blank ).each do |meth|
--            section.should respond_to(meth)
-+            expect(section).to respond_to(meth)
-           end
-         end
-       end
-     end
- 
-     it 'should add a Section to the document' do
--      IniParse::Generator.gen do |doc|
-+      expect(IniParse::Generator.gen do |doc|
-         doc.a_section { |section| }
--      end.should have_section("a_section")
-+      end).to have_section("a_section")
-     end
- 
-     it 'should change the Generator context to the section during the section block' do
-       IniParse::Generator.gen do |doc|
-         doc.a_section do |section|
--          section.context.should be_kind_of(IniParse::Lines::Section)
--          section.context.key.should == "a_section"
-+          expect(section.context).to be_kind_of(IniParse::Lines::Section)
-+          expect(section.context.key).to eq("a_section")
-         end
-       end
-     end
-@@ -47,24 +47,24 @@ describe 'When generating a document using Generator with section blocks using m
-     it 'should reset the Generator context to the document after the section block' do
-       IniParse::Generator.gen do |doc|
-         doc.a_section { |section| }
--        doc.context.should be_kind_of(IniParse::Document)
-+        expect(doc.context).to be_kind_of(IniParse::Document)
-       end
-     end
- 
-     it 'should append a blank line to the document, after the section' do
--      IniParse::Generator.gen do |doc|
-+      expect(IniParse::Generator.gen do |doc|
-         doc.a_section { |section| }
--      end.lines.to_a.last.should be_kind_of(IniParse::Lines::Blank)
-+      end.lines.to_a.last).to be_kind_of(IniParse::Lines::Blank)
-     end
- 
-     it 'should raise a LineNotAllowed if you attempt to nest a section' do
--      lambda do
-+      expect do
-         IniParse::Generator.gen do |doc|
-           doc.a_section do |section_one|
-             section_one.another_section { |section_two| }
-           end
-         end
--      end.should raise_error(IniParse::LineNotAllowed)
-+      end.to raise_error(IniParse::LineNotAllowed)
-     end
-   end
- 
-@@ -78,7 +78,7 @@ describe 'When generating a document using Generator with section blocks using m
-     describe 'when the context is a Document' do
-       it "adds the option to an __anonymous__ section" do
-         doc = IniParse::Generator.gen { |doc| doc.my_option = "a value" }
--        doc['__anonymous__']['my_option'].should eql('a value')
-+        expect(doc['__anonymous__']['my_option']).to eql('a value')
-       end
-     end
- 
-@@ -91,8 +91,8 @@ describe 'When generating a document using Generator with section blocks using m
-         end
- 
-         section = document["a_section"]
--        section.should have_option("my_option")
--        section["my_option"].should == "a value"
-+        expect(section).to have_option("my_option")
-+        expect(section["my_option"]).to eq("a value")
-       end
-     end
-   end
-diff --git a/spec/generator/with_section_blocks_spec.rb b/spec/generator/with_section_blocks_spec.rb
-index da82840..4af5009 100644
---- a/spec/generator/with_section_blocks_spec.rb
-+++ b/spec/generator/with_section_blocks_spec.rb
-@@ -13,17 +13,17 @@ require 'spec_helper'
- describe 'When generating a document using Generator with section blocks,' do
- 
-   it 'should be able to compile an empty document' do
--    lambda { IniParse::Generator.gen { |doc| } }.should_not raise_error
-+    expect { IniParse::Generator.gen { |doc| } }.not_to raise_error
-   end
- 
-   it 'should raise LocalJumpError if no block is given' do
--    lambda { IniParse::Generator.gen }.should raise_error(LocalJumpError)
-+    expect { IniParse::Generator.gen }.to raise_error(LocalJumpError)
-   end
- 
-   it "should yield an object with generator methods" do
-     IniParse::Generator.gen do |doc|
-       %w( section option comment blank ).each do |meth|
--        doc.should respond_to(meth)
-+        expect(doc).to respond_to(meth)
-       end
-     end
-   end
-@@ -39,23 +39,23 @@ describe 'When generating a document using Generator with section blocks,' do
-       IniParse::Generator.gen do |doc|
-         doc.section("a section") do |section|
-           %w( option comment blank ).each do |meth|
--            section.should respond_to(meth)
-+            expect(section).to respond_to(meth)
-           end
-         end
-       end
-     end
- 
-     it 'should add a Section to the document' do
--      IniParse::Generator.gen do |doc|
-+      expect(IniParse::Generator.gen do |doc|
-         doc.section("a section") { |section| }
--      end.should have_section("a section")
-+      end).to have_section("a section")
-     end
- 
-     it 'should change the Generator context to the section during the section block' do
-       IniParse::Generator.gen do |doc|
-         doc.section("a section") do |section|
--          section.context.should be_kind_of(IniParse::Lines::Section)
--          section.context.key.should == "a section"
-+          expect(section.context).to be_kind_of(IniParse::Lines::Section)
-+          expect(section.context.key).to eq("a section")
-         end
-       end
-     end
-@@ -63,7 +63,7 @@ describe 'When generating a document using Generator with section blocks,' do
-     it 'should reset the Generator context to the document after the section block' do
-       IniParse::Generator.gen do |doc|
-         doc.section("a section") { |section| }
--        doc.context.should be_kind_of(IniParse::Document)
-+        expect(doc.context).to be_kind_of(IniParse::Document)
-       end
-     end
- 
-@@ -72,7 +72,7 @@ describe 'When generating a document using Generator with section blocks,' do
-         doc.section("a section") { |section| }
-       end
- 
--      document["a section"].to_ini.should match(/\A    /)
-+      expect(document["a section"].to_ini).to match(/\A    /)
-     end
- 
-     it 'should pass extra options to the Section instance' do
-@@ -80,23 +80,23 @@ describe 'When generating a document using Generator with section blocks,' do
-         doc.section("a section", :indent => '    ') { |section| }
-       end
- 
--      document["a section"].to_ini.should match(/\A    /)
-+      expect(document["a section"].to_ini).to match(/\A    /)
-     end
- 
-     it 'should append a blank line to the document, after the section' do
--      IniParse::Generator.gen do |doc|
-+      expect(IniParse::Generator.gen do |doc|
-         doc.section("a section") { |section| }
--      end.lines.to_a.last.should be_kind_of(IniParse::Lines::Blank)
-+      end.lines.to_a.last).to be_kind_of(IniParse::Lines::Blank)
-     end
- 
-     it 'should raise a LineNotAllowed if you attempt to nest a section' do
--      lambda do
-+      expect do
-         IniParse::Generator.gen do |doc|
-           doc.section("a section") do |section_one|
-             section_one.section("another_section") { |section_two| }
-           end
-         end
--      end.should raise_error(IniParse::LineNotAllowed)
-+      end.to raise_error(IniParse::LineNotAllowed)
-     end
-   end
- 
-@@ -114,7 +114,7 @@ describe 'When generating a document using Generator with section blocks,' do
-           doc.option("my option", "a value")
-         end
- 
--        document['__anonymous__']['my option'].should eql('a value')
-+        expect(document['__anonymous__']['my option']).to eql('a value')
-       end
-     end
- 
-@@ -127,8 +127,8 @@ describe 'When generating a document using Generator with section blocks,' do
-         end
- 
-         section = document["a section"]
--        section.should have_option("my option")
--        section["my option"].should == "a value"
-+        expect(section).to have_option("my option")
-+        expect(section["my option"]).to eq("a value")
-       end
- 
-       it 'should pass extra options to the Option instance' do
-@@ -138,7 +138,7 @@ describe 'When generating a document using Generator with section blocks,' do
-           end
-         end
- 
--        document["a section"].option("my option").to_ini.should match(/^    /)
-+        expect(document["a section"].option("my option").to_ini).to match(/^    /)
-       end
- 
-       it "should use the parent document's options as a base" do
-@@ -148,7 +148,7 @@ describe 'When generating a document using Generator with section blocks,' do
-           end
-         end
- 
--        document["a section"].option("my option").to_ini.should match(/^    /)
-+        expect(document["a section"].option("my option").to_ini).to match(/^    /)
-       end
- 
-       it "should use the parent section's options as a base" do
-@@ -158,7 +158,7 @@ describe 'When generating a document using Generator with section blocks,' do
-           end
-         end
- 
--        document["a section"].option("my option").to_ini.should match(/^    /)
-+        expect(document["a section"].option("my option").to_ini).to match(/^    /)
-       end
- 
-       it "should allow customisation of the parent's options" do
-@@ -171,8 +171,8 @@ describe 'When generating a document using Generator with section blocks,' do
-         end
- 
-         option_ini = document["a section"].option("my option").to_ini
--        option_ini.should match(/^    /)
--        option_ini.should match(/ # a comment/)
-+        expect(option_ini).to match(/^    /)
-+        expect(option_ini).to match(/ # a comment/)
-       end
- 
-       it "should not use the parent section's comment when setting line options" do
-@@ -182,7 +182,7 @@ describe 'When generating a document using Generator with section blocks,' do
-           end
-         end
- 
--        document["a section"].option("my option").to_ini.should_not match(/My section$/)
-+        expect(document["a section"].option("my option").to_ini).not_to match(/My section$/)
-       end
-     end
-   end
-@@ -199,7 +199,7 @@ describe 'When generating a document using Generator with section blocks,' do
-         doc.comment("My comment", :indent => '    ')
-       end
- 
--      document.lines.to_a.first.to_ini.should match(/\A    /)
-+      expect(document.lines.to_a.first.to_ini).to match(/\A    /)
-     end
- 
-     it 'should ignore any extra :comment option' do
-@@ -207,8 +207,8 @@ describe 'When generating a document using Generator with section blocks,' do
-         doc.comment("My comment", :comment => 'Ignored')
-       end
- 
--      document.lines.to_a.first.to_ini.should match(/My comment/)
--      document.lines.to_a.first.to_ini.should_not match(/Ignored/)
-+      expect(document.lines.to_a.first.to_ini).to match(/My comment/)
-+      expect(document.lines.to_a.first.to_ini).not_to match(/Ignored/)
-     end
- 
-     describe 'when the context is a Document' do
-@@ -218,8 +218,8 @@ describe 'When generating a document using Generator with section blocks,' do
-         end
- 
-         comment = document.lines.to_a.first
--        comment.should be_kind_of(IniParse::Lines::Comment)
--        comment.to_ini.should match(/My comment/)
-+        expect(comment).to be_kind_of(IniParse::Lines::Comment)
-+        expect(comment.to_ini).to match(/My comment/)
-       end
- 
-       it 'should use the default line options as a base' do
-@@ -230,7 +230,7 @@ describe 'When generating a document using Generator with section blocks,' do
-         comment_ini = document.lines.to_a.first.to_ini
- 
-         # Match separator (;) and offset (0).
--        comment_ini.should == '; My comment'
-+        expect(comment_ini).to eq('; My comment')
-       end
-     end
- 
-@@ -243,8 +243,8 @@ describe 'When generating a document using Generator with section blocks,' do
-         end
- 
-         comment = document['a section'].lines.to_a.first
--        comment.should be_kind_of(IniParse::Lines::Comment)
--        comment.to_ini.should match(/My comment/)
-+        expect(comment).to be_kind_of(IniParse::Lines::Comment)
-+        expect(comment.to_ini).to match(/My comment/)
-       end
- 
-       it "should use the parent document's line options as a base" do
-@@ -254,7 +254,7 @@ describe 'When generating a document using Generator with section blocks,' do
-           end
-         end
- 
--        document['a section'].lines.to_a.first.to_ini.should match(/^     ;/)
-+        expect(document['a section'].lines.to_a.first.to_ini).to match(/^     ;/)
-       end
- 
-       it "should use the parent section's line options as a base" do
-@@ -264,7 +264,7 @@ describe 'When generating a document using Generator with section blocks,' do
-           end
-         end
- 
--        document['a section'].lines.to_a.first.to_ini.should match(/^     ;/)
-+        expect(document['a section'].lines.to_a.first.to_ini).to match(/^     ;/)
-       end
- 
-       it "should allow customisation of the parent's options" do
-@@ -275,8 +275,8 @@ describe 'When generating a document using Generator with section blocks,' do
-         end
- 
-         # Match separator (#) and offset (5)
--        document['a section'].lines.to_a.first.to_ini.should \
--          == '     # My comment'
-+        expect(document['a section'].lines.to_a.first.to_ini).to \
-+          eq('     # My comment')
-       end
- 
-       it "should not use the parent section's comment when setting line options" do
-@@ -287,8 +287,8 @@ describe 'When generating a document using Generator with section blocks,' do
-         end
- 
-         comment_ini = document['a section'].lines.to_a.first.to_ini
--        comment_ini.should match(/My comment/)
--        comment_ini.should_not match(/My section/)
-+        expect(comment_ini).to match(/My comment/)
-+        expect(comment_ini).not_to match(/My section/)
-       end
-     end
-   end
-@@ -305,7 +305,7 @@ describe 'When generating a document using Generator with section blocks,' do
-         doc.blank
-       end
- 
--      document.lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
-+      expect(document.lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
-     end
- 
-     it 'should add a blank line to the section when it is the context' do
-@@ -315,7 +315,7 @@ describe 'When generating a document using Generator with section blocks,' do
-         end
-       end
- 
--      document['a section'].lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
-+      expect(document['a section'].lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
-     end
-   end
- 
-diff --git a/spec/generator/without_section_blocks_spec.rb b/spec/generator/without_section_blocks_spec.rb
-index 00e0cea..1aba308 100644
---- a/spec/generator/without_section_blocks_spec.rb
-+++ b/spec/generator/without_section_blocks_spec.rb
-@@ -29,17 +29,17 @@ describe 'When generating a document using Generator without section blocks,' do
-   describe 'adding a section' do
-     it 'should add a Section to the document' do
-       @gen.section("a section")
--      @gen.document.should have_section("a section")
-+      expect(@gen.document).to have_section("a section")
-     end
- 
-     it 'should change the Generator context to the section' do
-       @gen.section("a section")
--      @gen.context.should == @gen.document['a section']
-+      expect(@gen.context).to eq(@gen.document['a section'])
-     end
- 
-     it 'should pass extra options to the Section instance' do
-       @gen.section("a section", :indent => '    ')
--      @gen.document["a section"].to_ini.should match(/\A    /)
-+      expect(@gen.document["a section"].to_ini).to match(/\A    /)
-     end
-   end
- 
-@@ -53,13 +53,13 @@ describe 'When generating a document using Generator without section blocks,' do
-     it 'should pass extra options to the Option instance' do
-       @gen.section("a section")
-       @gen.option("my option", "a value", :indent => '    ')
--      @gen.document["a section"].option("my option").to_ini.should match(/^    /)
-+      expect(@gen.document["a section"].option("my option").to_ini).to match(/^    /)
-     end
- 
-     describe 'when the context is a Document' do
-       it "should add the option to an __anonymous__ section" do
-         @gen.option("key", "value")
--        @gen.document['__anonymous__']['key'].should eql('value')
-+        expect(@gen.document['__anonymous__']['key']).to eql('value')
-       end
-     end
- 
-@@ -67,8 +67,8 @@ describe 'When generating a document using Generator without section blocks,' do
-       it 'should add the option to the section' do
-         @gen.section("a section")
-         @gen.option("my option", "a value")
--        @gen.document["a section"].should have_option("my option")
--        @gen.document["a section"]["my option"].should == "a value"
-+        expect(@gen.document["a section"]).to have_option("my option")
-+        expect(@gen.document["a section"]["my option"]).to eq("a value")
-       end
-     end
-   end
-@@ -82,22 +82,22 @@ describe 'When generating a document using Generator without section blocks,' do
-   describe 'adding a comment' do
-     it 'should pass extra options to the Option instance' do
-       @gen.comment("My comment", :indent => '    ')
--      @gen.document.lines.to_a.first.to_ini.should match(/^    /)
-+      expect(@gen.document.lines.to_a.first.to_ini).to match(/^    /)
-     end
- 
-     it 'should ignore any extra :comment option' do
-       @gen.comment("My comment", :comment => 'Ignored')
-       comment_ini = @gen.document.lines.to_a.first.to_ini
--      comment_ini.should match(/My comment/)
--      comment_ini.should_not match(/Ignored/)
-+      expect(comment_ini).to match(/My comment/)
-+      expect(comment_ini).not_to match(/Ignored/)
-     end
- 
-     describe 'when the context is a Document' do
-       it 'should add a comment to the document' do
-         @gen.comment('My comment')
-         comment = @gen.document.lines.to_a.first
--        comment.should be_kind_of(IniParse::Lines::Comment)
--        comment.to_ini.should match(/; My comment/)
-+        expect(comment).to be_kind_of(IniParse::Lines::Comment)
-+        expect(comment.to_ini).to match(/; My comment/)
-       end
-     end
- 
-@@ -106,8 +106,8 @@ describe 'When generating a document using Generator without section blocks,' do
-         @gen.section('a section')
-         @gen.comment('My comment')
-         comment = @gen.document['a section'].lines.to_a.first
--        comment.should be_kind_of(IniParse::Lines::Comment)
--        comment.to_ini.should match(/My comment/)
-+        expect(comment).to be_kind_of(IniParse::Lines::Comment)
-+        expect(comment.to_ini).to match(/My comment/)
-       end
-     end
-   end
-@@ -122,14 +122,14 @@ describe 'When generating a document using Generator without section blocks,' do
-     it 'should add a blank line to the document when it is the context' do
-       @gen.blank
-       comment = @gen.document.lines.to_a.first
--      comment.should be_kind_of(IniParse::Lines::Blank)
-+      expect(comment).to be_kind_of(IniParse::Lines::Blank)
-     end
- 
-     it 'should add a blank line to the section when it is the context' do
-       @gen.section('a section')
-       @gen.blank
-       comment = @gen.document['a section'].lines.to_a.first
--      comment.should be_kind_of(IniParse::Lines::Blank)
-+      expect(comment).to be_kind_of(IniParse::Lines::Blank)
-     end
-   end
- 
-diff --git a/spec/iniparse_spec.rb b/spec/iniparse_spec.rb
-index 0735660..6acebc9 100644
---- a/spec/iniparse_spec.rb
-+++ b/spec/iniparse_spec.rb
-@@ -45,18 +45,18 @@ describe "IniParse" do
-   end
- 
-   describe '.open' do
--    before(:each) { File.stub(:read).and_return('[section]') }
-+    before(:each) { allow(File).to receive(:read).and_return('[section]') }
- 
-     it 'should return an IniParse::Document' do
--      IniParse.open('/my/path.ini').should be_kind_of(IniParse::Document)
-+      expect(IniParse.open('/my/path.ini')).to be_kind_of(IniParse::Document)
-     end
- 
-     it 'should set the path on the returned Document' do
--      IniParse.open('/my/path.ini').path.should == '/my/path.ini'
-+      expect(IniParse.open('/my/path.ini').path).to eq('/my/path.ini')
-     end
- 
-     it 'should read the file at the given path' do
--      File.should_receive(:read).with('/my/path.ini').and_return('[section]')
-+      expect(File).to receive(:read).with('/my/path.ini').and_return('[section]')
-       IniParse.open('/my/path.ini')
-     end
-   end
-diff --git a/spec/line_collection_spec.rb b/spec/line_collection_spec.rb
-index fa0554c..85a0924 100644
---- a/spec/line_collection_spec.rb
-+++ b/spec/line_collection_spec.rb
-@@ -4,7 +4,7 @@ require 'spec_helper'
- # Shared specs for all Collection types...
- # ----------------------------------------------------------------------------
- 
--share_examples_for "LineCollection" do
-+shared_examples_for "LineCollection" do
-   before(:each) do
-     @collection << (@c1 = IniParse::Lines::Comment.new)
-     @collection <<  @i1
-@@ -16,7 +16,7 @@ share_examples_for "LineCollection" do
- 
-   describe '#each' do
-     it 'should remove blanks and comments by default' do
--      @collection.each { |l| l.should be_kind_of(@i1.class) }
-+      @collection.each { |l| expect(l).to be_kind_of(@i1.class) }
-     end
- 
-     it 'should not remove blanks and comments if true is given' do
-@@ -27,121 +27,121 @@ share_examples_for "LineCollection" do
-         arr << line
-       end
- 
--      arr.should == [@c1, @i1, @i2, @b1, @i3, @b2]
-+      expect(arr).to eq([@c1, @i1, @i2, @b1, @i3, @b2])
-     end
-   end
- 
-   describe '#[]' do
-     it 'should fetch the correct value' do
--      @collection['first'].should  == @i1
--      @collection['second'].should == @i2
--      @collection['third'].should  == @i3
-+      expect(@collection['first']).to  eq(@i1)
-+      expect(@collection['second']).to eq(@i2)
-+      expect(@collection['third']).to  eq(@i3)
-     end
- 
-     it 'should return nil if the given key does not exist' do
--      @collection['does not exist'].should be_nil
-+      expect(@collection['does not exist']).to be_nil
-     end
-   end
- 
-   describe '#[]=' do
-     it 'should successfully add a new key' do
-       @collection['fourth'] = @new
--      @collection['fourth'].should == @new
-+      expect(@collection['fourth']).to eq(@new)
-     end
- 
-     it 'should successfully update an existing key' do
-       @collection['second'] = @new
--      @collection['second'].should == @new
-+      expect(@collection['second']).to eq(@new)
- 
-       # Make sure the old data is gone.
--      @collection.detect { |s| s.key == 'second' }.should be_nil
-+      expect(@collection.detect { |s| s.key == 'second' }).to be_nil
-     end
- 
-     it 'should typecast given keys to a string' do
-       @collection[:a_symbol] = @new
--      @collection['a_symbol'].should == @new
-+      expect(@collection['a_symbol']).to eq(@new)
-     end
-   end
- 
-   describe '#<<' do
-     it 'should set the key correctly if given a new item' do
--      @collection.should_not have_key(@new.key)
-+      expect(@collection).not_to have_key(@new.key)
-       @collection << @new
--      @collection.should have_key(@new.key)
-+      expect(@collection).to have_key(@new.key)
-     end
- 
-     it 'should append Blank lines' do
-       @collection << IniParse::Lines::Blank.new
--      @collection.instance_variable_get(:@lines).last.should \
-+      expect(@collection.instance_variable_get(:@lines).last).to \
-         be_kind_of(IniParse::Lines::Blank)
-     end
- 
-     it 'should append Comment lines' do
-       @collection << IniParse::Lines::Comment.new
--      @collection.instance_variable_get(:@lines).last.should \
-+      expect(@collection.instance_variable_get(:@lines).last).to \
-         be_kind_of(IniParse::Lines::Comment)
-     end
- 
-     it 'should return self' do
--      (@collection << @new).should == @collection
-+      expect(@collection << @new).to eq(@collection)
-     end
-   end
- 
-   describe '#delete' do
-     it 'should remove the given value and adjust the indicies' do
--      @collection['second'].should_not be_nil
-+      expect(@collection['second']).not_to be_nil
-       @collection.delete('second')
--      @collection['second'].should be_nil
--      @collection['first'].should == @i1
--      @collection['third'].should == @i3
-+      expect(@collection['second']).to be_nil
-+      expect(@collection['first']).to eq(@i1)
-+      expect(@collection['third']).to eq(@i3)
-     end
- 
-     it "should do nothing if the supplied key does not exist" do
-       @collection.delete('does not exist')
--      @collection['first'].should == @i1
--      @collection['third'].should == @i3
-+      expect(@collection['first']).to eq(@i1)
-+      expect(@collection['third']).to eq(@i3)
-     end
-   end
- 
-   describe '#to_a' do
-     it 'should return an array' do
--      @collection.to_a.should be_kind_of(Array)
-+      expect(@collection.to_a).to be_kind_of(Array)
-     end
- 
-     it 'should include all lines' do
--      @collection.to_a.should == [@c1, @i1, @i2, @b1, @i3, @b2]
-+      expect(@collection.to_a).to eq([@c1, @i1, @i2, @b1, @i3, @b2])
-     end
- 
-     it 'should include references to the same line objects as the collection' do
-       @collection << @new
--      @collection.to_a.last.object_id.should == @new.object_id
-+      expect(@collection.to_a.last.object_id).to eq(@new.object_id)
-     end
-   end
- 
-   describe '#to_hash' do
-     it 'should return a hash' do
--      @collection.to_hash.should be_kind_of(Hash)
-+      expect(@collection.to_hash).to be_kind_of(Hash)
-     end
- 
-     it 'should have the correct keys' do
-       hash = @collection.to_hash
--      hash.keys.length.should == 3
--      hash.should have_key('first')
--      hash.should have_key('second')
--      hash.should have_key('third')
-+      expect(hash.keys.length).to eq(3)
-+      expect(hash).to have_key('first')
-+      expect(hash).to have_key('second')
-+      expect(hash).to have_key('third')
-     end
- 
-     it 'should have the correct values' do
-       hash = @collection.to_hash
--      hash['first'].should  == @i1
--      hash['second'].should == @i2
--      hash['third'].should  == @i3
-+      expect(hash['first']).to  eq(@i1)
-+      expect(hash['second']).to eq(@i2)
-+      expect(hash['third']).to  eq(@i3)
-     end
-   end
- 
-   describe '#keys' do
-     it 'should return an array of strings' do
--      @collection.keys.should == ['first', 'second', 'third']
-+      expect(@collection.keys).to eq(['first', 'second', 'third'])
-     end
-   end
- end
-@@ -163,7 +163,7 @@ describe 'IniParse::OptionCollection' do
- 
-   describe '#<<' do
-     it 'should raise a LineNotAllowed exception if a Section is pushed' do
--      lambda { @collection << IniParse::Lines::Section.new('s') }.should \
-+      expect { @collection << IniParse::Lines::Section.new('s') }.to \
-         raise_error(IniParse::LineNotAllowed)
-     end
- 
-@@ -174,7 +174,7 @@ describe 'IniParse::OptionCollection' do
-       @collection << option_one
-       @collection << option_two
- 
--      @collection['k'].should == [option_one, option_two]
-+      expect(@collection['k']).to eq([option_one, option_two])
-     end
-   end
- 
-@@ -182,7 +182,7 @@ describe 'IniParse::OptionCollection' do
-     it 'should handle duplicates' do
-       @collection << @i1 << @i2 << @i3
-       @collection << IniParse::Lines::Option.new('first', 'v5')
--      @collection.keys.should == ['first', 'second', 'third']
-+      expect(@collection.keys).to eq(['first', 'second', 'third'])
-     end
-   end
- end
-@@ -202,7 +202,7 @@ describe 'IniParse::SectionCollection' do
-     it 'should add merge Section with the other, if it is a duplicate' do
-       new_section = IniParse::Lines::Section.new('first')
-       @collection << @i1
--      @i1.should_receive(:merge!).with(new_section).once
-+      expect(@i1).to receive(:merge!).with(new_section).once
-       @collection << new_section
-     end
-   end
-diff --git a/spec/lines_spec.rb b/spec/lines_spec.rb
-index ec64945..c34a8cf 100644
---- a/spec/lines_spec.rb
-+++ b/spec/lines_spec.rb
-@@ -13,44 +13,44 @@ end
- describe "IniParse::Lines::Line module" do
-   describe '#to_ini' do
-     it 'should return +line_contents+' do
--      IniParse::Test::FakeLine.new.to_ini.should == 'fake line'
-+      expect(IniParse::Test::FakeLine.new.to_ini).to eq('fake line')
-     end
- 
-     it 'should preserve line indents' do
--      IniParse::Test::FakeLine.new(
-+      expect(IniParse::Test::FakeLine.new(
-         :indent => '    '
--      ).to_ini.should == '    fake line'
-+      ).to_ini).to eq('    fake line')
-     end
- 
-     describe 'when a comment is set' do
-       it 'should correctly include the comment' do
--        IniParse::Test::FakeLine.new(
-+        expect(IniParse::Test::FakeLine.new(
-           :comment => 'comment', :comment_sep => ';', :comment_offset => 10
--        ).to_ini.should == 'fake line ; comment'
-+        ).to_ini).to eq('fake line ; comment')
-       end
- 
-       it 'should correctly indent the comment' do
--        IniParse::Test::FakeLine.new(
-+        expect(IniParse::Test::FakeLine.new(
-           :comment => 'comment', :comment_sep => ';', :comment_offset => 15
--        ).to_ini.should == 'fake line      ; comment'
-+        ).to_ini).to eq('fake line      ; comment')
-       end
- 
-       it 'should use ";" as a default comment seperator' do
--        IniParse::Test::FakeLine.new(
-+        expect(IniParse::Test::FakeLine.new(
-           :comment => 'comment'
--        ).to_ini.should == 'fake line ; comment'
-+        ).to_ini).to eq('fake line ; comment')
-       end
- 
-       it 'should use the correct seperator' do
--        IniParse::Test::FakeLine.new(
-+        expect(IniParse::Test::FakeLine.new(
-           :comment => 'comment', :comment_sep => '#'
--        ).to_ini.should == 'fake line # comment'
-+        ).to_ini).to eq('fake line # comment')
-       end
- 
-       it 'should use the ensure a space is added before the comment seperator' do
--        IniParse::Test::FakeLine.new(
-+        expect(IniParse::Test::FakeLine.new(
-           :comment => 'comment', :comment_sep => ';', :comment_offset => 0
--        ).to_ini.should == 'fake line ; comment'
-+        ).to_ini).to eq('fake line ; comment')
-       end
- 
-       it 'should not add an extra space if the line is blank' do
-@@ -58,34 +58,34 @@ describe "IniParse::Lines::Line module" do
-           :comment => 'comment', :comment_sep => ';', :comment_offset => 0
-         )
- 
--        line.stub(:line_contents).and_return('')
--        line.to_ini.should == '; comment'
-+        allow(line).to receive(:line_contents).and_return('')
-+        expect(line.to_ini).to eq('; comment')
-       end
-     end
- 
-     describe 'when no comment is set' do
-       it 'should not add trailing space if :comment_offset has a value' do
--        IniParse::Test::FakeLine.new(:comment_offset => 10).to_ini.should == 'fake line'
-+        expect(IniParse::Test::FakeLine.new(:comment_offset => 10).to_ini).to eq('fake line')
-       end
- 
-       it 'should not add a comment seperator :comment_sep has a value' do
--        IniParse::Test::FakeLine.new(:comment_sep => ';').to_ini.should == 'fake line'
-+        expect(IniParse::Test::FakeLine.new(:comment_sep => ';').to_ini).to eq('fake line')
-       end
-     end
-   end
- 
-   describe '#has_comment?' do
-     it 'should return true if :comment has a non-blank value' do
--      IniParse::Test::FakeLine.new(:comment => 'comment').should have_comment
-+      expect(IniParse::Test::FakeLine.new(:comment => 'comment')).to have_comment
-     end
- 
-     it 'should return true if :comment has a blank value' do
--      IniParse::Test::FakeLine.new(:comment => '').should have_comment
-+      expect(IniParse::Test::FakeLine.new(:comment => '')).to have_comment
-     end
- 
-     it 'should return false if :comment has a nil value' do
--      IniParse::Test::FakeLine.new.should_not have_comment
--      IniParse::Test::FakeLine.new(:comment => nil).should_not have_comment
-+      expect(IniParse::Test::FakeLine.new).not_to have_comment
-+      expect(IniParse::Test::FakeLine.new(:comment => nil)).not_to have_comment
-     end
-   end
- end
-@@ -98,20 +98,20 @@ describe 'IniParse::Lines::Section' do
-   before(:each) { @section = IniParse::Lines::Section.new('a section') }
- 
-   it 'should respond_to +lines+' do
--    @section.should respond_to(:lines)
-+    expect(@section).to respond_to(:lines)
-   end
- 
-   it 'should not respond_to +lines=+' do
--    @section.should_not respond_to(:lines=)
-+    expect(@section).not_to respond_to(:lines=)
-   end
- 
-   it 'should include Enumerable' do
--    IniParse::Lines::Section.included_modules.should include(Enumerable)
-+    expect(IniParse::Lines::Section.included_modules).to include(Enumerable)
-   end
- 
-   describe '#initialize' do
-     it 'should typecast the given key to a string' do
--      IniParse::Lines::Section.new(:symbol).key.should == 'symbol'
-+      expect(IniParse::Lines::Section.new(:symbol).key).to eq('symbol')
-     end
-   end
- 
-@@ -119,68 +119,68 @@ describe 'IniParse::Lines::Section' do
-     it 'should retrieve the line identified by the given key' do
-       option = IniParse::Lines::Option.new('k', 'value one')
-       @section.lines << option
--      @section.option('k').should == option
-+      expect(@section.option('k')).to eq(option)
-     end
- 
-     it 'should return nil if the given key does not exist' do
--      @section.option('does_not_exist').should be_nil
-+      expect(@section.option('does_not_exist')).to be_nil
-     end
-   end
- 
-   describe '#each' do
-     it 'should call #each on +lines+' do
--      @section.lines.should_receive(:each)
-+      expect(@section.lines).to receive(:each)
-       @section.each { |l| }
-     end
-   end
- 
-   describe '#[]' do
-     it 'should return nil if the given key does not exist' do
--      @section['k'].should be_nil
-+      expect(@section['k']).to be_nil
-     end
- 
-     it 'should return a value if the given key exists' do
-       @section.lines << IniParse::Lines::Option.new('k', 'v')
--      @section['k'].should == 'v'
-+      expect(@section['k']).to eq('v')
-     end
- 
-     it 'should return an array of values if the key is a duplicate' do
-       @section.lines << IniParse::Lines::Option.new('k', 'v1')
-       @section.lines << IniParse::Lines::Option.new('k', 'v2')
-       @section.lines << IniParse::Lines::Option.new('k', 'v3')
--      @section['k'].should == ['v1', 'v2', 'v3']
-+      expect(@section['k']).to eq(['v1', 'v2', 'v3'])
-     end
- 
-     it 'should typecast the key to a string' do
-       @section.lines << IniParse::Lines::Option.new('k', 'v')
--      @section[:k].should == 'v'
-+      expect(@section[:k]).to eq('v')
-     end
-   end
- 
-   describe '#[]=' do
-     it 'should add a new Option with the given key and value' do
-       @section['k'] = 'a value'
--      @section.option('k').should be_kind_of(IniParse::Lines::Option)
--      @section['k'].should == 'a value'
-+      expect(@section.option('k')).to be_kind_of(IniParse::Lines::Option)
-+      expect(@section['k']).to eq('a value')
-     end
- 
-     it 'should update the Option if one already exists' do
-       @section.lines << IniParse::Lines::Option.new('k', 'orig value')
-       @section['k'] = 'new value'
--      @section['k'].should == 'new value'
-+      expect(@section['k']).to eq('new value')
-     end
- 
-     it 'should replace the existing Option if it is an array' do
-       @section.lines << IniParse::Lines::Option.new('k', 'v1')
-       @section.lines << IniParse::Lines::Option.new('k', 'v2')
-       @section['k'] = 'new value'
--      @section.option('k').should be_kind_of(IniParse::Lines::Option)
--      @section['k'].should == 'new value'
-+      expect(@section.option('k')).to be_kind_of(IniParse::Lines::Option)
-+      expect(@section['k']).to eq('new value')
-     end
- 
-     it 'should typecast the key to a string' do
-       @section[:k] = 'a value'
--      @section['k'].should == 'a value'
-+      expect(@section['k']).to eq('a value')
-     end
-   end
- 
-@@ -199,16 +199,16 @@ describe 'IniParse::Lines::Section' do
-       @new_section.lines << IniParse::Lines::Option.new('d', 'val4')
- 
-       @section.merge!(@new_section)
--      @section['a'].should == 'val1'
--      @section['b'].should == 'val2'
--      @section['c'].should == 'val3'
--      @section['d'].should == 'val4'
-+      expect(@section['a']).to eq('val1')
-+      expect(@section['b']).to eq('val2')
-+      expect(@section['c']).to eq('val3')
-+      expect(@section['d']).to eq('val4')
-     end
- 
-     it 'should handle duplicates' do
-       @new_section.lines << IniParse::Lines::Option.new('a', 'val2')
-       @section.merge!(@new_section)
--      @section['a'].should == ['val1', 'val2']
-+      expect(@section['a']).to eq(['val1', 'val2'])
-     end
- 
-     it 'should handle duplicates on both sides' do
-@@ -217,7 +217,7 @@ describe 'IniParse::Lines::Section' do
-       @new_section.lines << IniParse::Lines::Option.new('a', 'val4')
- 
-       @section.merge!(@new_section)
--      @section['a'].should == ['val1', 'val2', 'val3', 'val4']
-+      expect(@section['a']).to eq(['val1', 'val2', 'val3', 'val4'])
-     end
- 
-     it 'should copy blank lines' do
-@@ -225,7 +225,7 @@ describe 'IniParse::Lines::Section' do
-       @section.merge!(@new_section)
-       line = nil
-       @section.each(true) { |l| line = l }
--      line.should be_kind_of(IniParse::Lines::Blank)
-+      expect(line).to be_kind_of(IniParse::Lines::Blank)
-     end
- 
-     it 'should copy comments' do
-@@ -233,7 +233,7 @@ describe 'IniParse::Lines::Section' do
-       @section.merge!(@new_section)
-       line = nil
-       @section.each(true) { |l| line = l }
--      line.should be_kind_of(IniParse::Lines::Comment)
-+      expect(line).to be_kind_of(IniParse::Lines::Comment)
-     end
-   end
- 
-@@ -247,27 +247,27 @@ describe 'IniParse::Lines::Section' do
-     end
- 
-     it 'removes the option given a key' do
--      lambda { @section.delete('a') }.
--        should change { @section['a'] }.to(nil)
-+      expect { @section.delete('a') }.
-+        to change { @section['a'] }.to(nil)
-     end
- 
-     it 'removes the option given an Option' do
--      lambda { @section.delete(opt_one) }.
--        should change { @section['a'] }.to(nil)
-+      expect { @section.delete(opt_one) }.
-+        to change { @section['a'] }.to(nil)
-     end
- 
-     it 'should not remove non-matching lines' do
--      lambda { @section.delete('a') }.should_not change { @section['c'] }
-+      expect { @section.delete('a') }.not_to change { @section['c'] }
-     end
- 
-     it 'returns the section' do
--      @section.delete('a').should eql(@section)
-+      expect(@section.delete('a')).to eql(@section)
-     end
-   end
- 
-   describe '#to_ini' do
-     it 'should include the section key' do
--      IniParse::Lines::Section.new('a section').to_ini.should == '[a section]'
-+      expect(IniParse::Lines::Section.new('a section').to_ini).to eq('[a section]')
-     end
- 
-     it 'should include lines belonging to the section' do
-@@ -278,22 +278,24 @@ describe 'IniParse::Lines::Section' do
-       )
-       @section.lines << IniParse::Lines::Option.new('b', 'val2')
- 
--      @section.to_ini.should ==
-+      expect(@section.to_ini).to eq(
-         "[a section]\n" \
-         "a = val1\n" \
-         "\n" \
-         "; my comment\n" \
-         "b = val2"
-+      )
-     end
- 
-     it 'should include duplicate lines' do
-       @section.lines << IniParse::Lines::Option.new('a', 'val1')
-       @section.lines << IniParse::Lines::Option.new('a', 'val2')
- 
--      @section.to_ini.should ==
-+      expect(@section.to_ini).to eq(
-         "[a section]\n" \
-         "a = val1\n" \
-         "a = val2"
-+      )
-     end
-   end
- 
-@@ -303,11 +305,11 @@ describe 'IniParse::Lines::Section' do
-     end
- 
-     it 'should return true if an option with the given key exists' do
--      @section.should have_option('first')
-+      expect(@section).to have_option('first')
-     end
- 
-     it 'should return true if no option with the given key exists' do
--      @section.should_not have_option('second')
-+      expect(@section).not_to have_option('second')
-     end
-   end
- end
-@@ -319,13 +321,13 @@ end
- describe 'Iniparse::Lines::Option' do
-   describe '#initialize' do
-     it 'should typecast the given key to a string' do
--      IniParse::Lines::Option.new(:symbol, '').key.should == 'symbol'
-+      expect(IniParse::Lines::Option.new(:symbol, '').key).to eq('symbol')
-     end
-   end
- 
-   describe '#to_ini' do
-     it 'should include the key and value' do
--      IniParse::Lines::Option.new('key', 'value').to_ini.should == 'key = value'
-+      expect(IniParse::Lines::Option.new('key', 'value').to_ini).to eq('key = value')
-     end
-   end
- 
-@@ -335,70 +337,70 @@ describe 'Iniparse::Lines::Option' do
-     end
- 
-     it 'should typecast empty values to nil' do
--      parse('key =').should be_option_tuple('key', nil)
--      parse('key = ').should be_option_tuple('key', nil)
--      parse('key =    ').should be_option_tuple('key', nil)
-+      expect(parse('key =')).to be_option_tuple('key', nil)
-+      expect(parse('key = ')).to be_option_tuple('key', nil)
-+      expect(parse('key =    ')).to be_option_tuple('key', nil)
-     end
- 
-     it 'should not typecast "true" if true is part of a word' do
--      parse('key = TestTrueTest').should be_option_tuple('key', 'TestTrueTest')
--      parse('key = TrueTest').should be_option_tuple('key', 'TrueTest')
--      parse('key = TestTrue').should be_option_tuple('key', 'TestTrue')
-+      expect(parse('key = TestTrueTest')).to be_option_tuple('key', 'TestTrueTest')
-+      expect(parse('key = TrueTest')).to be_option_tuple('key', 'TrueTest')
-+      expect(parse('key = TestTrue')).to be_option_tuple('key', 'TestTrue')
-     end
- 
-     it 'should not typecast "false" if false is part of a word' do
--      parse('key = TestFalseTest').should be_option_tuple('key', 'TestFalseTest')
--      parse('key = FalseTest').should be_option_tuple('key', 'FalseTest')
--      parse('key = TestFalse').should be_option_tuple('key', 'TestFalse')
-+      expect(parse('key = TestFalseTest')).to be_option_tuple('key', 'TestFalseTest')
-+      expect(parse('key = FalseTest')).to be_option_tuple('key', 'FalseTest')
-+      expect(parse('key = TestFalse')).to be_option_tuple('key', 'TestFalse')
-     end
- 
-     it 'should typecast "true" to TrueClass' do
--      parse('key = true').should be_option_tuple('key', true)
--      parse('key = TRUE').should be_option_tuple('key', true)
-+      expect(parse('key = true')).to be_option_tuple('key', true)
-+      expect(parse('key = TRUE')).to be_option_tuple('key', true)
-     end
- 
-     it 'should typecast "false" to FalseClass' do
--      parse('key = false').should be_option_tuple('key', false)
--      parse('key = FALSE').should be_option_tuple('key', false)
-+      expect(parse('key = false')).to be_option_tuple('key', false)
-+      expect(parse('key = FALSE')).to be_option_tuple('key', false)
-     end
- 
-     it 'should typecast integer values to Integer' do
--      parse('key = 1').should be_option_tuple('key', 1)
--      parse('key = 10').should be_option_tuple('key', 10)
-+      expect(parse('key = 1')).to be_option_tuple('key', 1)
-+      expect(parse('key = 10')).to be_option_tuple('key', 10)
-     end
- 
-     it 'should not typecast integers with a leading 0 to Integer' do
--      parse('key = 0700').should be_option_tuple('key', '0700')
-+      expect(parse('key = 0700')).to be_option_tuple('key', '0700')
-     end
- 
-     it 'should typecast negative integer values to Integer' do
--      parse('key = -1').should be_option_tuple('key', -1)
-+      expect(parse('key = -1')).to be_option_tuple('key', -1)
-     end
- 
-     it 'should typecast float values to Float' do
--      parse('key = 3.14159265').should be_option_tuple('key', 3.14159265)
-+      expect(parse('key = 3.14159265')).to be_option_tuple('key', 3.14159265)
-     end
- 
-     it 'should typecast negative float values to Float' do
--      parse('key = -3.14159265').should be_option_tuple('key', -3.14159265)
-+      expect(parse('key = -3.14159265')).to be_option_tuple('key', -3.14159265)
-     end
- 
-     it 'should typecast scientific notation numbers to Float' do
--      parse('key = 10e5').should be_option_tuple('key', 10e5)
--      parse('key = 10e+5').should be_option_tuple('key', 10e5)
--      parse('key = 10e-5').should be_option_tuple('key', 10e-5)
-+      expect(parse('key = 10e5')).to be_option_tuple('key', 10e5)
-+      expect(parse('key = 10e+5')).to be_option_tuple('key', 10e5)
-+      expect(parse('key = 10e-5')).to be_option_tuple('key', 10e-5)
- 
--      parse('key = -10e5').should be_option_tuple('key', -10e5)
--      parse('key = -10e+5').should be_option_tuple('key', -10e5)
--      parse('key = -10e-5').should be_option_tuple('key', -10e-5)
-+      expect(parse('key = -10e5')).to be_option_tuple('key', -10e5)
-+      expect(parse('key = -10e+5')).to be_option_tuple('key', -10e5)
-+      expect(parse('key = -10e-5')).to be_option_tuple('key', -10e-5)
- 
--      parse('key = 3.14159265e5').should be_option_tuple('key', 3.14159265e5)
--      parse('key = 3.14159265e+5').should be_option_tuple('key', 3.14159265e5)
--      parse('key = 3.14159265e-5').should be_option_tuple('key', 3.14159265e-5)
-+      expect(parse('key = 3.14159265e5')).to be_option_tuple('key', 3.14159265e5)
-+      expect(parse('key = 3.14159265e+5')).to be_option_tuple('key', 3.14159265e5)
-+      expect(parse('key = 3.14159265e-5')).to be_option_tuple('key', 3.14159265e-5)
- 
--      parse('key = -3.14159265e5').should be_option_tuple('key', -3.14159265e5)
--      parse('key = -3.14159265e+5').should be_option_tuple('key', -3.14159265e5)
--      parse('key = -3.14159265e-5').should be_option_tuple('key', -3.14159265e-5)
-+      expect(parse('key = -3.14159265e5')).to be_option_tuple('key', -3.14159265e5)
-+      expect(parse('key = -3.14159265e+5')).to be_option_tuple('key', -3.14159265e5)
-+      expect(parse('key = -3.14159265e-5')).to be_option_tuple('key', -3.14159265e-5)
-     end
-   end
- end
-@@ -414,34 +416,34 @@ end
- describe 'IniParse::Lines::Comment' do
-   describe '#has_comment?' do
-     it 'should return true if :comment has a non-blank value' do
--      IniParse::Lines::Comment.new(:comment => 'comment').should have_comment
-+      expect(IniParse::Lines::Comment.new(:comment => 'comment')).to have_comment
-     end
- 
-     it 'should return true if :comment has a blank value' do
--      IniParse::Lines::Comment.new(:comment => '').should have_comment
-+      expect(IniParse::Lines::Comment.new(:comment => '')).to have_comment
-     end
- 
-     it 'should return true if :comment has a nil value' do
--      IniParse::Lines::Comment.new.should have_comment
--      IniParse::Lines::Comment.new(:comment => nil).should have_comment
-+      expect(IniParse::Lines::Comment.new).to have_comment
-+      expect(IniParse::Lines::Comment.new(:comment => nil)).to have_comment
-     end
-   end
- 
-   describe '#to_ini' do
-     it 'should return the comment' do
--      IniParse::Lines::Comment.new(
-+      expect(IniParse::Lines::Comment.new(
-         :comment => 'a comment'
--      ).to_ini.should == '; a comment'
-+      ).to_ini).to eq('; a comment')
-     end
- 
-     it 'should preserve comment offset' do
--      IniParse::Lines::Comment.new(
-+      expect(IniParse::Lines::Comment.new(
-         :comment => 'a comment', :comment_offset => 10
--      ).to_ini.should == '          ; a comment'
-+      ).to_ini).to eq('          ; a comment')
-     end
- 
-     it 'should return just the comment_sep if the comment is blank' do
--      IniParse::Lines::Comment.new.to_ini.should == ';'
-+      expect(IniParse::Lines::Comment.new.to_ini).to eq(';')
-     end
-   end
- end
-diff --git a/spec/parser/document_parsing_spec.rb b/spec/parser/document_parsing_spec.rb
-index 4636aae..c882542 100644
---- a/spec/parser/document_parsing_spec.rb
-+++ b/spec/parser/document_parsing_spec.rb
-@@ -9,53 +9,53 @@ describe 'Parsing a document' do
-     end
- 
-     it 'should have a comment as the first line' do
--      @doc.lines.to_a.first.should be_kind_of(IniParse::Lines::Comment)
-+      expect(@doc.lines.to_a.first).to be_kind_of(IniParse::Lines::Comment)
-     end
- 
-     it 'should have one section' do
--      @doc.lines.keys.should == ['first_section']
-+      expect(@doc.lines.keys).to eq(['first_section'])
-     end
- 
-     it 'should have one option belonging to `first_section`' do
--      @doc['first_section']['key'].should == 'value'
-+      expect(@doc['first_section']['key']).to eq('value')
-     end
-   end
- 
-   it 'should allow blank lines to preceed the first section' do
--    lambda {
-+    expect {
-       @doc = IniParse::Parser.new(fixture(:blank_before_section)).parse
--    }.should_not raise_error
-+    }.not_to raise_error
- 
--    @doc.lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
-+    expect(@doc.lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
-   end
- 
-   it 'should allow a blank line to belong to a section' do
--    lambda {
-+    expect {
-       @doc = IniParse::Parser.new(fixture(:blank_in_section)).parse
--    }.should_not raise_error
-+    }.not_to raise_error
- 
--    @doc['first_section'].lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
-+    expect(@doc['first_section'].lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
-   end
- 
-   it 'should permit comments on their own line' do
--    lambda {
-+    expect {
-       @doc = IniParse::Parser.new(fixture(:comment_line)).parse
--    }.should_not raise_error
-+    }.not_to raise_error
- 
-     line = @doc['first_section'].lines.to_a.first
--    line.comment.should eql('; block comment ;')
-+    expect(line.comment).to eql('; block comment ;')
-   end
- 
-   it 'should permit options before the first section' do
-     doc = IniParse::Parser.new(fixture(:option_before_section)).parse
- 
--    doc.lines.should have_key('__anonymous__')
--    doc['__anonymous__']['foo'].should eql('bar')
--    doc['foo']['another'].should eql('thing')
-+    expect(doc.lines).to have_key('__anonymous__')
-+    expect(doc['__anonymous__']['foo']).to eql('bar')
-+    expect(doc['foo']['another']).to eql('thing')
-   end
- 
-   it 'should raise ParseError if a line could not be parsed' do
--    lambda { IniParse::Parser.new(fixture(:invalid_line)).parse }.should \
-+    expect { IniParse::Parser.new(fixture(:invalid_line)).parse }.to \
-       raise_error(IniParse::ParseError)
-   end
- 
-@@ -65,20 +65,20 @@ describe 'Parsing a document' do
-     end
- 
-     it 'should have two sections' do
--      @doc.lines.to_a.length.should == 2
-+      expect(@doc.lines.to_a.length).to eq(2)
-     end
- 
-     it 'should have one section' do
--      @doc.lines.keys.should == ['first_section = name',
--                                 'another_section = a name']
-+      expect(@doc.lines.keys).to eq(['first_section = name',
-+                                 'another_section = a name'])
-     end
- 
-     it 'should have one option belonging to `first_section = name`' do
--      @doc['first_section = name']['key'].should == 'value'
-+      expect(@doc['first_section = name']['key']).to eq('value')
-     end
- 
-     it 'should have one option belonging to `another_section = a name`' do
--      @doc['another_section = a name']['another'].should == 'thing'
-+      expect(@doc['another_section = a name']['another']).to eq('thing')
-     end
-   end
- 
-@@ -89,19 +89,19 @@ describe 'Parsing a document' do
- 
-     it 'should only add the section once' do
-       # "first_section" and "second_section".
--      @doc.lines.to_a.length.should == 2
-+      expect(@doc.lines.to_a.length).to eq(2)
-     end
- 
-     it 'should retain values from the first time' do
--      @doc['first_section']['key'].should == 'value'
-+      expect(@doc['first_section']['key']).to eq('value')
-     end
- 
-     it 'should add new keys' do
--      @doc['first_section']['third'].should == 'fourth'
-+      expect(@doc['first_section']['third']).to eq('fourth')
-     end
- 
-     it 'should merge in duplicate keys' do
--      @doc['first_section']['another'].should == %w( thing again )
-+      expect(@doc['first_section']['another']).to eq(%w( thing again ))
-     end
-   end
- end
-diff --git a/spec/parser/line_parsing_spec.rb b/spec/parser/line_parsing_spec.rb
-index 3183bc5..818da81 100644
---- a/spec/parser/line_parsing_spec.rb
-+++ b/spec/parser/line_parsing_spec.rb
-@@ -4,12 +4,12 @@ require 'spec_helper'
- 
- describe 'Parsing a line' do
-   it 'should strip leading whitespace and set the :indent option' do
--    IniParse::Parser.parse_line('  [section]').should \
-+    expect(IniParse::Parser.parse_line('  [section]')).to \
-       be_section_tuple(:any, {:indent => '  '})
-   end
- 
-   it 'should raise an error if the line could not be matched' do
--    lambda { IniParse::Parser.parse_line('invalid line') }.should \
-+    expect { IniParse::Parser.parse_line('invalid line') }.to \
-       raise_error(IniParse::ParseError)
-   end
- 
-@@ -17,7 +17,7 @@ describe 'Parsing a line' do
-     begin
-       # Remove last type.
-       type = IniParse::Parser.parse_types.pop
--      type.should_not_receive(:parse)
-+      expect(type).not_to receive(:parse)
-       IniParse::Parser.parse_line('[section]')
-     ensure
-       IniParse::Parser.parse_types << type
-@@ -36,20 +36,20 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return an option tuple' do
--      @tuple.should be_option_tuple('k', 'v')
-+      expect(@tuple).to be_option_tuple('k', 'v')
-     end
- 
-     it 'should set no indent, comment, offset or separator' do
--      @tuple.last[:indent].should be_nil
--      @tuple.last[:comment].should be_nil
--      @tuple.last[:comment_offset].should be_nil
--      @tuple.last[:comment_sep].should be_nil
-+      expect(@tuple.last[:indent]).to be_nil
-+      expect(@tuple.last[:comment]).to be_nil
-+      expect(@tuple.last[:comment_offset]).to be_nil
-+      expect(@tuple.last[:comment_sep]).to be_nil
-     end
-   end
- 
-   describe 'with "k = a value with spaces"' do
-     it 'should return an option tuple' do
--      IniParse::Parser.parse_line('k = a value with spaces').should \
-+      expect(IniParse::Parser.parse_line('k = a value with spaces')).to \
-         be_option_tuple('k', 'a value with spaces')
-     end
-   end
-@@ -60,19 +60,19 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return an option tuple' do
--      @tuple.should be_option_tuple('k', 'v')
-+      expect(@tuple).to be_option_tuple('k', 'v')
-     end
- 
-     it 'should set the comment to "a comment"' do
--      @tuple.should be_option_tuple(:any, :any, :comment => 'a comment')
-+      expect(@tuple).to be_option_tuple(:any, :any, :comment => 'a comment')
-     end
- 
-     it 'should set the comment separator to ";"' do
--      @tuple.should be_option_tuple(:any, :any, :comment_sep => ';')
-+      expect(@tuple).to be_option_tuple(:any, :any, :comment_sep => ';')
-     end
- 
-     it 'should set the comment offset to 6' do
--      @tuple.should be_option_tuple(:any, :any, :comment_offset => 6)
-+      expect(@tuple).to be_option_tuple(:any, :any, :comment_offset => 6)
-     end
-   end
- 
-@@ -82,13 +82,13 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return an option tuple with the correct value' do
--      @tuple.should be_option_tuple(:any, 'v;w;x y;z')
-+      expect(@tuple).to be_option_tuple(:any, 'v;w;x y;z')
-     end
- 
-     it 'should not set a comment' do
--      @tuple.last[:comment].should be_nil
--      @tuple.last[:comment_offset].should be_nil
--      @tuple.last[:comment_sep].should be_nil
-+      expect(@tuple.last[:comment]).to be_nil
-+      expect(@tuple.last[:comment_offset]).to be_nil
-+      expect(@tuple.last[:comment_sep]).to be_nil
-     end
-   end
- 
-@@ -98,58 +98,58 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return an option tuple with the correct value' do
--      @tuple.should be_option_tuple(:any, 'v;w')
-+      expect(@tuple).to be_option_tuple(:any, 'v;w')
-     end
- 
-     it 'should set the comment to "a comment"' do
--      @tuple.should be_option_tuple(:any, :any, :comment => 'a comment')
-+      expect(@tuple).to be_option_tuple(:any, :any, :comment => 'a comment')
-     end
- 
-     it 'should set the comment separator to ";"' do
--      @tuple.should be_option_tuple(:any, :any, :comment_sep => ';')
-+      expect(@tuple).to be_option_tuple(:any, :any, :comment_sep => ';')
-     end
- 
-     it 'should set the comment offset to 8' do
--      @tuple.should be_option_tuple(:any, :any, :comment_offset => 8)
-+      expect(@tuple).to be_option_tuple(:any, :any, :comment_offset => 8)
-     end
-   end
- 
-   describe 'with "key=value"' do
-     it 'should return an option tuple with the correct key and value' do
--      IniParse::Parser.parse_line('key=value').should \
-+      expect(IniParse::Parser.parse_line('key=value')).to \
-         be_option_tuple('key', 'value')
-     end
-   end
- 
-   describe 'with "key= value"' do
-     it 'should return an option tuple with the correct key and value' do
--      IniParse::Parser.parse_line('key= value').should \
-+      expect(IniParse::Parser.parse_line('key= value')).to \
-         be_option_tuple('key', 'value')
-     end
-   end
- 
-   describe 'with "key =value"' do
-     it 'should return an option tuple with the correct key and value' do
--      IniParse::Parser.parse_line('key =value').should \
-+      expect(IniParse::Parser.parse_line('key =value')).to \
-         be_option_tuple('key', 'value')
-     end
-   end
- 
-   describe 'with "key   =   value"' do
-     it 'should return an option tuple with the correct key and value' do
--      IniParse::Parser.parse_line('key   =   value').should \
-+      expect(IniParse::Parser.parse_line('key   =   value')).to \
-         be_option_tuple('key', 'value')
-     end
-   end
- 
-   describe 'with "key ="' do
-     it 'should return an option tuple with the correct key' do
--      IniParse::Parser.parse_line('key =').should \
-+      expect(IniParse::Parser.parse_line('key =')).to \
-         be_option_tuple('key')
-     end
- 
-     it 'should set the option value to nil' do
--      IniParse::Parser.parse_line('key =').should \
-+      expect(IniParse::Parser.parse_line('key =')).to \
-         be_option_tuple(:any, nil)
-     end
-   end
-@@ -157,49 +157,49 @@ describe 'Parsing a line' do
- 
-   describe 'with "key = EEjDDJJjDJDJD233232=="' do
-     it 'should include the "equals" in the option value' do
--      IniParse::Parser.parse_line('key = EEjDDJJjDJDJD233232==').should \
-+      expect(IniParse::Parser.parse_line('key = EEjDDJJjDJDJD233232==')).to \
-         be_option_tuple('key', 'EEjDDJJjDJDJD233232==')
-     end
-   end
- 
-   describe 'with "key = ==EEjDDJJjDJDJD233232"' do
-     it 'should include the "equals" in the option value' do
--      IniParse::Parser.parse_line('key = ==EEjDDJJjDJDJD233232').should \
-+      expect(IniParse::Parser.parse_line('key = ==EEjDDJJjDJDJD233232')).to \
-         be_option_tuple('key', '==EEjDDJJjDJDJD233232')
-     end
-   end
- 
-   describe 'with "key.two = value"' do
-     it 'should return an option tuple with the correct key' do
--      IniParse::Parser.parse_line('key.two = value').should \
-+      expect(IniParse::Parser.parse_line('key.two = value')).to \
-         be_option_tuple('key.two')
-     end
-   end
- 
-   describe 'with "key/with/slashes = value"' do
-     it 'should return an option tuple with the correct key' do
--      IniParse::Parser.parse_line('key/with/slashes = value').should \
-+      expect(IniParse::Parser.parse_line('key/with/slashes = value')).to \
-         be_option_tuple('key/with/slashes', 'value')
-     end
-   end
- 
-   describe 'with "key_with_underscores = value"' do
-     it 'should return an option tuple with the correct key' do
--      IniParse::Parser.parse_line('key_with_underscores = value').should \
-+      expect(IniParse::Parser.parse_line('key_with_underscores = value')).to \
-         be_option_tuple('key_with_underscores', 'value')
-     end
-   end
- 
-   describe 'with "key-with-dashes = value"' do
-     it 'should return an option tuple with the correct key' do
--      IniParse::Parser.parse_line('key-with-dashes = value').should \
-+      expect(IniParse::Parser.parse_line('key-with-dashes = value')).to \
-         be_option_tuple('key-with-dashes', 'value')
-     end
-   end
- 
-   describe 'with "key with spaces = value"' do
-     it 'should return an option tuple with the correct key' do
--      IniParse::Parser.parse_line('key with spaces = value').should \
-+      expect(IniParse::Parser.parse_line('key with spaces = value')).to \
-         be_option_tuple('key with spaces', 'value')
-     end
-   end
-@@ -216,27 +216,27 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return a section tuple' do
--      @tuple.should be_section_tuple('section')
-+      expect(@tuple).to be_section_tuple('section')
-     end
- 
-     it 'should set no indent, comment, offset or separator' do
--      @tuple.last[:indent].should be_nil
--      @tuple.last[:comment].should be_nil
--      @tuple.last[:comment_offset].should be_nil
--      @tuple.last[:comment_sep].should be_nil
-+      expect(@tuple.last[:indent]).to be_nil
-+      expect(@tuple.last[:comment]).to be_nil
-+      expect(@tuple.last[:comment_offset]).to be_nil
-+      expect(@tuple.last[:comment_sep]).to be_nil
-     end
-   end
- 
-   describe 'with "[section with whitespace]"' do
-     it 'should return a section tuple with the correct key' do
--      IniParse::Parser.parse_line('[section with whitespace]').should \
-+      expect(IniParse::Parser.parse_line('[section with whitespace]')).to \
-         be_section_tuple('section with whitespace')
-     end
-   end
- 
-   describe 'with "[  section with surounding whitespace  ]"' do
-     it 'should return a section tuple with the correct key' do
--      IniParse::Parser.parse_line('[  section with surounding whitespace  ]').should \
-+      expect(IniParse::Parser.parse_line('[  section with surounding whitespace  ]')).to \
-         be_section_tuple('  section with surounding whitespace  ')
-     end
-   end
-@@ -247,19 +247,19 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return a section tuple' do
--      @tuple.should be_section_tuple('section')
-+      expect(@tuple).to be_section_tuple('section')
-     end
- 
-     it 'should set the comment to "a comment"' do
--      @tuple.should be_section_tuple(:any, :comment => 'a comment')
-+      expect(@tuple).to be_section_tuple(:any, :comment => 'a comment')
-     end
- 
-     it 'should set the comment separator to ";"' do
--      @tuple.should be_section_tuple(:any, :comment_sep => ';')
-+      expect(@tuple).to be_section_tuple(:any, :comment_sep => ';')
-     end
- 
-     it 'should set the comment offset to 10' do
--      @tuple.should be_section_tuple(:any, :comment_offset => 10)
-+      expect(@tuple).to be_section_tuple(:any, :comment_offset => 10)
-     end
-   end
- 
-@@ -269,14 +269,14 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return a section tuple with the correct key' do
--      @tuple.should be_section_tuple('section;with#comment;chars')
-+      expect(@tuple).to be_section_tuple('section;with#comment;chars')
-     end
- 
-     it 'should not set a comment' do
--      @tuple.last[:indent].should be_nil
--      @tuple.last[:comment].should be_nil
--      @tuple.last[:comment_offset].should be_nil
--      @tuple.last[:comment_sep].should be_nil
-+      expect(@tuple.last[:indent]).to be_nil
-+      expect(@tuple.last[:comment]).to be_nil
-+      expect(@tuple.last[:comment_offset]).to be_nil
-+      expect(@tuple.last[:comment_sep]).to be_nil
-     end
-   end
- 
-@@ -286,19 +286,19 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return a section tuple with the correct key' do
--      @tuple.should be_section_tuple('section;with#comment;chars')
-+      expect(@tuple).to be_section_tuple('section;with#comment;chars')
-     end
- 
-     it 'should set the comment to "a comment"' do
--      @tuple.should be_section_tuple(:any, :comment => 'a comment')
-+      expect(@tuple).to be_section_tuple(:any, :comment => 'a comment')
-     end
- 
-     it 'should set the comment separator to ";"' do
--      @tuple.should be_section_tuple(:any, :comment_sep => ';')
-+      expect(@tuple).to be_section_tuple(:any, :comment_sep => ';')
-     end
- 
-     it 'should set the comment offset to 29' do
--      @tuple.should be_section_tuple(:any, :comment_offset => 29)
-+      expect(@tuple).to be_section_tuple(:any, :comment_offset => 29)
-     end
-   end
- 
-@@ -314,15 +314,15 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return a comment tuple with the correct comment' do
--      @tuple.should be_comment_tuple('a comment')
-+      expect(@tuple).to be_comment_tuple('a comment')
-     end
- 
-     it 'should set the comment separator to ";"' do
--      @tuple.should be_comment_tuple(:any, :comment_sep => ';')
-+      expect(@tuple).to be_comment_tuple(:any, :comment_sep => ';')
-     end
- 
-     it 'should set the comment offset to 0' do
--      @tuple.should be_comment_tuple(:any, :comment_offset => 0)
-+      expect(@tuple).to be_comment_tuple(:any, :comment_offset => 0)
-     end
-   end
- 
-@@ -332,15 +332,15 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return a comment tuple with the correct comment' do
--      @tuple.should be_comment_tuple('a comment')
-+      expect(@tuple).to be_comment_tuple('a comment')
-     end
- 
-     it 'should set the comment separator to ";"' do
--      @tuple.should be_comment_tuple(:any, :comment_sep => ';')
-+      expect(@tuple).to be_comment_tuple(:any, :comment_sep => ';')
-     end
- 
-     it 'should set the comment offset to 1' do
--      @tuple.should be_comment_tuple(:any, :comment_offset => 1)
-+      expect(@tuple).to be_comment_tuple(:any, :comment_offset => 1)
-     end
-   end
- 
-@@ -350,15 +350,15 @@ describe 'Parsing a line' do
-     end
- 
-     it 'should return a comment tuple with an empty value' do
--      @tuple.should be_comment_tuple('')
-+      expect(@tuple).to be_comment_tuple('')
-     end
- 
-     it 'should set the comment separator to ";"' do
--      @tuple.should be_comment_tuple(:any, :comment_sep => ';')
-+      expect(@tuple).to be_comment_tuple(:any, :comment_sep => ';')
-     end
- 
-     it 'should set the comment offset to 0' do
--      @tuple.should be_comment_tuple(:any, :comment_offset => 0)
-+      expect(@tuple).to be_comment_tuple(:any, :comment_offset => 0)
-     end
-   end
- 
-@@ -370,13 +370,13 @@ describe 'Parsing a line' do
- 
-   describe 'with ""' do
-     it 'should return a blank tuple' do
--      IniParse::Parser.parse_line('').should be_blank_tuple
-+      expect(IniParse::Parser.parse_line('')).to be_blank_tuple
-     end
-   end
- 
-   describe 'with " "' do
-     it 'should return a blank tuple' do
--      IniParse::Parser.parse_line(' ').should be_blank_tuple
-+      expect(IniParse::Parser.parse_line(' ')).to be_blank_tuple
-     end
-   end
- end
-diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
-index 78e812d..891234d 100644
---- a/spec/spec_helper.rb
-+++ b/spec/spec_helper.rb
-@@ -26,7 +26,7 @@ module IniParse
-           "expected #{@expected} but got #{@target.class}"
-         end
- 
--        def negative_failure_message
-+        def failure_message_when_negated
-           "expected #{@expected} to not be #{@target.class}"
-         end
- 
-@@ -68,7 +68,7 @@ module IniParse
-           "expected #{@expected_type} tuple #{@failure_message}"
-         end
- 
--        def negative_failure_message
-+        def failure_message_when_negated
-           "expected #{@tuple.inspect} to not be #{@expected_type} tuple"
-         end
- 
-diff --git a/spec/spec_helper_spec.rb b/spec/spec_helper_spec.rb
-index 178db71..141c5fb 100644
---- a/spec/spec_helper_spec.rb
-+++ b/spec/spec_helper_spec.rb
-@@ -8,19 +8,19 @@ require 'spec_helper'
- 
- describe 'An empty array' do
-   it 'should not pass be_section_tuple' do
--    [].should_not be_section_tuple
-+    expect([]).not_to be_section_tuple
-   end
- 
-   it 'should not pass be_option_tuple' do
--    [].should_not be_option_tuple
-+    expect([]).not_to be_option_tuple
-   end
- 
-   it 'should not pass be_blank_tuple' do
--    [].should_not be_blank_tuple
-+    expect([]).not_to be_blank_tuple
-   end
- 
-   it 'should not pass be_comment_tuple' do
--    [].should_not be_comment_tuple
-+    expect([]).not_to be_comment_tuple
-   end
- end
- 
-@@ -34,39 +34,39 @@ describe 'Line tuple [:section, "key", {:opt => "val"}]' do
-   before(:all) { @tuple = [:section, "key", {:opt => "val"}] }
- 
-   it 'should pass be_section_tuple' do
--    @tuple.should be_section_tuple
-+    expect(@tuple).to be_section_tuple
-   end
- 
-   it 'should pass be_section_tuple("key")' do
--    @tuple.should be_section_tuple("key")
-+    expect(@tuple).to be_section_tuple("key")
-   end
- 
-   it 'should fail be_section_tuple("invalid")' do
--    @tuple.should_not be_section_tuple("invalid")
-+    expect(@tuple).not_to be_section_tuple("invalid")
-   end
- 
-   it 'should pass be_section_tuple("key", {:opt => "val"})' do
--    @tuple.should be_section_tuple("key", {:opt => "val"})
-+    expect(@tuple).to be_section_tuple("key", {:opt => "val"})
-   end
- 
-   it 'should not pass be_section_tuple("key", {:invalid => "val"})' do
--    @tuple.should_not be_section_tuple("key", {:invalid => "val"})
-+    expect(@tuple).not_to be_section_tuple("key", {:invalid => "val"})
-   end
- 
-   it 'should not pass be_section_tuple("key", {:opt => "invalid"})' do
--    @tuple.should_not be_section_tuple("key", {:opt => "invalid"})
-+    expect(@tuple).not_to be_section_tuple("key", {:opt => "invalid"})
-   end
- 
-   it 'should fail be_option_tuple' do
--    @tuple.should_not be_option_tuple
-+    expect(@tuple).not_to be_option_tuple
-   end
- 
-   it 'should fail be_blank_tuple' do
--    @tuple.should_not be_blank_tuple
-+    expect(@tuple).not_to be_blank_tuple
-   end
- 
-   it 'should fail be_comment_tuple' do
--    @tuple.should_not be_comment_tuple
-+    expect(@tuple).not_to be_comment_tuple
-   end
- end
- 
-@@ -80,51 +80,51 @@ describe 'Line tuple [:option, "key", "val", {:opt => "val"}]' do
-   before(:all) { @tuple = [:option, "key", "val", {:opt => "val"}] }
- 
-   it 'should fail be_section_tuple' do
--    @tuple.should_not be_section_tuple
-+    expect(@tuple).not_to be_section_tuple
-   end
- 
-   it 'should pass be_option_tuple' do
--    @tuple.should be_option_tuple
-+    expect(@tuple).to be_option_tuple
-   end
- 
-   it 'should pass be_option_tuple("key")' do
--    @tuple.should be_option_tuple("key")
-+    expect(@tuple).to be_option_tuple("key")
-   end
- 
-   it 'should fail be_option_tuple("invalid")' do
--    @tuple.should_not be_option_tuple("invalid")
-+    expect(@tuple).not_to be_option_tuple("invalid")
-   end
- 
-   it 'should pass be_option_tuple("key", "val")' do
--    @tuple.should be_option_tuple("key", "val")
-+    expect(@tuple).to be_option_tuple("key", "val")
-   end
- 
-   it 'should pass be_option_tuple(:any, "val")' do
--    @tuple.should be_option_tuple(:any, "val")
-+    expect(@tuple).to be_option_tuple(:any, "val")
-   end
- 
-   it 'should fail be_option_tuple("key", "invalid")' do
--    @tuple.should_not be_option_tuple("key", "invalid")
-+    expect(@tuple).not_to be_option_tuple("key", "invalid")
-   end
- 
-   it 'should pass be_option_tuple("key", "val", { :opt => "val" })' do
--    @tuple.should be_option_tuple("key", "val", { :opt => "val" })
-+    expect(@tuple).to be_option_tuple("key", "val", { :opt => "val" })
-   end
- 
-   it 'should fail be_option_tuple("key", "val", { :invalid => "val" })' do
--    @tuple.should_not be_option_tuple("key", "val", { :invalid => "val" })
-+    expect(@tuple).not_to be_option_tuple("key", "val", { :invalid => "val" })
-   end
- 
-   it 'should fail be_option_tuple("key", "val", { :opt => "invalid" })' do
--    @tuple.should_not be_option_tuple("key", "val", { :opt => "invalid" })
-+    expect(@tuple).not_to be_option_tuple("key", "val", { :opt => "invalid" })
-   end
- 
-   it 'should fail be_blank_tuple' do
--    @tuple.should_not be_blank_tuple
-+    expect(@tuple).not_to be_blank_tuple
-   end
- 
-   it 'should fail be_comment_tuple' do
--    @tuple.should_not be_comment_tuple
-+    expect(@tuple).not_to be_comment_tuple
-   end
- end
- 
-@@ -138,19 +138,19 @@ describe 'Line tuple [:blank]' do
-   before(:all) { @tuple = [:blank] }
- 
-   it 'should fail be_section_tuple' do
--    @tuple.should_not be_section_tuple
-+    expect(@tuple).not_to be_section_tuple
-   end
- 
-   it 'should fail be_option_tuple' do
--    @tuple.should_not be_option_tuple
-+    expect(@tuple).not_to be_option_tuple
-   end
- 
-   it 'should pass be_blank_tuple' do
--    @tuple.should be_blank_tuple
-+    expect(@tuple).to be_blank_tuple
-   end
- 
-   it 'should fail be_comment_tuple' do
--    @tuple.should_not be_comment_tuple
-+    expect(@tuple).not_to be_comment_tuple
-   end
- end
- 
-@@ -164,38 +164,38 @@ describe 'Line tuple [:comment, "A comment", {:opt => "val"}]' do
-   before(:all) { @tuple = [:comment, "A comment", {:opt => "val"}] }
- 
-   it 'should fail be_section_tuple' do
--    @tuple.should_not be_section_tuple
-+    expect(@tuple).not_to be_section_tuple
-   end
- 
-   it 'should fail be_option_tuple' do
--    @tuple.should_not be_option_tuple
-+    expect(@tuple).not_to be_option_tuple
-   end
- 
-   it 'should fail be_blank_tuple' do
--    @tuple.should_not be_blank_tuple
-+    expect(@tuple).not_to be_blank_tuple
-   end
- 
-   it 'should pass be_comment_tuple' do
--    @tuple.should be_comment_tuple
-+    expect(@tuple).to be_comment_tuple
-   end
- 
-   it 'should pass be_comment_tuple("A comment")' do
--    @tuple.should be_comment_tuple("A comment")
-+    expect(@tuple).to be_comment_tuple("A comment")
-   end
- 
-   it 'should fail be_comment_tuple("Invalid")' do
--    @tuple.should_not be_comment_tuple("Invalid")
-+    expect(@tuple).not_to be_comment_tuple("Invalid")
-   end
- 
-   it 'should pass be_comment_tuple("A comment", {:opt => "val"})' do
--    @tuple.should be_comment_tuple("A comment", {:opt => "val"})
-+    expect(@tuple).to be_comment_tuple("A comment", {:opt => "val"})
-   end
- 
-   it 'should fail be_comment_tuple("A comment", {:invalid => "val"})' do
--    @tuple.should_not be_comment_tuple("A comment", {:invalid => "val"})
-+    expect(@tuple).not_to be_comment_tuple("A comment", {:invalid => "val"})
-   end
- 
-   it 'should fail be_comment_tuple("A comment", {:opt => "invalid"})' do
--    @tuple.should_not be_comment_tuple("A comment", {:opt => "invalid"})
-+    expect(@tuple).not_to be_comment_tuple("A comment", {:opt => "invalid"})
-   end
- end
diff --git a/debian/patches/series b/debian/patches/series
index 81be0ff..e69de29 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1 +0,0 @@
-0001-Port-test-suite-to-RSpec-3.patch
diff --git a/iniparse.gemspec b/iniparse.gemspec
index 7fec34d..a0ee932 100644
--- a/iniparse.gemspec
+++ b/iniparse.gemspec
@@ -12,8 +12,8 @@ Gem::Specification.new do |s|
   ## If your rubyforge_project name is different, then edit it and comment out
   ## the sub! line in the Rakefile
   s.name              = 'iniparse'
-  s.version           = '1.4.2'
-  s.date              = '2015-12-03'
+  s.version           = '1.4.4'
+  s.date              = '2017-07-04'
   s.rubyforge_project = 'iniparse'
 
   s.summary           = 'A pure Ruby library for parsing INI documents.'
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
   s.extra_rdoc_files  = %w(LICENSE README.rdoc)
 
   # Dependencies.
-  s.add_development_dependency('rspec', '~> 2.14')
+  s.add_development_dependency('rspec', '~> 3.4')
 
   # = MANIFEST =
   s.files = %w[
diff --git a/lib/iniparse.rb b/lib/iniparse.rb
index e8ef5f0..b3998d3 100644
--- a/lib/iniparse.rb
+++ b/lib/iniparse.rb
@@ -7,7 +7,7 @@ require File.join(dir, 'lines')
 require File.join(dir, 'parser')
 
 module IniParse
-  VERSION = '1.4.2'
+  VERSION = '1.4.4'
 
   # A base class for IniParse errors.
   class IniParseError < StandardError; end
diff --git a/lib/iniparse/line_collection.rb b/lib/iniparse/line_collection.rb
index 70126f8..cf36f8f 100644
--- a/lib/iniparse/line_collection.rb
+++ b/lib/iniparse/line_collection.rb
@@ -111,7 +111,7 @@ module IniParse
     include LineCollection
 
     def <<(line)
-      if line.kind_of?(IniParse::Lines::Option)
+      if line.kind_of?(IniParse::Lines::Option) || (has_key?('__anonymous__') && (line.blank? || line.kind_of?(IniParse::Lines::Comment)))
         option = line
         line   = IniParse::Lines::AnonymousSection.new
 
diff --git a/lib/iniparse/lines.rb b/lib/iniparse/lines.rb
index 25519f2..775905e 100644
--- a/lib/iniparse/lines.rb
+++ b/lib/iniparse/lines.rb
@@ -11,6 +11,7 @@ module IniParse
         @comment_prefix = opts.fetch(:comment_prefix, ' ')
         @comment_offset = opts.fetch(:comment_offset, 0)
         @indent         = opts.fetch(:indent, '')
+        @option_sep     = opts.fetch(:option_sep, nil)
       end
 
       # Returns if this line has an inline comment.
@@ -54,7 +55,8 @@ module IniParse
           comment_sep: @comment_sep,
           comment_prefix: @comment_prefix,
           comment_offset: @comment_offset,
-          indent: @indent
+          indent: @indent,
+          option_sep: @option_sep
         }
       end
     end
@@ -248,9 +250,9 @@ module IniParse
     class Option
       include Line
 
-      @regex = /^\s*([^=]+)  # Option
-                 =
-                 (.*?)$      # Value
+      @regex = /^\s*([^=]+?)  # Option, not greedy
+                 (\s*=\s*)    # Separator, greedy
+                 (.*?)$       # Value
                /x
 
       attr_accessor :key, :value
@@ -263,11 +265,13 @@ module IniParse
       def initialize(key, value, opts = {})
         super(opts)
         @key, @value = key.to_s, value
+        @option_sep = opts.fetch(:option_sep, ' = ')
       end
 
       def self.parse(line, opts)
         if m = @regex.match(line)
-          [:option, m[1].strip, typecast(m[2].strip), opts]
+          opts[:option_sep] = m[2]
+          [:option, m[1].strip, typecast(m[3].strip), opts]
         end
       end
 
@@ -291,9 +295,9 @@ module IniParse
       # because of options key duplication
       def line_contents
         if value.kind_of?(Array)
-          value.map { |v, i| "#{key} = #{v}" }
+          value.map { |v, i| "#{key}#{@option_sep}#{v}" }
         else
-          "#{key} = #{value}"
+          "#{key}#{@option_sep}#{value}"
         end
       end
     end
diff --git a/lib/iniparse/parser.rb b/lib/iniparse/parser.rb
index 4072a2b..43ccad5 100644
--- a/lib/iniparse/parser.rb
+++ b/lib/iniparse/parser.rb
@@ -64,7 +64,7 @@ module IniParse
         if parsed.nil?
           raise IniParse::ParseError,
             "A line of your INI document could not be parsed to a " \
-            "LineType: '#{line}'."
+            "LineType: #{line.inspect}."
         end
 
         parsed
@@ -89,7 +89,7 @@ module IniParse
 
           line = m[1]
         else
-          line.rstrip!
+          line = line.chomp
         end
 
         [line, opts]
diff --git a/spec/document_spec.rb b/spec/document_spec.rb
index 353a7d8..24081f5 100644
--- a/spec/document_spec.rb
+++ b/spec/document_spec.rb
@@ -3,28 +3,28 @@ require 'spec_helper'
 describe "IniParse::Document" do
   it 'should have a +lines+ reader' do
     methods = IniParse::Document.instance_methods.map { |m| m.to_sym }
-    methods.should include(:lines)
+    expect(methods).to include(:lines)
   end
 
   it 'should not have a +lines+ writer' do
     methods = IniParse::Document.instance_methods.map { |m| m.to_sym }
-    methods.should_not include(:lines=)
+    expect(methods).not_to include(:lines=)
   end
 
   it 'should delegate #[] to +lines+' do
     doc = IniParse::Document.new
-    doc.lines.should_receive(:[]).with('key')
+    expect(doc.lines).to receive(:[]).with('key')
     doc['key']
   end
 
   it 'should call #each to +lines+' do
     doc = IniParse::Document.new
-    doc.lines.should_receive(:each)
+    expect(doc.lines).to receive(:each)
     doc.each { |l| }
   end
 
   it 'should be enumerable' do
-    IniParse::Document.included_modules.should include(Enumerable)
+    expect(IniParse::Document.included_modules).to include(Enumerable)
 
     sections = [
       IniParse::Lines::Section.new('first section'),
@@ -34,7 +34,7 @@ describe "IniParse::Document" do
     doc = IniParse::Document.new
     doc.lines << sections[0] << sections[1]
 
-    doc.map { |line| line }.should == sections
+    expect(doc.map { |line| line }).to eq(sections)
   end
 
   describe '#has_section?' do
@@ -45,12 +45,12 @@ describe "IniParse::Document" do
     end
 
     it 'should return true if a section with the given key exists' do
-      @doc.should have_section('first section')
-      @doc.should have_section('another section')
+      expect(@doc).to have_section('first section')
+      expect(@doc).to have_section('another section')
     end
 
     it 'should return true if no section with the given key exists' do
-      @doc.should_not have_section('second section')
+      expect(@doc).not_to have_section('second section')
     end
   end
 
@@ -70,22 +70,22 @@ describe "IniParse::Document" do
     end
 
     it 'removes the section given a key' do
-      lambda { document.delete('first') }.
-        should change { document['first'] }.to(nil)
+      expect { document.delete('first') }.
+        to change { document['first'] }.to(nil)
     end
 
     it 'removes the section given a Section' do
-      lambda { document.delete(document['first']) }.
-        should change { document['first'] }.to(nil)
+      expect { document.delete(document['first']) }.
+        to change { document['first'] }.to(nil)
     end
 
     it 'removes the lines' do
-      lambda { document.delete('first') }.
-        should change { document.to_ini.match(/alpha/) }.to(nil)
+      expect { document.delete('first') }.
+        to change { document.to_ini.match(/alpha/) }.to(nil)
     end
 
     it 'returns the document' do
-      document.delete('first').should eql(document)
+      expect(document.delete('first')).to eql(document)
     end
   end
 
@@ -122,31 +122,31 @@ describe "IniParse::Document" do
     describe 'when no path is given to save' do
       it 'should save the INI document if a path was given when initialized' do
         doc = IniParse::Document.new('/a/path/to/a/file.ini')
-        File.should_receive(:open).with('/a/path/to/a/file.ini', 'w')
+        expect(File).to receive(:open).with('/a/path/to/a/file.ini', 'w')
         doc.save
       end
 
       it 'should raise IniParseError if no path was given when initialized' do
-        lambda { IniParse::Document.new.save }.should \
+        expect { IniParse::Document.new.save }.to \
           raise_error(IniParse::IniParseError)
       end
     end
 
     describe 'when a path is given to save' do
       it "should update the document's +path+" do
-        File.stub(:open).and_return(true)
+        allow(File).to receive(:open).and_return(true)
         doc = IniParse::Document.new('/a/path/to/a/file.ini')
         doc.save('/a/new/path.ini')
-        doc.path.should == '/a/new/path.ini'
+        expect(doc.path).to eq('/a/new/path.ini')
       end
 
       it 'should save the INI document to the given path' do
-        File.should_receive(:open).with('/a/new/path.ini', 'w')
+        expect(File).to receive(:open).with('/a/new/path.ini', 'w')
         IniParse::Document.new('/a/path/to/a/file.ini').save('/a/new/path.ini')
       end
 
       it 'should raise IniParseError if no path was given when initialized' do
-        lambda { IniParse::Document.new.save }.should \
+        expect { IniParse::Document.new.save }.to \
           raise_error(IniParse::IniParseError)
       end
     end
diff --git a/spec/fixture_spec.rb b/spec/fixture_spec.rb
index 81eab3c..8231456 100644
--- a/spec/fixture_spec.rb
+++ b/spec/fixture_spec.rb
@@ -7,16 +7,16 @@ describe "IniParse" do
     end
 
     it 'should parse without any errors' do
-      lambda { IniParse.parse(@fixture) }.should_not raise_error
+      expect { IniParse.parse(@fixture) }.not_to raise_error
     end
 
     it 'should have the correct sections' do
-      IniParse.parse(fixture('openttd.ini')).lines.keys.should == [
+      expect(IniParse.parse(fixture('openttd.ini')).lines.keys).to eq([
         'misc', 'music', 'difficulty', 'game_creation', 'vehicle',
         'construction', 'station', 'economy', 'pf', 'order', 'gui', 'ai',
         'locale', 'network', 'currency', 'servers', 'bans', 'news_display',
         'version', 'preset-J', 'newgrf', 'newgrf-static'
-      ]
+      ])
     end
 
     it 'should have the correct options' do
@@ -24,7 +24,7 @@ describe "IniParse" do
       doc     = IniParse.parse(@fixture)
       section = doc['misc']
 
-      section.lines.keys.should == [
+      expect(section.lines.keys).to eq([
         'display_opt', 'news_ticker_sound', 'fullscreen', 'language',
         'resolution', 'screenshot_format', 'savegame_format',
         'rightclick_emulate', 'small_font', 'medium_font', 'large_font',
@@ -32,26 +32,26 @@ describe "IniParse" do
         'large_aa', 'sprite_cache_size', 'player_face',
         'transparency_options', 'transparency_locks', 'invisibility_options',
         'keyboard', 'keyboard_caps'
-      ]
+      ])
 
       # Test some of the options.
-      section['display_opt'].should == 'SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|FULL_DETAIL|WAYPOINTS'
-      section['news_ticker_sound'].should be_false
-      section['language'].should == 'english_US.lng'
-      section['resolution'].should == '1680,936'
-      section['large_size'].should == 16
+      expect(section['display_opt']).to eq('SHOW_TOWN_NAMES|SHOW_STATION_NAMES|SHOW_SIGNS|FULL_ANIMATION|FULL_DETAIL|WAYPOINTS')
+      expect(section['news_ticker_sound']).to be_falsey
+      expect(section['language']).to eq('english_US.lng')
+      expect(section['resolution']).to eq('1680,936')
+      expect(section['large_size']).to eq(16)
 
       # Test some other options.
-      doc['currency']['suffix'].should == '" credits"'
-      doc['news_display']['production_nobody'].should == 'summarized'
-      doc['version']['version_number'].should == '070039B0'
+      expect(doc['currency']['suffix']).to eq('" credits"')
+      expect(doc['news_display']['production_nobody']).to eq('summarized')
+      expect(doc['version']['version_number']).to eq('070039B0')
 
-      doc['preset-J']['gcf/1_other/BlackCC/mauvetoblackw.grf'].should be_nil
-      doc['preset-J']['gcf/1_other/OpenGFX/OpenGFX_-_newFaces_v0.1.grf'].should be_nil
+      expect(doc['preset-J']['gcf/1_other/BlackCC/mauvetoblackw.grf']).to be_nil
+      expect(doc['preset-J']['gcf/1_other/OpenGFX/OpenGFX_-_newFaces_v0.1.grf']).to be_nil
     end
 
     it 'should be identical to the original when calling #to_ini' do
-      IniParse.parse(@fixture).to_ini.should == @fixture
+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
     end
   end
 
@@ -61,14 +61,14 @@ describe "IniParse" do
     end
 
     it 'should parse without any errors' do
-      lambda { IniParse.parse(@fixture) }.should_not raise_error
+      expect { IniParse.parse(@fixture) }.not_to raise_error
     end
 
     it 'should have the correct sections' do
-      IniParse.parse(fixture('race07.ini')).lines.keys.should == [
+      expect(IniParse.parse(fixture('race07.ini')).lines.keys).to eq([
         'Header', 'Race', 'Slot010', 'Slot016', 'Slot013', 'Slot018',
         'Slot002', 'END'
-      ]
+      ])
     end
 
     it 'should have the correct options' do
@@ -76,24 +76,24 @@ describe "IniParse" do
       doc     = IniParse.parse(@fixture)
       section = doc['Slot010']
 
-      section.lines.keys.should == [
+      expect(section.lines.keys).to eq([
         'Driver', 'SteamUser', 'SteamId', 'Vehicle', 'Team', 'QualTime',
         'Laps', 'Lap', 'LapDistanceTravelled', 'BestLap', 'RaceTime'
-      ]
+      ])
 
       # Test some of the options.
-      section['Driver'].should == 'Mark Voss'
-      section['SteamUser'].should == 'mvoss'
-      section['SteamId'].should == 1865369
-      section['Vehicle'].should == 'Chevrolet Lacetti 2007'
-      section['Team'].should == 'TEMPLATE_TEAM'
-      section['QualTime'].should == '1:37.839'
-      section['Laps'].should == 13
-      section['LapDistanceTravelled'].should == 3857.750244
-      section['BestLap'].should == '1:38.031'
-      section['RaceTime'].should == '0:21:38.988'
-
-      section['Lap'].should == [
+      expect(section['Driver']).to eq('Mark Voss')
+      expect(section['SteamUser']).to eq('mvoss')
+      expect(section['SteamId']).to eq(1865369)
+      expect(section['Vehicle']).to eq('Chevrolet Lacetti 2007')
+      expect(section['Team']).to eq('TEMPLATE_TEAM')
+      expect(section['QualTime']).to eq('1:37.839')
+      expect(section['Laps']).to eq(13)
+      expect(section['LapDistanceTravelled']).to eq(3857.750244)
+      expect(section['BestLap']).to eq('1:38.031')
+      expect(section['RaceTime']).to eq('0:21:38.988')
+
+      expect(section['Lap']).to eq([
         '(0, -1.000, 1:48.697)',   '(1, 89.397, 1:39.455)',
         '(2, 198.095, 1:38.060)',  '(3, 297.550, 1:38.632)',
         '(4, 395.610, 1:38.031)',  '(5, 494.242, 1:39.562)',
@@ -101,20 +101,19 @@ describe "IniParse" do
         '(8, 791.785, 1:39.889)',  '(9, 890.151, 1:39.420)',
         '(10, 990.040, 1:39.401)', '(11, 1089.460, 1:39.506)',
         '(12, 1188.862, 1:40.017)'
-      ]
+      ])
 
-      doc['Header']['Version'].should == '1.1.1.14'
-      doc['Header']['TimeString'].should == '2008/09/13 23:26:32'
-      doc['Header']['Aids'].should == '0,0,0,0,0,1,1,0,0'
+      expect(doc['Header']['Version']).to eq('1.1.1.14')
+      expect(doc['Header']['TimeString']).to eq('2008/09/13 23:26:32')
+      expect(doc['Header']['Aids']).to eq('0,0,0,0,0,1,1,0,0')
 
-      doc['Race']['AIDB'].should == 'GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW'
-      doc['Race']['Race Length'].should == 0.1
+      expect(doc['Race']['AIDB']).to eq('GameData\Locations\Anderstorp_2007\2007_ANDERSTORP.AIW')
+      expect(doc['Race']['Race Length']).to eq(0.1)
     end
 
     it 'should be identical to the original when calling #to_ini' do
-      pending('awaiting presevation (or lack) of whitespace around =') do
-        IniParse.parse(@fixture).to_ini.should == @fixture
-      end
+      pending('awaiting presevation (or lack) of whitespace around =')
+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
     end
   end
 
@@ -124,13 +123,13 @@ describe "IniParse" do
     end
 
     it 'should parse without any errors' do
-      lambda { IniParse.parse(@fixture) }.should_not raise_error
+      expect { IniParse.parse(@fixture) }.not_to raise_error
     end
 
     it 'should have the correct sections' do
-      IniParse.parse(@fixture).lines.keys.should == [
+      expect(IniParse.parse(@fixture).lines.keys).to eq([
         'global', 'printers'
-      ]
+      ])
     end
 
     it 'should have the correct options' do
@@ -138,7 +137,7 @@ describe "IniParse" do
       doc     = IniParse.parse(@fixture)
       section = doc['global']
 
-      section.lines.keys.should == [
+      expect(section.lines.keys).to eq([
         'debug pid', 'log level', 'server string', 'printcap name',
         'printing', 'encrypt passwords', 'use spnego', 'passdb backend',
         'idmap domains', 'idmap config default: default',
@@ -152,15 +151,15 @@ describe "IniParse" do
         'usershare allow full config', 'com.apple:filter shares by access',
         'obey pam restrictions', 'acl check permissions',
         'name resolve order', 'include'
-      ]
+      ])
 
-      section['display charset'].should == 'UTF-8-MAC'
-      section['vfs objects'].should == 'darwinacl,darwin_streams'
-      section['usershare path'].should == '/var/samba/shares'
+      expect(section['display charset']).to eq('UTF-8-MAC')
+      expect(section['vfs objects']).to eq('darwinacl,darwin_streams')
+      expect(section['usershare path']).to eq('/var/samba/shares')
     end
 
     it 'should be identical to the original when calling #to_ini' do
-      IniParse.parse(@fixture).to_ini.should == @fixture
+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
     end
   end
 
@@ -170,7 +169,7 @@ describe "IniParse" do
     end
 
     it 'should be identical to the original when calling #to_ini' do
-      IniParse.parse(@fixture).to_ini.should == @fixture
+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
     end
   end
 
@@ -180,7 +179,41 @@ describe "IniParse" do
     end
 
     it 'should be identical to the original when calling #to_ini' do
-      IniParse.parse(@fixture).to_ini.should == @fixture
+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
+    end
+  end
+
+  describe 'DOS line endings' do
+    before(:all) do
+      @fixture = fixture(:dos_endings)
+    end
+
+    it 'should have the correct sections' do
+      expect(IniParse.parse(@fixture).lines.keys).to eq(%w[database])
+    end
+
+    it 'should have the correct options' do
+      # Test the keys from one section.
+      doc     = IniParse.parse(@fixture)
+      section = doc['database']
+
+      expect(section.lines.keys).to eq(%w[first second])
+
+      expect(section['first']).to eq(true)
+      expect(section['second']).to eq(false)
+    end
+
+    pending 'should be identical to the original when calling #to_ini' do
+      expect(IniParse.parse(@fixture).to_ini).to eq(@fixture)
+    end
+  end
+
+  describe 'anonymous-order.ini fixture' do
+    # https://github.com/antw/iniparse/issues/17
+    let(:raw) { fixture(:anon_section_with_comments) }
+
+    it 'should be identical to the original when calling #to_ini' do
+      expect(IniParse.parse(raw).to_ini).to eq(raw)
     end
   end
 end
diff --git a/spec/fixtures/openttd.ini b/spec/fixtures/openttd.ini
index 0d4dd8b..3584bbd 100644
--- a/spec/fixtures/openttd.ini
+++ b/spec/fixtures/openttd.ini
@@ -8,9 +8,9 @@ resolution = 1680,936
 screenshot_format = 
 savegame_format = 
 rightclick_emulate = false
-small_font = 
-medium_font = 
-large_font = 
+small_font =
+medium_font =
+large_font =
 small_size = 6
 medium_size = 10
 large_size = 16
@@ -22,8 +22,8 @@ player_face = 0
 transparency_options = 3
 transparency_locks = 0
 invisibility_options = 30
-keyboard = 
-keyboard_caps = 
+keyboard =
+keyboard_caps =
 
 [music]
 playlist = 0
diff --git a/spec/generator/method_missing_spec.rb b/spec/generator/method_missing_spec.rb
index 9fc1540..9370cb1 100644
--- a/spec/generator/method_missing_spec.rb
+++ b/spec/generator/method_missing_spec.rb
@@ -23,23 +23,23 @@ describe 'When generating a document using Generator with section blocks using m
       IniParse::Generator.gen do |doc|
         doc.a_section do |section|
           %w( option comment blank ).each do |meth|
-            section.should respond_to(meth)
+            expect(section).to respond_to(meth)
           end
         end
       end
     end
 
     it 'should add a Section to the document' do
-      IniParse::Generator.gen do |doc|
+      expect(IniParse::Generator.gen do |doc|
         doc.a_section { |section| }
-      end.should have_section("a_section")
+      end).to have_section("a_section")
     end
 
     it 'should change the Generator context to the section during the section block' do
       IniParse::Generator.gen do |doc|
         doc.a_section do |section|
-          section.context.should be_kind_of(IniParse::Lines::Section)
-          section.context.key.should == "a_section"
+          expect(section.context).to be_kind_of(IniParse::Lines::Section)
+          expect(section.context.key).to eq("a_section")
         end
       end
     end
@@ -47,24 +47,24 @@ describe 'When generating a document using Generator with section blocks using m
     it 'should reset the Generator context to the document after the section block' do
       IniParse::Generator.gen do |doc|
         doc.a_section { |section| }
-        doc.context.should be_kind_of(IniParse::Document)
+        expect(doc.context).to be_kind_of(IniParse::Document)
       end
     end
 
     it 'should append a blank line to the document, after the section' do
-      IniParse::Generator.gen do |doc|
+      expect(IniParse::Generator.gen do |doc|
         doc.a_section { |section| }
-      end.lines.to_a.last.should be_kind_of(IniParse::Lines::Blank)
+      end.lines.to_a.last).to be_kind_of(IniParse::Lines::Blank)
     end
 
     it 'should raise a LineNotAllowed if you attempt to nest a section' do
-      lambda do
+      expect do
         IniParse::Generator.gen do |doc|
           doc.a_section do |section_one|
             section_one.another_section { |section_two| }
           end
         end
-      end.should raise_error(IniParse::LineNotAllowed)
+      end.to raise_error(IniParse::LineNotAllowed)
     end
   end
 
@@ -78,7 +78,7 @@ describe 'When generating a document using Generator with section blocks using m
     describe 'when the context is a Document' do
       it "adds the option to an __anonymous__ section" do
         doc = IniParse::Generator.gen { |doc| doc.my_option = "a value" }
-        doc['__anonymous__']['my_option'].should eql('a value')
+        expect(doc['__anonymous__']['my_option']).to eql('a value')
       end
     end
 
@@ -91,8 +91,8 @@ describe 'When generating a document using Generator with section blocks using m
         end
 
         section = document["a_section"]
-        section.should have_option("my_option")
-        section["my_option"].should == "a value"
+        expect(section).to have_option("my_option")
+        expect(section["my_option"]).to eq("a value")
       end
     end
   end
diff --git a/spec/generator/with_section_blocks_spec.rb b/spec/generator/with_section_blocks_spec.rb
index da82840..4af5009 100644
--- a/spec/generator/with_section_blocks_spec.rb
+++ b/spec/generator/with_section_blocks_spec.rb
@@ -13,17 +13,17 @@ require 'spec_helper'
 describe 'When generating a document using Generator with section blocks,' do
 
   it 'should be able to compile an empty document' do
-    lambda { IniParse::Generator.gen { |doc| } }.should_not raise_error
+    expect { IniParse::Generator.gen { |doc| } }.not_to raise_error
   end
 
   it 'should raise LocalJumpError if no block is given' do
-    lambda { IniParse::Generator.gen }.should raise_error(LocalJumpError)
+    expect { IniParse::Generator.gen }.to raise_error(LocalJumpError)
   end
 
   it "should yield an object with generator methods" do
     IniParse::Generator.gen do |doc|
       %w( section option comment blank ).each do |meth|
-        doc.should respond_to(meth)
+        expect(doc).to respond_to(meth)
       end
     end
   end
@@ -39,23 +39,23 @@ describe 'When generating a document using Generator with section blocks,' do
       IniParse::Generator.gen do |doc|
         doc.section("a section") do |section|
           %w( option comment blank ).each do |meth|
-            section.should respond_to(meth)
+            expect(section).to respond_to(meth)
           end
         end
       end
     end
 
     it 'should add a Section to the document' do
-      IniParse::Generator.gen do |doc|
+      expect(IniParse::Generator.gen do |doc|
         doc.section("a section") { |section| }
-      end.should have_section("a section")
+      end).to have_section("a section")
     end
 
     it 'should change the Generator context to the section during the section block' do
       IniParse::Generator.gen do |doc|
         doc.section("a section") do |section|
-          section.context.should be_kind_of(IniParse::Lines::Section)
-          section.context.key.should == "a section"
+          expect(section.context).to be_kind_of(IniParse::Lines::Section)
+          expect(section.context.key).to eq("a section")
         end
       end
     end
@@ -63,7 +63,7 @@ describe 'When generating a document using Generator with section blocks,' do
     it 'should reset the Generator context to the document after the section block' do
       IniParse::Generator.gen do |doc|
         doc.section("a section") { |section| }
-        doc.context.should be_kind_of(IniParse::Document)
+        expect(doc.context).to be_kind_of(IniParse::Document)
       end
     end
 
@@ -72,7 +72,7 @@ describe 'When generating a document using Generator with section blocks,' do
         doc.section("a section") { |section| }
       end
 
-      document["a section"].to_ini.should match(/\A    /)
+      expect(document["a section"].to_ini).to match(/\A    /)
     end
 
     it 'should pass extra options to the Section instance' do
@@ -80,23 +80,23 @@ describe 'When generating a document using Generator with section blocks,' do
         doc.section("a section", :indent => '    ') { |section| }
       end
 
-      document["a section"].to_ini.should match(/\A    /)
+      expect(document["a section"].to_ini).to match(/\A    /)
     end
 
     it 'should append a blank line to the document, after the section' do
-      IniParse::Generator.gen do |doc|
+      expect(IniParse::Generator.gen do |doc|
         doc.section("a section") { |section| }
-      end.lines.to_a.last.should be_kind_of(IniParse::Lines::Blank)
+      end.lines.to_a.last).to be_kind_of(IniParse::Lines::Blank)
     end
 
     it 'should raise a LineNotAllowed if you attempt to nest a section' do
-      lambda do
+      expect do
         IniParse::Generator.gen do |doc|
           doc.section("a section") do |section_one|
             section_one.section("another_section") { |section_two| }
           end
         end
-      end.should raise_error(IniParse::LineNotAllowed)
+      end.to raise_error(IniParse::LineNotAllowed)
     end
   end
 
@@ -114,7 +114,7 @@ describe 'When generating a document using Generator with section blocks,' do
           doc.option("my option", "a value")
         end
 
-        document['__anonymous__']['my option'].should eql('a value')
+        expect(document['__anonymous__']['my option']).to eql('a value')
       end
     end
 
@@ -127,8 +127,8 @@ describe 'When generating a document using Generator with section blocks,' do
         end
 
         section = document["a section"]
-        section.should have_option("my option")
-        section["my option"].should == "a value"
+        expect(section).to have_option("my option")
+        expect(section["my option"]).to eq("a value")
       end
 
       it 'should pass extra options to the Option instance' do
@@ -138,7 +138,7 @@ describe 'When generating a document using Generator with section blocks,' do
           end
         end
 
-        document["a section"].option("my option").to_ini.should match(/^    /)
+        expect(document["a section"].option("my option").to_ini).to match(/^    /)
       end
 
       it "should use the parent document's options as a base" do
@@ -148,7 +148,7 @@ describe 'When generating a document using Generator with section blocks,' do
           end
         end
 
-        document["a section"].option("my option").to_ini.should match(/^    /)
+        expect(document["a section"].option("my option").to_ini).to match(/^    /)
       end
 
       it "should use the parent section's options as a base" do
@@ -158,7 +158,7 @@ describe 'When generating a document using Generator with section blocks,' do
           end
         end
 
-        document["a section"].option("my option").to_ini.should match(/^    /)
+        expect(document["a section"].option("my option").to_ini).to match(/^    /)
       end
 
       it "should allow customisation of the parent's options" do
@@ -171,8 +171,8 @@ describe 'When generating a document using Generator with section blocks,' do
         end
 
         option_ini = document["a section"].option("my option").to_ini
-        option_ini.should match(/^    /)
-        option_ini.should match(/ # a comment/)
+        expect(option_ini).to match(/^    /)
+        expect(option_ini).to match(/ # a comment/)
       end
 
       it "should not use the parent section's comment when setting line options" do
@@ -182,7 +182,7 @@ describe 'When generating a document using Generator with section blocks,' do
           end
         end
 
-        document["a section"].option("my option").to_ini.should_not match(/My section$/)
+        expect(document["a section"].option("my option").to_ini).not_to match(/My section$/)
       end
     end
   end
@@ -199,7 +199,7 @@ describe 'When generating a document using Generator with section blocks,' do
         doc.comment("My comment", :indent => '    ')
       end
 
-      document.lines.to_a.first.to_ini.should match(/\A    /)
+      expect(document.lines.to_a.first.to_ini).to match(/\A    /)
     end
 
     it 'should ignore any extra :comment option' do
@@ -207,8 +207,8 @@ describe 'When generating a document using Generator with section blocks,' do
         doc.comment("My comment", :comment => 'Ignored')
       end
 
-      document.lines.to_a.first.to_ini.should match(/My comment/)
-      document.lines.to_a.first.to_ini.should_not match(/Ignored/)
+      expect(document.lines.to_a.first.to_ini).to match(/My comment/)
+      expect(document.lines.to_a.first.to_ini).not_to match(/Ignored/)
     end
 
     describe 'when the context is a Document' do
@@ -218,8 +218,8 @@ describe 'When generating a document using Generator with section blocks,' do
         end
 
         comment = document.lines.to_a.first
-        comment.should be_kind_of(IniParse::Lines::Comment)
-        comment.to_ini.should match(/My comment/)
+        expect(comment).to be_kind_of(IniParse::Lines::Comment)
+        expect(comment.to_ini).to match(/My comment/)
       end
 
       it 'should use the default line options as a base' do
@@ -230,7 +230,7 @@ describe 'When generating a document using Generator with section blocks,' do
         comment_ini = document.lines.to_a.first.to_ini
 
         # Match separator (;) and offset (0).
-        comment_ini.should == '; My comment'
+        expect(comment_ini).to eq('; My comment')
       end
     end
 
@@ -243,8 +243,8 @@ describe 'When generating a document using Generator with section blocks,' do
         end
 
         comment = document['a section'].lines.to_a.first
-        comment.should be_kind_of(IniParse::Lines::Comment)
-        comment.to_ini.should match(/My comment/)
+        expect(comment).to be_kind_of(IniParse::Lines::Comment)
+        expect(comment.to_ini).to match(/My comment/)
       end
 
       it "should use the parent document's line options as a base" do
@@ -254,7 +254,7 @@ describe 'When generating a document using Generator with section blocks,' do
           end
         end
 
-        document['a section'].lines.to_a.first.to_ini.should match(/^     ;/)
+        expect(document['a section'].lines.to_a.first.to_ini).to match(/^     ;/)
       end
 
       it "should use the parent section's line options as a base" do
@@ -264,7 +264,7 @@ describe 'When generating a document using Generator with section blocks,' do
           end
         end
 
-        document['a section'].lines.to_a.first.to_ini.should match(/^     ;/)
+        expect(document['a section'].lines.to_a.first.to_ini).to match(/^     ;/)
       end
 
       it "should allow customisation of the parent's options" do
@@ -275,8 +275,8 @@ describe 'When generating a document using Generator with section blocks,' do
         end
 
         # Match separator (#) and offset (5)
-        document['a section'].lines.to_a.first.to_ini.should \
-          == '     # My comment'
+        expect(document['a section'].lines.to_a.first.to_ini).to \
+          eq('     # My comment')
       end
 
       it "should not use the parent section's comment when setting line options" do
@@ -287,8 +287,8 @@ describe 'When generating a document using Generator with section blocks,' do
         end
 
         comment_ini = document['a section'].lines.to_a.first.to_ini
-        comment_ini.should match(/My comment/)
-        comment_ini.should_not match(/My section/)
+        expect(comment_ini).to match(/My comment/)
+        expect(comment_ini).not_to match(/My section/)
       end
     end
   end
@@ -305,7 +305,7 @@ describe 'When generating a document using Generator with section blocks,' do
         doc.blank
       end
 
-      document.lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
+      expect(document.lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
     end
 
     it 'should add a blank line to the section when it is the context' do
@@ -315,7 +315,7 @@ describe 'When generating a document using Generator with section blocks,' do
         end
       end
 
-      document['a section'].lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
+      expect(document['a section'].lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
     end
   end
 
diff --git a/spec/generator/without_section_blocks_spec.rb b/spec/generator/without_section_blocks_spec.rb
index 00e0cea..1aba308 100644
--- a/spec/generator/without_section_blocks_spec.rb
+++ b/spec/generator/without_section_blocks_spec.rb
@@ -29,17 +29,17 @@ describe 'When generating a document using Generator without section blocks,' do
   describe 'adding a section' do
     it 'should add a Section to the document' do
       @gen.section("a section")
-      @gen.document.should have_section("a section")
+      expect(@gen.document).to have_section("a section")
     end
 
     it 'should change the Generator context to the section' do
       @gen.section("a section")
-      @gen.context.should == @gen.document['a section']
+      expect(@gen.context).to eq(@gen.document['a section'])
     end
 
     it 'should pass extra options to the Section instance' do
       @gen.section("a section", :indent => '    ')
-      @gen.document["a section"].to_ini.should match(/\A    /)
+      expect(@gen.document["a section"].to_ini).to match(/\A    /)
     end
   end
 
@@ -53,13 +53,13 @@ describe 'When generating a document using Generator without section blocks,' do
     it 'should pass extra options to the Option instance' do
       @gen.section("a section")
       @gen.option("my option", "a value", :indent => '    ')
-      @gen.document["a section"].option("my option").to_ini.should match(/^    /)
+      expect(@gen.document["a section"].option("my option").to_ini).to match(/^    /)
     end
 
     describe 'when the context is a Document' do
       it "should add the option to an __anonymous__ section" do
         @gen.option("key", "value")
-        @gen.document['__anonymous__']['key'].should eql('value')
+        expect(@gen.document['__anonymous__']['key']).to eql('value')
       end
     end
 
@@ -67,8 +67,8 @@ describe 'When generating a document using Generator without section blocks,' do
       it 'should add the option to the section' do
         @gen.section("a section")
         @gen.option("my option", "a value")
-        @gen.document["a section"].should have_option("my option")
-        @gen.document["a section"]["my option"].should == "a value"
+        expect(@gen.document["a section"]).to have_option("my option")
+        expect(@gen.document["a section"]["my option"]).to eq("a value")
       end
     end
   end
@@ -82,22 +82,22 @@ describe 'When generating a document using Generator without section blocks,' do
   describe 'adding a comment' do
     it 'should pass extra options to the Option instance' do
       @gen.comment("My comment", :indent => '    ')
-      @gen.document.lines.to_a.first.to_ini.should match(/^    /)
+      expect(@gen.document.lines.to_a.first.to_ini).to match(/^    /)
     end
 
     it 'should ignore any extra :comment option' do
       @gen.comment("My comment", :comment => 'Ignored')
       comment_ini = @gen.document.lines.to_a.first.to_ini
-      comment_ini.should match(/My comment/)
-      comment_ini.should_not match(/Ignored/)
+      expect(comment_ini).to match(/My comment/)
+      expect(comment_ini).not_to match(/Ignored/)
     end
 
     describe 'when the context is a Document' do
       it 'should add a comment to the document' do
         @gen.comment('My comment')
         comment = @gen.document.lines.to_a.first
-        comment.should be_kind_of(IniParse::Lines::Comment)
-        comment.to_ini.should match(/; My comment/)
+        expect(comment).to be_kind_of(IniParse::Lines::Comment)
+        expect(comment.to_ini).to match(/; My comment/)
       end
     end
 
@@ -106,8 +106,8 @@ describe 'When generating a document using Generator without section blocks,' do
         @gen.section('a section')
         @gen.comment('My comment')
         comment = @gen.document['a section'].lines.to_a.first
-        comment.should be_kind_of(IniParse::Lines::Comment)
-        comment.to_ini.should match(/My comment/)
+        expect(comment).to be_kind_of(IniParse::Lines::Comment)
+        expect(comment.to_ini).to match(/My comment/)
       end
     end
   end
@@ -122,14 +122,14 @@ describe 'When generating a document using Generator without section blocks,' do
     it 'should add a blank line to the document when it is the context' do
       @gen.blank
       comment = @gen.document.lines.to_a.first
-      comment.should be_kind_of(IniParse::Lines::Blank)
+      expect(comment).to be_kind_of(IniParse::Lines::Blank)
     end
 
     it 'should add a blank line to the section when it is the context' do
       @gen.section('a section')
       @gen.blank
       comment = @gen.document['a section'].lines.to_a.first
-      comment.should be_kind_of(IniParse::Lines::Blank)
+      expect(comment).to be_kind_of(IniParse::Lines::Blank)
     end
   end
 
diff --git a/spec/iniparse_spec.rb b/spec/iniparse_spec.rb
index 0735660..6acebc9 100644
--- a/spec/iniparse_spec.rb
+++ b/spec/iniparse_spec.rb
@@ -45,18 +45,18 @@ describe "IniParse" do
   end
 
   describe '.open' do
-    before(:each) { File.stub(:read).and_return('[section]') }
+    before(:each) { allow(File).to receive(:read).and_return('[section]') }
 
     it 'should return an IniParse::Document' do
-      IniParse.open('/my/path.ini').should be_kind_of(IniParse::Document)
+      expect(IniParse.open('/my/path.ini')).to be_kind_of(IniParse::Document)
     end
 
     it 'should set the path on the returned Document' do
-      IniParse.open('/my/path.ini').path.should == '/my/path.ini'
+      expect(IniParse.open('/my/path.ini').path).to eq('/my/path.ini')
     end
 
     it 'should read the file at the given path' do
-      File.should_receive(:read).with('/my/path.ini').and_return('[section]')
+      expect(File).to receive(:read).with('/my/path.ini').and_return('[section]')
       IniParse.open('/my/path.ini')
     end
   end
diff --git a/spec/line_collection_spec.rb b/spec/line_collection_spec.rb
index fa0554c..85a0924 100644
--- a/spec/line_collection_spec.rb
+++ b/spec/line_collection_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
 # Shared specs for all Collection types...
 # ----------------------------------------------------------------------------
 
-share_examples_for "LineCollection" do
+shared_examples_for "LineCollection" do
   before(:each) do
     @collection << (@c1 = IniParse::Lines::Comment.new)
     @collection <<  @i1
@@ -16,7 +16,7 @@ share_examples_for "LineCollection" do
 
   describe '#each' do
     it 'should remove blanks and comments by default' do
-      @collection.each { |l| l.should be_kind_of(@i1.class) }
+      @collection.each { |l| expect(l).to be_kind_of(@i1.class) }
     end
 
     it 'should not remove blanks and comments if true is given' do
@@ -27,121 +27,121 @@ share_examples_for "LineCollection" do
         arr << line
       end
 
-      arr.should == [@c1, @i1, @i2, @b1, @i3, @b2]
+      expect(arr).to eq([@c1, @i1, @i2, @b1, @i3, @b2])
     end
   end
 
   describe '#[]' do
     it 'should fetch the correct value' do
-      @collection['first'].should  == @i1
-      @collection['second'].should == @i2
-      @collection['third'].should  == @i3
+      expect(@collection['first']).to  eq(@i1)
+      expect(@collection['second']).to eq(@i2)
+      expect(@collection['third']).to  eq(@i3)
     end
 
     it 'should return nil if the given key does not exist' do
-      @collection['does not exist'].should be_nil
+      expect(@collection['does not exist']).to be_nil
     end
   end
 
   describe '#[]=' do
     it 'should successfully add a new key' do
       @collection['fourth'] = @new
-      @collection['fourth'].should == @new
+      expect(@collection['fourth']).to eq(@new)
     end
 
     it 'should successfully update an existing key' do
       @collection['second'] = @new
-      @collection['second'].should == @new
+      expect(@collection['second']).to eq(@new)
 
       # Make sure the old data is gone.
-      @collection.detect { |s| s.key == 'second' }.should be_nil
+      expect(@collection.detect { |s| s.key == 'second' }).to be_nil
     end
 
     it 'should typecast given keys to a string' do
       @collection[:a_symbol] = @new
-      @collection['a_symbol'].should == @new
+      expect(@collection['a_symbol']).to eq(@new)
     end
   end
 
   describe '#<<' do
     it 'should set the key correctly if given a new item' do
-      @collection.should_not have_key(@new.key)
+      expect(@collection).not_to have_key(@new.key)
       @collection << @new
-      @collection.should have_key(@new.key)
+      expect(@collection).to have_key(@new.key)
     end
 
     it 'should append Blank lines' do
       @collection << IniParse::Lines::Blank.new
-      @collection.instance_variable_get(:@lines).last.should \
+      expect(@collection.instance_variable_get(:@lines).last).to \
         be_kind_of(IniParse::Lines::Blank)
     end
 
     it 'should append Comment lines' do
       @collection << IniParse::Lines::Comment.new
-      @collection.instance_variable_get(:@lines).last.should \
+      expect(@collection.instance_variable_get(:@lines).last).to \
         be_kind_of(IniParse::Lines::Comment)
     end
 
     it 'should return self' do
-      (@collection << @new).should == @collection
+      expect(@collection << @new).to eq(@collection)
     end
   end
 
   describe '#delete' do
     it 'should remove the given value and adjust the indicies' do
-      @collection['second'].should_not be_nil
+      expect(@collection['second']).not_to be_nil
       @collection.delete('second')
-      @collection['second'].should be_nil
-      @collection['first'].should == @i1
-      @collection['third'].should == @i3
+      expect(@collection['second']).to be_nil
+      expect(@collection['first']).to eq(@i1)
+      expect(@collection['third']).to eq(@i3)
     end
 
     it "should do nothing if the supplied key does not exist" do
       @collection.delete('does not exist')
-      @collection['first'].should == @i1
-      @collection['third'].should == @i3
+      expect(@collection['first']).to eq(@i1)
+      expect(@collection['third']).to eq(@i3)
     end
   end
 
   describe '#to_a' do
     it 'should return an array' do
-      @collection.to_a.should be_kind_of(Array)
+      expect(@collection.to_a).to be_kind_of(Array)
     end
 
     it 'should include all lines' do
-      @collection.to_a.should == [@c1, @i1, @i2, @b1, @i3, @b2]
+      expect(@collection.to_a).to eq([@c1, @i1, @i2, @b1, @i3, @b2])
     end
 
     it 'should include references to the same line objects as the collection' do
       @collection << @new
-      @collection.to_a.last.object_id.should == @new.object_id
+      expect(@collection.to_a.last.object_id).to eq(@new.object_id)
     end
   end
 
   describe '#to_hash' do
     it 'should return a hash' do
-      @collection.to_hash.should be_kind_of(Hash)
+      expect(@collection.to_hash).to be_kind_of(Hash)
     end
 
     it 'should have the correct keys' do
       hash = @collection.to_hash
-      hash.keys.length.should == 3
-      hash.should have_key('first')
-      hash.should have_key('second')
-      hash.should have_key('third')
+      expect(hash.keys.length).to eq(3)
+      expect(hash).to have_key('first')
+      expect(hash).to have_key('second')
+      expect(hash).to have_key('third')
     end
 
     it 'should have the correct values' do
       hash = @collection.to_hash
-      hash['first'].should  == @i1
-      hash['second'].should == @i2
-      hash['third'].should  == @i3
+      expect(hash['first']).to  eq(@i1)
+      expect(hash['second']).to eq(@i2)
+      expect(hash['third']).to  eq(@i3)
     end
   end
 
   describe '#keys' do
     it 'should return an array of strings' do
-      @collection.keys.should == ['first', 'second', 'third']
+      expect(@collection.keys).to eq(['first', 'second', 'third'])
     end
   end
 end
@@ -163,7 +163,7 @@ describe 'IniParse::OptionCollection' do
 
   describe '#<<' do
     it 'should raise a LineNotAllowed exception if a Section is pushed' do
-      lambda { @collection << IniParse::Lines::Section.new('s') }.should \
+      expect { @collection << IniParse::Lines::Section.new('s') }.to \
         raise_error(IniParse::LineNotAllowed)
     end
 
@@ -174,7 +174,7 @@ describe 'IniParse::OptionCollection' do
       @collection << option_one
       @collection << option_two
 
-      @collection['k'].should == [option_one, option_two]
+      expect(@collection['k']).to eq([option_one, option_two])
     end
   end
 
@@ -182,7 +182,7 @@ describe 'IniParse::OptionCollection' do
     it 'should handle duplicates' do
       @collection << @i1 << @i2 << @i3
       @collection << IniParse::Lines::Option.new('first', 'v5')
-      @collection.keys.should == ['first', 'second', 'third']
+      expect(@collection.keys).to eq(['first', 'second', 'third'])
     end
   end
 end
@@ -202,7 +202,7 @@ describe 'IniParse::SectionCollection' do
     it 'should add merge Section with the other, if it is a duplicate' do
       new_section = IniParse::Lines::Section.new('first')
       @collection << @i1
-      @i1.should_receive(:merge!).with(new_section).once
+      expect(@i1).to receive(:merge!).with(new_section).once
       @collection << new_section
     end
   end
diff --git a/spec/lines_spec.rb b/spec/lines_spec.rb
index ec64945..c34a8cf 100644
--- a/spec/lines_spec.rb
+++ b/spec/lines_spec.rb
@@ -13,44 +13,44 @@ end
 describe "IniParse::Lines::Line module" do
   describe '#to_ini' do
     it 'should return +line_contents+' do
-      IniParse::Test::FakeLine.new.to_ini.should == 'fake line'
+      expect(IniParse::Test::FakeLine.new.to_ini).to eq('fake line')
     end
 
     it 'should preserve line indents' do
-      IniParse::Test::FakeLine.new(
+      expect(IniParse::Test::FakeLine.new(
         :indent => '    '
-      ).to_ini.should == '    fake line'
+      ).to_ini).to eq('    fake line')
     end
 
     describe 'when a comment is set' do
       it 'should correctly include the comment' do
-        IniParse::Test::FakeLine.new(
+        expect(IniParse::Test::FakeLine.new(
           :comment => 'comment', :comment_sep => ';', :comment_offset => 10
-        ).to_ini.should == 'fake line ; comment'
+        ).to_ini).to eq('fake line ; comment')
       end
 
       it 'should correctly indent the comment' do
-        IniParse::Test::FakeLine.new(
+        expect(IniParse::Test::FakeLine.new(
           :comment => 'comment', :comment_sep => ';', :comment_offset => 15
-        ).to_ini.should == 'fake line      ; comment'
+        ).to_ini).to eq('fake line      ; comment')
       end
 
       it 'should use ";" as a default comment seperator' do
-        IniParse::Test::FakeLine.new(
+        expect(IniParse::Test::FakeLine.new(
           :comment => 'comment'
-        ).to_ini.should == 'fake line ; comment'
+        ).to_ini).to eq('fake line ; comment')
       end
 
       it 'should use the correct seperator' do
-        IniParse::Test::FakeLine.new(
+        expect(IniParse::Test::FakeLine.new(
           :comment => 'comment', :comment_sep => '#'
-        ).to_ini.should == 'fake line # comment'
+        ).to_ini).to eq('fake line # comment')
       end
 
       it 'should use the ensure a space is added before the comment seperator' do
-        IniParse::Test::FakeLine.new(
+        expect(IniParse::Test::FakeLine.new(
           :comment => 'comment', :comment_sep => ';', :comment_offset => 0
-        ).to_ini.should == 'fake line ; comment'
+        ).to_ini).to eq('fake line ; comment')
       end
 
       it 'should not add an extra space if the line is blank' do
@@ -58,34 +58,34 @@ describe "IniParse::Lines::Line module" do
           :comment => 'comment', :comment_sep => ';', :comment_offset => 0
         )
 
-        line.stub(:line_contents).and_return('')
-        line.to_ini.should == '; comment'
+        allow(line).to receive(:line_contents).and_return('')
+        expect(line.to_ini).to eq('; comment')
       end
     end
 
     describe 'when no comment is set' do
       it 'should not add trailing space if :comment_offset has a value' do
-        IniParse::Test::FakeLine.new(:comment_offset => 10).to_ini.should == 'fake line'
+        expect(IniParse::Test::FakeLine.new(:comment_offset => 10).to_ini).to eq('fake line')
       end
 
       it 'should not add a comment seperator :comment_sep has a value' do
-        IniParse::Test::FakeLine.new(:comment_sep => ';').to_ini.should == 'fake line'
+        expect(IniParse::Test::FakeLine.new(:comment_sep => ';').to_ini).to eq('fake line')
       end
     end
   end
 
   describe '#has_comment?' do
     it 'should return true if :comment has a non-blank value' do
-      IniParse::Test::FakeLine.new(:comment => 'comment').should have_comment
+      expect(IniParse::Test::FakeLine.new(:comment => 'comment')).to have_comment
     end
 
     it 'should return true if :comment has a blank value' do
-      IniParse::Test::FakeLine.new(:comment => '').should have_comment
+      expect(IniParse::Test::FakeLine.new(:comment => '')).to have_comment
     end
 
     it 'should return false if :comment has a nil value' do
-      IniParse::Test::FakeLine.new.should_not have_comment
-      IniParse::Test::FakeLine.new(:comment => nil).should_not have_comment
+      expect(IniParse::Test::FakeLine.new).not_to have_comment
+      expect(IniParse::Test::FakeLine.new(:comment => nil)).not_to have_comment
     end
   end
 end
@@ -98,20 +98,20 @@ describe 'IniParse::Lines::Section' do
   before(:each) { @section = IniParse::Lines::Section.new('a section') }
 
   it 'should respond_to +lines+' do
-    @section.should respond_to(:lines)
+    expect(@section).to respond_to(:lines)
   end
 
   it 'should not respond_to +lines=+' do
-    @section.should_not respond_to(:lines=)
+    expect(@section).not_to respond_to(:lines=)
   end
 
   it 'should include Enumerable' do
-    IniParse::Lines::Section.included_modules.should include(Enumerable)
+    expect(IniParse::Lines::Section.included_modules).to include(Enumerable)
   end
 
   describe '#initialize' do
     it 'should typecast the given key to a string' do
-      IniParse::Lines::Section.new(:symbol).key.should == 'symbol'
+      expect(IniParse::Lines::Section.new(:symbol).key).to eq('symbol')
     end
   end
 
@@ -119,68 +119,68 @@ describe 'IniParse::Lines::Section' do
     it 'should retrieve the line identified by the given key' do
       option = IniParse::Lines::Option.new('k', 'value one')
       @section.lines << option
-      @section.option('k').should == option
+      expect(@section.option('k')).to eq(option)
     end
 
     it 'should return nil if the given key does not exist' do
-      @section.option('does_not_exist').should be_nil
+      expect(@section.option('does_not_exist')).to be_nil
     end
   end
 
   describe '#each' do
     it 'should call #each on +lines+' do
-      @section.lines.should_receive(:each)
+      expect(@section.lines).to receive(:each)
       @section.each { |l| }
     end
   end
 
   describe '#[]' do
     it 'should return nil if the given key does not exist' do
-      @section['k'].should be_nil
+      expect(@section['k']).to be_nil
     end
 
     it 'should return a value if the given key exists' do
       @section.lines << IniParse::Lines::Option.new('k', 'v')
-      @section['k'].should == 'v'
+      expect(@section['k']).to eq('v')
     end
 
     it 'should return an array of values if the key is a duplicate' do
       @section.lines << IniParse::Lines::Option.new('k', 'v1')
       @section.lines << IniParse::Lines::Option.new('k', 'v2')
       @section.lines << IniParse::Lines::Option.new('k', 'v3')
-      @section['k'].should == ['v1', 'v2', 'v3']
+      expect(@section['k']).to eq(['v1', 'v2', 'v3'])
     end
 
     it 'should typecast the key to a string' do
       @section.lines << IniParse::Lines::Option.new('k', 'v')
-      @section[:k].should == 'v'
+      expect(@section[:k]).to eq('v')
     end
   end
 
   describe '#[]=' do
     it 'should add a new Option with the given key and value' do
       @section['k'] = 'a value'
-      @section.option('k').should be_kind_of(IniParse::Lines::Option)
-      @section['k'].should == 'a value'
+      expect(@section.option('k')).to be_kind_of(IniParse::Lines::Option)
+      expect(@section['k']).to eq('a value')
     end
 
     it 'should update the Option if one already exists' do
       @section.lines << IniParse::Lines::Option.new('k', 'orig value')
       @section['k'] = 'new value'
-      @section['k'].should == 'new value'
+      expect(@section['k']).to eq('new value')
     end
 
     it 'should replace the existing Option if it is an array' do
       @section.lines << IniParse::Lines::Option.new('k', 'v1')
       @section.lines << IniParse::Lines::Option.new('k', 'v2')
       @section['k'] = 'new value'
-      @section.option('k').should be_kind_of(IniParse::Lines::Option)
-      @section['k'].should == 'new value'
+      expect(@section.option('k')).to be_kind_of(IniParse::Lines::Option)
+      expect(@section['k']).to eq('new value')
     end
 
     it 'should typecast the key to a string' do
       @section[:k] = 'a value'
-      @section['k'].should == 'a value'
+      expect(@section['k']).to eq('a value')
     end
   end
 
@@ -199,16 +199,16 @@ describe 'IniParse::Lines::Section' do
       @new_section.lines << IniParse::Lines::Option.new('d', 'val4')
 
       @section.merge!(@new_section)
-      @section['a'].should == 'val1'
-      @section['b'].should == 'val2'
-      @section['c'].should == 'val3'
-      @section['d'].should == 'val4'
+      expect(@section['a']).to eq('val1')
+      expect(@section['b']).to eq('val2')
+      expect(@section['c']).to eq('val3')
+      expect(@section['d']).to eq('val4')
     end
 
     it 'should handle duplicates' do
       @new_section.lines << IniParse::Lines::Option.new('a', 'val2')
       @section.merge!(@new_section)
-      @section['a'].should == ['val1', 'val2']
+      expect(@section['a']).to eq(['val1', 'val2'])
     end
 
     it 'should handle duplicates on both sides' do
@@ -217,7 +217,7 @@ describe 'IniParse::Lines::Section' do
       @new_section.lines << IniParse::Lines::Option.new('a', 'val4')
 
       @section.merge!(@new_section)
-      @section['a'].should == ['val1', 'val2', 'val3', 'val4']
+      expect(@section['a']).to eq(['val1', 'val2', 'val3', 'val4'])
     end
 
     it 'should copy blank lines' do
@@ -225,7 +225,7 @@ describe 'IniParse::Lines::Section' do
       @section.merge!(@new_section)
       line = nil
       @section.each(true) { |l| line = l }
-      line.should be_kind_of(IniParse::Lines::Blank)
+      expect(line).to be_kind_of(IniParse::Lines::Blank)
     end
 
     it 'should copy comments' do
@@ -233,7 +233,7 @@ describe 'IniParse::Lines::Section' do
       @section.merge!(@new_section)
       line = nil
       @section.each(true) { |l| line = l }
-      line.should be_kind_of(IniParse::Lines::Comment)
+      expect(line).to be_kind_of(IniParse::Lines::Comment)
     end
   end
 
@@ -247,27 +247,27 @@ describe 'IniParse::Lines::Section' do
     end
 
     it 'removes the option given a key' do
-      lambda { @section.delete('a') }.
-        should change { @section['a'] }.to(nil)
+      expect { @section.delete('a') }.
+        to change { @section['a'] }.to(nil)
     end
 
     it 'removes the option given an Option' do
-      lambda { @section.delete(opt_one) }.
-        should change { @section['a'] }.to(nil)
+      expect { @section.delete(opt_one) }.
+        to change { @section['a'] }.to(nil)
     end
 
     it 'should not remove non-matching lines' do
-      lambda { @section.delete('a') }.should_not change { @section['c'] }
+      expect { @section.delete('a') }.not_to change { @section['c'] }
     end
 
     it 'returns the section' do
-      @section.delete('a').should eql(@section)
+      expect(@section.delete('a')).to eql(@section)
     end
   end
 
   describe '#to_ini' do
     it 'should include the section key' do
-      IniParse::Lines::Section.new('a section').to_ini.should == '[a section]'
+      expect(IniParse::Lines::Section.new('a section').to_ini).to eq('[a section]')
     end
 
     it 'should include lines belonging to the section' do
@@ -278,22 +278,24 @@ describe 'IniParse::Lines::Section' do
       )
       @section.lines << IniParse::Lines::Option.new('b', 'val2')
 
-      @section.to_ini.should ==
+      expect(@section.to_ini).to eq(
         "[a section]\n" \
         "a = val1\n" \
         "\n" \
         "; my comment\n" \
         "b = val2"
+      )
     end
 
     it 'should include duplicate lines' do
       @section.lines << IniParse::Lines::Option.new('a', 'val1')
       @section.lines << IniParse::Lines::Option.new('a', 'val2')
 
-      @section.to_ini.should ==
+      expect(@section.to_ini).to eq(
         "[a section]\n" \
         "a = val1\n" \
         "a = val2"
+      )
     end
   end
 
@@ -303,11 +305,11 @@ describe 'IniParse::Lines::Section' do
     end
 
     it 'should return true if an option with the given key exists' do
-      @section.should have_option('first')
+      expect(@section).to have_option('first')
     end
 
     it 'should return true if no option with the given key exists' do
-      @section.should_not have_option('second')
+      expect(@section).not_to have_option('second')
     end
   end
 end
@@ -319,13 +321,13 @@ end
 describe 'Iniparse::Lines::Option' do
   describe '#initialize' do
     it 'should typecast the given key to a string' do
-      IniParse::Lines::Option.new(:symbol, '').key.should == 'symbol'
+      expect(IniParse::Lines::Option.new(:symbol, '').key).to eq('symbol')
     end
   end
 
   describe '#to_ini' do
     it 'should include the key and value' do
-      IniParse::Lines::Option.new('key', 'value').to_ini.should == 'key = value'
+      expect(IniParse::Lines::Option.new('key', 'value').to_ini).to eq('key = value')
     end
   end
 
@@ -335,70 +337,70 @@ describe 'Iniparse::Lines::Option' do
     end
 
     it 'should typecast empty values to nil' do
-      parse('key =').should be_option_tuple('key', nil)
-      parse('key = ').should be_option_tuple('key', nil)
-      parse('key =    ').should be_option_tuple('key', nil)
+      expect(parse('key =')).to be_option_tuple('key', nil)
+      expect(parse('key = ')).to be_option_tuple('key', nil)
+      expect(parse('key =    ')).to be_option_tuple('key', nil)
     end
 
     it 'should not typecast "true" if true is part of a word' do
-      parse('key = TestTrueTest').should be_option_tuple('key', 'TestTrueTest')
-      parse('key = TrueTest').should be_option_tuple('key', 'TrueTest')
-      parse('key = TestTrue').should be_option_tuple('key', 'TestTrue')
+      expect(parse('key = TestTrueTest')).to be_option_tuple('key', 'TestTrueTest')
+      expect(parse('key = TrueTest')).to be_option_tuple('key', 'TrueTest')
+      expect(parse('key = TestTrue')).to be_option_tuple('key', 'TestTrue')
     end
 
     it 'should not typecast "false" if false is part of a word' do
-      parse('key = TestFalseTest').should be_option_tuple('key', 'TestFalseTest')
-      parse('key = FalseTest').should be_option_tuple('key', 'FalseTest')
-      parse('key = TestFalse').should be_option_tuple('key', 'TestFalse')
+      expect(parse('key = TestFalseTest')).to be_option_tuple('key', 'TestFalseTest')
+      expect(parse('key = FalseTest')).to be_option_tuple('key', 'FalseTest')
+      expect(parse('key = TestFalse')).to be_option_tuple('key', 'TestFalse')
     end
 
     it 'should typecast "true" to TrueClass' do
-      parse('key = true').should be_option_tuple('key', true)
-      parse('key = TRUE').should be_option_tuple('key', true)
+      expect(parse('key = true')).to be_option_tuple('key', true)
+      expect(parse('key = TRUE')).to be_option_tuple('key', true)
     end
 
     it 'should typecast "false" to FalseClass' do
-      parse('key = false').should be_option_tuple('key', false)
-      parse('key = FALSE').should be_option_tuple('key', false)
+      expect(parse('key = false')).to be_option_tuple('key', false)
+      expect(parse('key = FALSE')).to be_option_tuple('key', false)
     end
 
     it 'should typecast integer values to Integer' do
-      parse('key = 1').should be_option_tuple('key', 1)
-      parse('key = 10').should be_option_tuple('key', 10)
+      expect(parse('key = 1')).to be_option_tuple('key', 1)
+      expect(parse('key = 10')).to be_option_tuple('key', 10)
     end
 
     it 'should not typecast integers with a leading 0 to Integer' do
-      parse('key = 0700').should be_option_tuple('key', '0700')
+      expect(parse('key = 0700')).to be_option_tuple('key', '0700')
     end
 
     it 'should typecast negative integer values to Integer' do
-      parse('key = -1').should be_option_tuple('key', -1)
+      expect(parse('key = -1')).to be_option_tuple('key', -1)
     end
 
     it 'should typecast float values to Float' do
-      parse('key = 3.14159265').should be_option_tuple('key', 3.14159265)
+      expect(parse('key = 3.14159265')).to be_option_tuple('key', 3.14159265)
     end
 
     it 'should typecast negative float values to Float' do
-      parse('key = -3.14159265').should be_option_tuple('key', -3.14159265)
+      expect(parse('key = -3.14159265')).to be_option_tuple('key', -3.14159265)
     end
 
     it 'should typecast scientific notation numbers to Float' do
-      parse('key = 10e5').should be_option_tuple('key', 10e5)
-      parse('key = 10e+5').should be_option_tuple('key', 10e5)
-      parse('key = 10e-5').should be_option_tuple('key', 10e-5)
+      expect(parse('key = 10e5')).to be_option_tuple('key', 10e5)
+      expect(parse('key = 10e+5')).to be_option_tuple('key', 10e5)
+      expect(parse('key = 10e-5')).to be_option_tuple('key', 10e-5)
 
-      parse('key = -10e5').should be_option_tuple('key', -10e5)
-      parse('key = -10e+5').should be_option_tuple('key', -10e5)
-      parse('key = -10e-5').should be_option_tuple('key', -10e-5)
+      expect(parse('key = -10e5')).to be_option_tuple('key', -10e5)
+      expect(parse('key = -10e+5')).to be_option_tuple('key', -10e5)
+      expect(parse('key = -10e-5')).to be_option_tuple('key', -10e-5)
 
-      parse('key = 3.14159265e5').should be_option_tuple('key', 3.14159265e5)
-      parse('key = 3.14159265e+5').should be_option_tuple('key', 3.14159265e5)
-      parse('key = 3.14159265e-5').should be_option_tuple('key', 3.14159265e-5)
+      expect(parse('key = 3.14159265e5')).to be_option_tuple('key', 3.14159265e5)
+      expect(parse('key = 3.14159265e+5')).to be_option_tuple('key', 3.14159265e5)
+      expect(parse('key = 3.14159265e-5')).to be_option_tuple('key', 3.14159265e-5)
 
-      parse('key = -3.14159265e5').should be_option_tuple('key', -3.14159265e5)
-      parse('key = -3.14159265e+5').should be_option_tuple('key', -3.14159265e5)
-      parse('key = -3.14159265e-5').should be_option_tuple('key', -3.14159265e-5)
+      expect(parse('key = -3.14159265e5')).to be_option_tuple('key', -3.14159265e5)
+      expect(parse('key = -3.14159265e+5')).to be_option_tuple('key', -3.14159265e5)
+      expect(parse('key = -3.14159265e-5')).to be_option_tuple('key', -3.14159265e-5)
     end
   end
 end
@@ -414,34 +416,34 @@ end
 describe 'IniParse::Lines::Comment' do
   describe '#has_comment?' do
     it 'should return true if :comment has a non-blank value' do
-      IniParse::Lines::Comment.new(:comment => 'comment').should have_comment
+      expect(IniParse::Lines::Comment.new(:comment => 'comment')).to have_comment
     end
 
     it 'should return true if :comment has a blank value' do
-      IniParse::Lines::Comment.new(:comment => '').should have_comment
+      expect(IniParse::Lines::Comment.new(:comment => '')).to have_comment
     end
 
     it 'should return true if :comment has a nil value' do
-      IniParse::Lines::Comment.new.should have_comment
-      IniParse::Lines::Comment.new(:comment => nil).should have_comment
+      expect(IniParse::Lines::Comment.new).to have_comment
+      expect(IniParse::Lines::Comment.new(:comment => nil)).to have_comment
     end
   end
 
   describe '#to_ini' do
     it 'should return the comment' do
-      IniParse::Lines::Comment.new(
+      expect(IniParse::Lines::Comment.new(
         :comment => 'a comment'
-      ).to_ini.should == '; a comment'
+      ).to_ini).to eq('; a comment')
     end
 
     it 'should preserve comment offset' do
-      IniParse::Lines::Comment.new(
+      expect(IniParse::Lines::Comment.new(
         :comment => 'a comment', :comment_offset => 10
-      ).to_ini.should == '          ; a comment'
+      ).to_ini).to eq('          ; a comment')
     end
 
     it 'should return just the comment_sep if the comment is blank' do
-      IniParse::Lines::Comment.new.to_ini.should == ';'
+      expect(IniParse::Lines::Comment.new.to_ini).to eq(';')
     end
   end
 end
diff --git a/spec/parser/document_parsing_spec.rb b/spec/parser/document_parsing_spec.rb
index 4636aae..c882542 100644
--- a/spec/parser/document_parsing_spec.rb
+++ b/spec/parser/document_parsing_spec.rb
@@ -9,53 +9,53 @@ describe 'Parsing a document' do
     end
 
     it 'should have a comment as the first line' do
-      @doc.lines.to_a.first.should be_kind_of(IniParse::Lines::Comment)
+      expect(@doc.lines.to_a.first).to be_kind_of(IniParse::Lines::Comment)
     end
 
     it 'should have one section' do
-      @doc.lines.keys.should == ['first_section']
+      expect(@doc.lines.keys).to eq(['first_section'])
     end
 
     it 'should have one option belonging to `first_section`' do
-      @doc['first_section']['key'].should == 'value'
+      expect(@doc['first_section']['key']).to eq('value')
     end
   end
 
   it 'should allow blank lines to preceed the first section' do
-    lambda {
+    expect {
       @doc = IniParse::Parser.new(fixture(:blank_before_section)).parse
-    }.should_not raise_error
+    }.not_to raise_error
 
-    @doc.lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
+    expect(@doc.lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
   end
 
   it 'should allow a blank line to belong to a section' do
-    lambda {
+    expect {
       @doc = IniParse::Parser.new(fixture(:blank_in_section)).parse
-    }.should_not raise_error
+    }.not_to raise_error
 
-    @doc['first_section'].lines.to_a.first.should be_kind_of(IniParse::Lines::Blank)
+    expect(@doc['first_section'].lines.to_a.first).to be_kind_of(IniParse::Lines::Blank)
   end
 
   it 'should permit comments on their own line' do
-    lambda {
+    expect {
       @doc = IniParse::Parser.new(fixture(:comment_line)).parse
-    }.should_not raise_error
+    }.not_to raise_error
 
     line = @doc['first_section'].lines.to_a.first
-    line.comment.should eql('; block comment ;')
+    expect(line.comment).to eql('; block comment ;')
   end
 
   it 'should permit options before the first section' do
     doc = IniParse::Parser.new(fixture(:option_before_section)).parse
 
-    doc.lines.should have_key('__anonymous__')
-    doc['__anonymous__']['foo'].should eql('bar')
-    doc['foo']['another'].should eql('thing')
+    expect(doc.lines).to have_key('__anonymous__')
+    expect(doc['__anonymous__']['foo']).to eql('bar')
+    expect(doc['foo']['another']).to eql('thing')
   end
 
   it 'should raise ParseError if a line could not be parsed' do
-    lambda { IniParse::Parser.new(fixture(:invalid_line)).parse }.should \
+    expect { IniParse::Parser.new(fixture(:invalid_line)).parse }.to \
       raise_error(IniParse::ParseError)
   end
 
@@ -65,20 +65,20 @@ describe 'Parsing a document' do
     end
 
     it 'should have two sections' do
-      @doc.lines.to_a.length.should == 2
+      expect(@doc.lines.to_a.length).to eq(2)
     end
 
     it 'should have one section' do
-      @doc.lines.keys.should == ['first_section = name',
-                                 'another_section = a name']
+      expect(@doc.lines.keys).to eq(['first_section = name',
+                                 'another_section = a name'])
     end
 
     it 'should have one option belonging to `first_section = name`' do
-      @doc['first_section = name']['key'].should == 'value'
+      expect(@doc['first_section = name']['key']).to eq('value')
     end
 
     it 'should have one option belonging to `another_section = a name`' do
-      @doc['another_section = a name']['another'].should == 'thing'
+      expect(@doc['another_section = a name']['another']).to eq('thing')
     end
   end
 
@@ -89,19 +89,19 @@ describe 'Parsing a document' do
 
     it 'should only add the section once' do
       # "first_section" and "second_section".
-      @doc.lines.to_a.length.should == 2
+      expect(@doc.lines.to_a.length).to eq(2)
     end
 
     it 'should retain values from the first time' do
-      @doc['first_section']['key'].should == 'value'
+      expect(@doc['first_section']['key']).to eq('value')
     end
 
     it 'should add new keys' do
-      @doc['first_section']['third'].should == 'fourth'
+      expect(@doc['first_section']['third']).to eq('fourth')
     end
 
     it 'should merge in duplicate keys' do
-      @doc['first_section']['another'].should == %w( thing again )
+      expect(@doc['first_section']['another']).to eq(%w( thing again ))
     end
   end
 end
diff --git a/spec/parser/line_parsing_spec.rb b/spec/parser/line_parsing_spec.rb
index 3183bc5..818da81 100644
--- a/spec/parser/line_parsing_spec.rb
+++ b/spec/parser/line_parsing_spec.rb
@@ -4,12 +4,12 @@ require 'spec_helper'
 
 describe 'Parsing a line' do
   it 'should strip leading whitespace and set the :indent option' do
-    IniParse::Parser.parse_line('  [section]').should \
+    expect(IniParse::Parser.parse_line('  [section]')).to \
       be_section_tuple(:any, {:indent => '  '})
   end
 
   it 'should raise an error if the line could not be matched' do
-    lambda { IniParse::Parser.parse_line('invalid line') }.should \
+    expect { IniParse::Parser.parse_line('invalid line') }.to \
       raise_error(IniParse::ParseError)
   end
 
@@ -17,7 +17,7 @@ describe 'Parsing a line' do
     begin
       # Remove last type.
       type = IniParse::Parser.parse_types.pop
-      type.should_not_receive(:parse)
+      expect(type).not_to receive(:parse)
       IniParse::Parser.parse_line('[section]')
     ensure
       IniParse::Parser.parse_types << type
@@ -36,20 +36,20 @@ describe 'Parsing a line' do
     end
 
     it 'should return an option tuple' do
-      @tuple.should be_option_tuple('k', 'v')
+      expect(@tuple).to be_option_tuple('k', 'v')
     end
 
     it 'should set no indent, comment, offset or separator' do
-      @tuple.last[:indent].should be_nil
-      @tuple.last[:comment].should be_nil
-      @tuple.last[:comment_offset].should be_nil
-      @tuple.last[:comment_sep].should be_nil
+      expect(@tuple.last[:indent]).to be_nil
+      expect(@tuple.last[:comment]).to be_nil
+      expect(@tuple.last[:comment_offset]).to be_nil
+      expect(@tuple.last[:comment_sep]).to be_nil
     end
   end
 
   describe 'with "k = a value with spaces"' do
     it 'should return an option tuple' do
-      IniParse::Parser.parse_line('k = a value with spaces').should \
+      expect(IniParse::Parser.parse_line('k = a value with spaces')).to \
         be_option_tuple('k', 'a value with spaces')
     end
   end
@@ -60,19 +60,19 @@ describe 'Parsing a line' do
     end
 
     it 'should return an option tuple' do
-      @tuple.should be_option_tuple('k', 'v')
+      expect(@tuple).to be_option_tuple('k', 'v')
     end
 
     it 'should set the comment to "a comment"' do
-      @tuple.should be_option_tuple(:any, :any, :comment => 'a comment')
+      expect(@tuple).to be_option_tuple(:any, :any, :comment => 'a comment')
     end
 
     it 'should set the comment separator to ";"' do
-      @tuple.should be_option_tuple(:any, :any, :comment_sep => ';')
+      expect(@tuple).to be_option_tuple(:any, :any, :comment_sep => ';')
     end
 
     it 'should set the comment offset to 6' do
-      @tuple.should be_option_tuple(:any, :any, :comment_offset => 6)
+      expect(@tuple).to be_option_tuple(:any, :any, :comment_offset => 6)
     end
   end
 
@@ -82,13 +82,13 @@ describe 'Parsing a line' do
     end
 
     it 'should return an option tuple with the correct value' do
-      @tuple.should be_option_tuple(:any, 'v;w;x y;z')
+      expect(@tuple).to be_option_tuple(:any, 'v;w;x y;z')
     end
 
     it 'should not set a comment' do
-      @tuple.last[:comment].should be_nil
-      @tuple.last[:comment_offset].should be_nil
-      @tuple.last[:comment_sep].should be_nil
+      expect(@tuple.last[:comment]).to be_nil
+      expect(@tuple.last[:comment_offset]).to be_nil
+      expect(@tuple.last[:comment_sep]).to be_nil
     end
   end
 
@@ -98,58 +98,58 @@ describe 'Parsing a line' do
     end
 
     it 'should return an option tuple with the correct value' do
-      @tuple.should be_option_tuple(:any, 'v;w')
+      expect(@tuple).to be_option_tuple(:any, 'v;w')
     end
 
     it 'should set the comment to "a comment"' do
-      @tuple.should be_option_tuple(:any, :any, :comment => 'a comment')
+      expect(@tuple).to be_option_tuple(:any, :any, :comment => 'a comment')
     end
 
     it 'should set the comment separator to ";"' do
-      @tuple.should be_option_tuple(:any, :any, :comment_sep => ';')
+      expect(@tuple).to be_option_tuple(:any, :any, :comment_sep => ';')
     end
 
     it 'should set the comment offset to 8' do
-      @tuple.should be_option_tuple(:any, :any, :comment_offset => 8)
+      expect(@tuple).to be_option_tuple(:any, :any, :comment_offset => 8)
     end
   end
 
   describe 'with "key=value"' do
     it 'should return an option tuple with the correct key and value' do
-      IniParse::Parser.parse_line('key=value').should \
+      expect(IniParse::Parser.parse_line('key=value')).to \
         be_option_tuple('key', 'value')
     end
   end
 
   describe 'with "key= value"' do
     it 'should return an option tuple with the correct key and value' do
-      IniParse::Parser.parse_line('key= value').should \
+      expect(IniParse::Parser.parse_line('key= value')).to \
         be_option_tuple('key', 'value')
     end
   end
 
   describe 'with "key =value"' do
     it 'should return an option tuple with the correct key and value' do
-      IniParse::Parser.parse_line('key =value').should \
+      expect(IniParse::Parser.parse_line('key =value')).to \
         be_option_tuple('key', 'value')
     end
   end
 
   describe 'with "key   =   value"' do
     it 'should return an option tuple with the correct key and value' do
-      IniParse::Parser.parse_line('key   =   value').should \
+      expect(IniParse::Parser.parse_line('key   =   value')).to \
         be_option_tuple('key', 'value')
     end
   end
 
   describe 'with "key ="' do
     it 'should return an option tuple with the correct key' do
-      IniParse::Parser.parse_line('key =').should \
+      expect(IniParse::Parser.parse_line('key =')).to \
         be_option_tuple('key')
     end
 
     it 'should set the option value to nil' do
-      IniParse::Parser.parse_line('key =').should \
+      expect(IniParse::Parser.parse_line('key =')).to \
         be_option_tuple(:any, nil)
     end
   end
@@ -157,49 +157,49 @@ describe 'Parsing a line' do
 
   describe 'with "key = EEjDDJJjDJDJD233232=="' do
     it 'should include the "equals" in the option value' do
-      IniParse::Parser.parse_line('key = EEjDDJJjDJDJD233232==').should \
+      expect(IniParse::Parser.parse_line('key = EEjDDJJjDJDJD233232==')).to \
         be_option_tuple('key', 'EEjDDJJjDJDJD233232==')
     end
   end
 
   describe 'with "key = ==EEjDDJJjDJDJD233232"' do
     it 'should include the "equals" in the option value' do
-      IniParse::Parser.parse_line('key = ==EEjDDJJjDJDJD233232').should \
+      expect(IniParse::Parser.parse_line('key = ==EEjDDJJjDJDJD233232')).to \
         be_option_tuple('key', '==EEjDDJJjDJDJD233232')
     end
   end
 
   describe 'with "key.two = value"' do
     it 'should return an option tuple with the correct key' do
-      IniParse::Parser.parse_line('key.two = value').should \
+      expect(IniParse::Parser.parse_line('key.two = value')).to \
         be_option_tuple('key.two')
     end
   end
 
   describe 'with "key/with/slashes = value"' do
     it 'should return an option tuple with the correct key' do
-      IniParse::Parser.parse_line('key/with/slashes = value').should \
+      expect(IniParse::Parser.parse_line('key/with/slashes = value')).to \
         be_option_tuple('key/with/slashes', 'value')
     end
   end
 
   describe 'with "key_with_underscores = value"' do
     it 'should return an option tuple with the correct key' do
-      IniParse::Parser.parse_line('key_with_underscores = value').should \
+      expect(IniParse::Parser.parse_line('key_with_underscores = value')).to \
         be_option_tuple('key_with_underscores', 'value')
     end
   end
 
   describe 'with "key-with-dashes = value"' do
     it 'should return an option tuple with the correct key' do
-      IniParse::Parser.parse_line('key-with-dashes = value').should \
+      expect(IniParse::Parser.parse_line('key-with-dashes = value')).to \
         be_option_tuple('key-with-dashes', 'value')
     end
   end
 
   describe 'with "key with spaces = value"' do
     it 'should return an option tuple with the correct key' do
-      IniParse::Parser.parse_line('key with spaces = value').should \
+      expect(IniParse::Parser.parse_line('key with spaces = value')).to \
         be_option_tuple('key with spaces', 'value')
     end
   end
@@ -216,27 +216,27 @@ describe 'Parsing a line' do
     end
 
     it 'should return a section tuple' do
-      @tuple.should be_section_tuple('section')
+      expect(@tuple).to be_section_tuple('section')
     end
 
     it 'should set no indent, comment, offset or separator' do
-      @tuple.last[:indent].should be_nil
-      @tuple.last[:comment].should be_nil
-      @tuple.last[:comment_offset].should be_nil
-      @tuple.last[:comment_sep].should be_nil
+      expect(@tuple.last[:indent]).to be_nil
+      expect(@tuple.last[:comment]).to be_nil
+      expect(@tuple.last[:comment_offset]).to be_nil
+      expect(@tuple.last[:comment_sep]).to be_nil
     end
   end
 
   describe 'with "[section with whitespace]"' do
     it 'should return a section tuple with the correct key' do
-      IniParse::Parser.parse_line('[section with whitespace]').should \
+      expect(IniParse::Parser.parse_line('[section with whitespace]')).to \
         be_section_tuple('section with whitespace')
     end
   end
 
   describe 'with "[  section with surounding whitespace  ]"' do
     it 'should return a section tuple with the correct key' do
-      IniParse::Parser.parse_line('[  section with surounding whitespace  ]').should \
+      expect(IniParse::Parser.parse_line('[  section with surounding whitespace  ]')).to \
         be_section_tuple('  section with surounding whitespace  ')
     end
   end
@@ -247,19 +247,19 @@ describe 'Parsing a line' do
     end
 
     it 'should return a section tuple' do
-      @tuple.should be_section_tuple('section')
+      expect(@tuple).to be_section_tuple('section')
     end
 
     it 'should set the comment to "a comment"' do
-      @tuple.should be_section_tuple(:any, :comment => 'a comment')
+      expect(@tuple).to be_section_tuple(:any, :comment => 'a comment')
     end
 
     it 'should set the comment separator to ";"' do
-      @tuple.should be_section_tuple(:any, :comment_sep => ';')
+      expect(@tuple).to be_section_tuple(:any, :comment_sep => ';')
     end
 
     it 'should set the comment offset to 10' do
-      @tuple.should be_section_tuple(:any, :comment_offset => 10)
+      expect(@tuple).to be_section_tuple(:any, :comment_offset => 10)
     end
   end
 
@@ -269,14 +269,14 @@ describe 'Parsing a line' do
     end
 
     it 'should return a section tuple with the correct key' do
-      @tuple.should be_section_tuple('section;with#comment;chars')
+      expect(@tuple).to be_section_tuple('section;with#comment;chars')
     end
 
     it 'should not set a comment' do
-      @tuple.last[:indent].should be_nil
-      @tuple.last[:comment].should be_nil
-      @tuple.last[:comment_offset].should be_nil
-      @tuple.last[:comment_sep].should be_nil
+      expect(@tuple.last[:indent]).to be_nil
+      expect(@tuple.last[:comment]).to be_nil
+      expect(@tuple.last[:comment_offset]).to be_nil
+      expect(@tuple.last[:comment_sep]).to be_nil
     end
   end
 
@@ -286,19 +286,19 @@ describe 'Parsing a line' do
     end
 
     it 'should return a section tuple with the correct key' do
-      @tuple.should be_section_tuple('section;with#comment;chars')
+      expect(@tuple).to be_section_tuple('section;with#comment;chars')
     end
 
     it 'should set the comment to "a comment"' do
-      @tuple.should be_section_tuple(:any, :comment => 'a comment')
+      expect(@tuple).to be_section_tuple(:any, :comment => 'a comment')
     end
 
     it 'should set the comment separator to ";"' do
-      @tuple.should be_section_tuple(:any, :comment_sep => ';')
+      expect(@tuple).to be_section_tuple(:any, :comment_sep => ';')
     end
 
     it 'should set the comment offset to 29' do
-      @tuple.should be_section_tuple(:any, :comment_offset => 29)
+      expect(@tuple).to be_section_tuple(:any, :comment_offset => 29)
     end
   end
 
@@ -314,15 +314,15 @@ describe 'Parsing a line' do
     end
 
     it 'should return a comment tuple with the correct comment' do
-      @tuple.should be_comment_tuple('a comment')
+      expect(@tuple).to be_comment_tuple('a comment')
     end
 
     it 'should set the comment separator to ";"' do
-      @tuple.should be_comment_tuple(:any, :comment_sep => ';')
+      expect(@tuple).to be_comment_tuple(:any, :comment_sep => ';')
     end
 
     it 'should set the comment offset to 0' do
-      @tuple.should be_comment_tuple(:any, :comment_offset => 0)
+      expect(@tuple).to be_comment_tuple(:any, :comment_offset => 0)
     end
   end
 
@@ -332,15 +332,15 @@ describe 'Parsing a line' do
     end
 
     it 'should return a comment tuple with the correct comment' do
-      @tuple.should be_comment_tuple('a comment')
+      expect(@tuple).to be_comment_tuple('a comment')
     end
 
     it 'should set the comment separator to ";"' do
-      @tuple.should be_comment_tuple(:any, :comment_sep => ';')
+      expect(@tuple).to be_comment_tuple(:any, :comment_sep => ';')
     end
 
     it 'should set the comment offset to 1' do
-      @tuple.should be_comment_tuple(:any, :comment_offset => 1)
+      expect(@tuple).to be_comment_tuple(:any, :comment_offset => 1)
     end
   end
 
@@ -350,15 +350,15 @@ describe 'Parsing a line' do
     end
 
     it 'should return a comment tuple with an empty value' do
-      @tuple.should be_comment_tuple('')
+      expect(@tuple).to be_comment_tuple('')
     end
 
     it 'should set the comment separator to ";"' do
-      @tuple.should be_comment_tuple(:any, :comment_sep => ';')
+      expect(@tuple).to be_comment_tuple(:any, :comment_sep => ';')
     end
 
     it 'should set the comment offset to 0' do
-      @tuple.should be_comment_tuple(:any, :comment_offset => 0)
+      expect(@tuple).to be_comment_tuple(:any, :comment_offset => 0)
     end
   end
 
@@ -370,13 +370,13 @@ describe 'Parsing a line' do
 
   describe 'with ""' do
     it 'should return a blank tuple' do
-      IniParse::Parser.parse_line('').should be_blank_tuple
+      expect(IniParse::Parser.parse_line('')).to be_blank_tuple
     end
   end
 
   describe 'with " "' do
     it 'should return a blank tuple' do
-      IniParse::Parser.parse_line(' ').should be_blank_tuple
+      expect(IniParse::Parser.parse_line(' ')).to be_blank_tuple
     end
   end
 end
diff --git a/spec/spec_fixtures.rb b/spec/spec_fixtures.rb
index a75120e..57a775b 100644
--- a/spec/spec_fixtures.rb
+++ b/spec/spec_fixtures.rb
@@ -74,3 +74,24 @@ IniParse::Test::Fixtures[:duplicate_section] = <<-FIX.gsub(/^  /, '')
   third = fourth
   another = again
 FIX
+
+IniParse::Test::Fixtures[:dos_endings] =
+  "[database]\r\n" \
+  "first = true\r\n" \
+  "second = false\r\n"
+
+# https://github.com/antw/iniparse/issues/17
+IniParse::Test::Fixtures[:anon_section_with_comments] = <<-FIX.gsub(/^  /, '')
+  #####################
+  # A lot of comments #
+  #####################
+
+  # optiona comment
+  optiona = A
+
+  # optionb comment
+  optionb = B
+
+  # optionc comment
+  optionc = C
+FIX
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 78e812d..891234d 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -26,7 +26,7 @@ module IniParse
           "expected #{@expected} but got #{@target.class}"
         end
 
-        def negative_failure_message
+        def failure_message_when_negated
           "expected #{@expected} to not be #{@target.class}"
         end
 
@@ -68,7 +68,7 @@ module IniParse
           "expected #{@expected_type} tuple #{@failure_message}"
         end
 
-        def negative_failure_message
+        def failure_message_when_negated
           "expected #{@tuple.inspect} to not be #{@expected_type} tuple"
         end
 
diff --git a/spec/spec_helper_spec.rb b/spec/spec_helper_spec.rb
index 178db71..141c5fb 100644
--- a/spec/spec_helper_spec.rb
+++ b/spec/spec_helper_spec.rb
@@ -8,19 +8,19 @@ require 'spec_helper'
 
 describe 'An empty array' do
   it 'should not pass be_section_tuple' do
-    [].should_not be_section_tuple
+    expect([]).not_to be_section_tuple
   end
 
   it 'should not pass be_option_tuple' do
-    [].should_not be_option_tuple
+    expect([]).not_to be_option_tuple
   end
 
   it 'should not pass be_blank_tuple' do
-    [].should_not be_blank_tuple
+    expect([]).not_to be_blank_tuple
   end
 
   it 'should not pass be_comment_tuple' do
-    [].should_not be_comment_tuple
+    expect([]).not_to be_comment_tuple
   end
 end
 
@@ -34,39 +34,39 @@ describe 'Line tuple [:section, "key", {:opt => "val"}]' do
   before(:all) { @tuple = [:section, "key", {:opt => "val"}] }
 
   it 'should pass be_section_tuple' do
-    @tuple.should be_section_tuple
+    expect(@tuple).to be_section_tuple
   end
 
   it 'should pass be_section_tuple("key")' do
-    @tuple.should be_section_tuple("key")
+    expect(@tuple).to be_section_tuple("key")
   end
 
   it 'should fail be_section_tuple("invalid")' do
-    @tuple.should_not be_section_tuple("invalid")
+    expect(@tuple).not_to be_section_tuple("invalid")
   end
 
   it 'should pass be_section_tuple("key", {:opt => "val"})' do
-    @tuple.should be_section_tuple("key", {:opt => "val"})
+    expect(@tuple).to be_section_tuple("key", {:opt => "val"})
   end
 
   it 'should not pass be_section_tuple("key", {:invalid => "val"})' do
-    @tuple.should_not be_section_tuple("key", {:invalid => "val"})
+    expect(@tuple).not_to be_section_tuple("key", {:invalid => "val"})
   end
 
   it 'should not pass be_section_tuple("key", {:opt => "invalid"})' do
-    @tuple.should_not be_section_tuple("key", {:opt => "invalid"})
+    expect(@tuple).not_to be_section_tuple("key", {:opt => "invalid"})
   end
 
   it 'should fail be_option_tuple' do
-    @tuple.should_not be_option_tuple
+    expect(@tuple).not_to be_option_tuple
   end
 
   it 'should fail be_blank_tuple' do
-    @tuple.should_not be_blank_tuple
+    expect(@tuple).not_to be_blank_tuple
   end
 
   it 'should fail be_comment_tuple' do
-    @tuple.should_not be_comment_tuple
+    expect(@tuple).not_to be_comment_tuple
   end
 end
 
@@ -80,51 +80,51 @@ describe 'Line tuple [:option, "key", "val", {:opt => "val"}]' do
   before(:all) { @tuple = [:option, "key", "val", {:opt => "val"}] }
 
   it 'should fail be_section_tuple' do
-    @tuple.should_not be_section_tuple
+    expect(@tuple).not_to be_section_tuple
   end
 
   it 'should pass be_option_tuple' do
-    @tuple.should be_option_tuple
+    expect(@tuple).to be_option_tuple
   end
 
   it 'should pass be_option_tuple("key")' do
-    @tuple.should be_option_tuple("key")
+    expect(@tuple).to be_option_tuple("key")
   end
 
   it 'should fail be_option_tuple("invalid")' do
-    @tuple.should_not be_option_tuple("invalid")
+    expect(@tuple).not_to be_option_tuple("invalid")
   end
 
   it 'should pass be_option_tuple("key", "val")' do
-    @tuple.should be_option_tuple("key", "val")
+    expect(@tuple).to be_option_tuple("key", "val")
   end
 
   it 'should pass be_option_tuple(:any, "val")' do
-    @tuple.should be_option_tuple(:any, "val")
+    expect(@tuple).to be_option_tuple(:any, "val")
   end
 
   it 'should fail be_option_tuple("key", "invalid")' do
-    @tuple.should_not be_option_tuple("key", "invalid")
+    expect(@tuple).not_to be_option_tuple("key", "invalid")
   end
 
   it 'should pass be_option_tuple("key", "val", { :opt => "val" })' do
-    @tuple.should be_option_tuple("key", "val", { :opt => "val" })
+    expect(@tuple).to be_option_tuple("key", "val", { :opt => "val" })
   end
 
   it 'should fail be_option_tuple("key", "val", { :invalid => "val" })' do
-    @tuple.should_not be_option_tuple("key", "val", { :invalid => "val" })
+    expect(@tuple).not_to be_option_tuple("key", "val", { :invalid => "val" })
   end
 
   it 'should fail be_option_tuple("key", "val", { :opt => "invalid" })' do
-    @tuple.should_not be_option_tuple("key", "val", { :opt => "invalid" })
+    expect(@tuple).not_to be_option_tuple("key", "val", { :opt => "invalid" })
   end
 
   it 'should fail be_blank_tuple' do
-    @tuple.should_not be_blank_tuple
+    expect(@tuple).not_to be_blank_tuple
   end
 
   it 'should fail be_comment_tuple' do
-    @tuple.should_not be_comment_tuple
+    expect(@tuple).not_to be_comment_tuple
   end
 end
 
@@ -138,19 +138,19 @@ describe 'Line tuple [:blank]' do
   before(:all) { @tuple = [:blank] }
 
   it 'should fail be_section_tuple' do
-    @tuple.should_not be_section_tuple
+    expect(@tuple).not_to be_section_tuple
   end
 
   it 'should fail be_option_tuple' do
-    @tuple.should_not be_option_tuple
+    expect(@tuple).not_to be_option_tuple
   end
 
   it 'should pass be_blank_tuple' do
-    @tuple.should be_blank_tuple
+    expect(@tuple).to be_blank_tuple
   end
 
   it 'should fail be_comment_tuple' do
-    @tuple.should_not be_comment_tuple
+    expect(@tuple).not_to be_comment_tuple
   end
 end
 
@@ -164,38 +164,38 @@ describe 'Line tuple [:comment, "A comment", {:opt => "val"}]' do
   before(:all) { @tuple = [:comment, "A comment", {:opt => "val"}] }
 
   it 'should fail be_section_tuple' do
-    @tuple.should_not be_section_tuple
+    expect(@tuple).not_to be_section_tuple
   end
 
   it 'should fail be_option_tuple' do
-    @tuple.should_not be_option_tuple
+    expect(@tuple).not_to be_option_tuple
   end
 
   it 'should fail be_blank_tuple' do
-    @tuple.should_not be_blank_tuple
+    expect(@tuple).not_to be_blank_tuple
   end
 
   it 'should pass be_comment_tuple' do
-    @tuple.should be_comment_tuple
+    expect(@tuple).to be_comment_tuple
   end
 
   it 'should pass be_comment_tuple("A comment")' do
-    @tuple.should be_comment_tuple("A comment")
+    expect(@tuple).to be_comment_tuple("A comment")
   end
 
   it 'should fail be_comment_tuple("Invalid")' do
-    @tuple.should_not be_comment_tuple("Invalid")
+    expect(@tuple).not_to be_comment_tuple("Invalid")
   end
 
   it 'should pass be_comment_tuple("A comment", {:opt => "val"})' do
-    @tuple.should be_comment_tuple("A comment", {:opt => "val"})
+    expect(@tuple).to be_comment_tuple("A comment", {:opt => "val"})
   end
 
   it 'should fail be_comment_tuple("A comment", {:invalid => "val"})' do
-    @tuple.should_not be_comment_tuple("A comment", {:invalid => "val"})
+    expect(@tuple).not_to be_comment_tuple("A comment", {:invalid => "val"})
   end
 
   it 'should fail be_comment_tuple("A comment", {:opt => "invalid"})' do
-    @tuple.should_not be_comment_tuple("A comment", {:opt => "invalid"})
+    expect(@tuple).not_to be_comment_tuple("A comment", {:opt => "invalid"})
   end
 end