[DRE-commits] [ruby-nokogiri] 01/07: New upstream version 1.8.0

Lucas Nussbaum lucas at moszumanska.debian.org
Thu Jul 6 20:28:53 UTC 2017


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

lucas pushed a commit to branch master
in repository ruby-nokogiri.

commit 3e366282b71274af11753121e49f57beb0bbd270
Author: Lucas Nussbaum <lucas at debian.org>
Date:   Thu Jul 6 19:54:59 2017 +0200

    New upstream version 1.8.0
---
 .autotest                                          |    6 +-
 .cross_rubies                                      |   11 +-
 .travis.yml                                        |   76 +-
 CHANGELOG.rdoc => CHANGELOG.md                     |  272 +++-
 Gemfile                                            |   19 +-
 Gemfile-libxml-ruby                                |    3 +
 LICENSE-DEPENDENCIES.md                            | 1612 ++++++++++++++++++++
 LICENSE.txt => LICENSE.md                          |    2 +-
 Manifest.txt                                       |   20 +-
 README.md                                          |   21 +-
 Rakefile                                           |   52 +-
 Y_U_NO_GEMSPEC.md                                  |    2 +-
 appveyor.yml                                       |    2 +
 build_all                                          |    1 -
 dependencies.yml                                   |   21 +-
 ext/nokogiri/extconf.rb                            |   58 +-
 ext/nokogiri/nokogiri.c                            |    4 -
 ext/nokogiri/nokogiri.h                            |   10 -
 ext/nokogiri/xml_attr.c                            |   20 +-
 ext/nokogiri/xml_node.c                            |   31 +-
 ext/nokogiri/xml_sax_push_parser.c                 |   68 +-
 lib/nokogiri.rb                                    |    2 +-
 lib/nokogiri/html/document.rb                      |    2 +-
 lib/nokogiri/html/sax/parser.rb                    |   10 +
 lib/nokogiri/version.rb                            |    9 +-
 lib/nokogiri/xml.rb                                |    2 +-
 lib/nokogiri/xml/document.rb                       |   20 +-
 lib/nokogiri/xml/node.rb                           |   18 +-
 lib/nokogiri/xml/node_set.rb                       |   30 +-
 lib/nokogiri/xml/parse_options.rb                  |    6 +-
 lib/nokogiri/xml/sax/parser.rb                     |   13 +-
 lib/nokogiri/xml/searchable.rb                     |   59 +-
 lib/nokogiri/xml/syntax_error.rb                   |   25 +-
 nokogiri.gemspec                                   |   49 +-
 ...arison-with-root-node-in-xmlXPathCmpNodes.patch |   34 +
 ...ix-XPointer-paths-beginning-with-range-to.patch |  174 +++
 ...sallow-namespace-nodes-in-XPointer-ranges.patch |  249 +++
 ...ap-overread-in-xsltFormatNumberConversion.patch |   31 +
 ...for-integer-overflow-in-xsltAddTextString.patch |   74 +
 ports/archives/libxml2-2.9.4.tar.gz                |  Bin 0 -> 5374830 bytes
 ports/archives/libxslt-1.1.29.tar.gz               |  Bin 0 -> 3428524 bytes
 suppressions/nokogiri_ree-1.8.7.358.supp           |   61 -
 suppressions/nokogiri_ruby-1.8.7.370.supp          |    0
 suppressions/nokogiri_ruby-1.9.2.320.supp          |   28 -
 suppressions/nokogiri_ruby-1.9.3.327.supp          |   28 -
 test/decorators/test_slop.rb                       |    5 +-
 test/helper.rb                                     |   10 +
 test/html/sax/test_parser.rb                       |   27 +
 test/html/test_document.rb                         |   13 +-
 test/html/test_document_encoding.rb                |    4 +-
 test/html/test_document_fragment.rb                |    3 +
 test/xml/sax/test_push_parser.rb                   |   48 +
 test/xml/test_attr.rb                              |    7 +
 test/xml/test_document.rb                          |    2 +-
 test/xml/test_document_fragment.rb                 |   27 +
 test/xml/test_entity_reference.rb                  |    4 +-
 test/xml/test_node.rb                              |   30 +-
 test/xml/test_node_reparenting.rb                  |   14 +
 test/xml/test_node_set.rb                          |   14 +-
 test/xml/test_reader.rb                            |   19 +
 test/xml/test_syntax_error.rb                      |   36 +-
 test/xml/test_unparented_node.rb                   |   65 +-
 test/xml/test_xpath.rb                             |   31 +-
 test_all                                           |  107 --
 64 files changed, 3039 insertions(+), 662 deletions(-)

diff --git a/.autotest b/.autotest
index 9d7c26b..878238a 100644
--- a/.autotest
+++ b/.autotest
@@ -12,11 +12,7 @@ end
 
 Autotest.add_hook :run_command do |at|
   at.unit_diff = 'cat'
-  if ENV['ONENINE']
-    system "rake1.9 compile"
-  else
-    system "rake compile"
-  end
+  system "rake compile"
 end
 
 Autotest.add_hook :ran_command do |at|
diff --git a/.cross_rubies b/.cross_rubies
index 8e67ddb..027b97e 100644
--- a/.cross_rubies
+++ b/.cross_rubies
@@ -1,9 +1,6 @@
-1.9.3-p551:i586-mingw32msvc
-2.0.0-p645:i686-w64-mingw32
-2.0.0-p645:x86_64-w64-mingw32
-2.1.6:i686-w64-mingw32
-2.1.6:x86_64-w64-mingw32
-2.2.2:i686-w64-mingw32
-2.2.2:x86_64-w64-mingw32
+2.4.0:i686-w64-mingw32
+2.4.0:x86_64-w64-mingw32
 2.3.0:i686-w64-mingw32
 2.3.0:x86_64-w64-mingw32
+2.2.2:i686-w64-mingw32
+2.2.2:x86_64-w64-mingw32
diff --git a/.travis.yml b/.travis.yml
index 5fd5e51..625d00b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,44 +1,51 @@
 language: ruby
-
-sudo: false
-
-rvm:
-- ruby-1.9.2
-- 1.9.3
-- 2.0
-- 2.1
-- 2.2.3
-- 2.3.0
-- jruby-19mode
-- jruby
-- jruby-9.0.4.0
-- jruby-head
-- rbx-19mode
-- rbx-2
-
-os:
-- linux
-- osx
+dist: trusty
+group: beta
+sudo: required
 
 matrix:
-  allow_failures:
-  # https://github.com/travis-ci/travis-ci/issues/5361
+  include:
+  - os: linux
+    rvm: 2.0
   - os: osx
-    rvm: 2.3.0
-  - rvm: jruby-head
-  exclude:
+    rvm: 2.0
+  - os: linux
+    rvm: 2.1
   - os: osx
-    rvm: ruby-1.9.2
+    rvm: 2.1
+  - os: linux
+    rvm: 2.2.5
   - os: osx
-    rvm: jruby-19mode
+    rvm: 2.2.5
+  - os: linux
+    rvm: 2.3.1
   - os: osx
-    rvm: jruby
+    rvm: 2.3.1
+  - os: linux
+    rvm: 2.4.0
+    env:
+      - RUBYOPT="--enable-frozen-string-literal --debug=frozen-string-literal"
   - os: osx
-    rvm: jruby-9.0.4.0
+    rvm: 2.4.0
+    env:
+      - RUBYOPT="--enable-frozen-string-literal --debug=frozen-string-literal"
+  - os: linux
+    rvm: ruby-head
+    env:
+      - RUBYOPT="--enable-frozen-string-literal --debug=frozen-string-literal"
   - os: osx
-    rvm: rbx-19mode
-  - os: osx
-    rvm: rbx-2
+    rvm: ruby-head
+    env:
+      - RUBYOPT="--enable-frozen-string-literal --debug=frozen-string-literal"
+  - os: linux
+    rvm: jruby-1.7
+  - os: linux
+    rvm: jruby-9.1.5.0
+  - os: linux
+    rvm: rbx-3
+  allow_failures:
+  - rvm: ruby-head
+  fast_finish: true
 
 notifications:
   irc:
@@ -49,3 +56,8 @@ notifications:
     template:
       - "%{repository} (%{branch}:%{commit} by %{author}): %{message} (%{build_url})"
     skip_join: true
+
+addons:
+  apt:
+    packages:
+    - haveged
diff --git a/CHANGELOG.rdoc b/CHANGELOG.md
similarity index 87%
rename from CHANGELOG.rdoc
rename to CHANGELOG.md
index a5db2e8..8047749 100644
--- a/CHANGELOG.rdoc
+++ b/CHANGELOG.md
@@ -1,6 +1,110 @@
-=== 1.6.8.1 / 2016-10-03
+# 1.8.0 / 2017-06-04
 
-==== Dependency License Notes
+## Backwards incompatibilities
+
+This release ends support for Ruby 2.1 on Windows in the `x86-mingw32` and `x64-mingw32` platform gems (containing pre-compiled DLLs). Official support ended for Ruby 2.1 on 2017-04-01.
+
+Please note that this deprecation note only applies to the precompiled Windows gems. Ruby 2.1 continues to be supported (for now) in the default gem when compiled on installation.
+
+
+## Dependencies
+
+* [Windows] Upgrade iconv from 1.14 to 1.15 (unless --use-system-libraries)
+* [Windows] Upgrade zlib from 1.2.8 to 1.2.11 (unless --use-system-libraries)
+* [MRI] Upgrade rake-compiler dependency from 0.9.2 to 1.0.3
+* [MRI] Upgrade mini-portile2 dependency from `~> 2.1.0` to `~> 2.2.0`
+
+
+## Compatibility notes
+
+* [JRuby] Removed support for `jruby --1.8` code paths. [#1607] (Thanks, @kares!)
+* [MRI Windows] Retrieve zlib source from http://zlib.net/fossils to avoid deprecation issues going forward. See #1632 for details around this problem.
+
+
+## Features
+
+* NodeSet#clone is not an alias for NodeSet#dup [#1503] (Thanks, @stephankaag!)
+* Allow Processing Instructions and Comments as children of a document root. [#1033] (Thanks, @windwiny!)
+* [MRI] PushParser#replace_entities and #replace_entities= will control whether entities are replaced or not. [#1017] (Thanks, @spraints!)
+* [MRI] SyntaxError#to_s now includes line number, column number, and log level if made available by the parser. [#1304, #1637] (Thanks, @spk and @ccarruitero!)
+* [MRI] Cross-built Windows gems now support Ruby 2.4
+* [MRI] Support for frozen string literals. [#1413]
+* [MRI] Support for installing Nokogiri on a machine in FIPS-enabled mode [#1544]
+* [MRI] Vendored libraries are verified with SHA-256 hashes (formerly some MD5 hashes were used) [#1544]
+* [JRuby] (performance) remove unnecessary synchronization of class-cache [#1563] (Thanks, @kares!)
+* [JRuby] (performance) remove unnecessary cloning of objects in XPath searches [#1563] (Thanks, @kares!)
+* [JRuby] (performance) more performance improvements, particularly in XPath, Reader, XmlNode, and XmlNodeSet [#1597] (Thanks, @kares!)
+
+
+## Bugs
+
+* HTML::SAX::Parser#parse_io now correctly parses HTML and not XML [#1577] (Thanks for the test case, @gregors!)
+* Support installation on systems with a `lib64` site config. [#1562]
+* [MRI] on OpenBSD, do not require gcc if using system libraries [#1515] (Thanks, @jeremyevans!)
+* [MRI] XML::Attr.new checks type of Document arg to prevent segfaults. [#1477]
+* [MRI] Prefer xmlCharStrdup (and friends) to strdup (and friends), which can cause problems on some platforms. [#1517] (Thanks, @jeremy!)
+* [JRuby] correctly append a text node before another text node [#1318] (Thanks, @jkraemer!)
+* [JRuby] custom xpath functions returning an integer now work correctly [#1595] (Thanks, @kares!)
+* [JRuby] serializing (`#to_html`, `#to_s`, et al) a document with explicit encoding now works correctly. [#1281, #1440] (Thanks, @kares!)
+* [JRuby] XML::Reader now returns parse errors [#1586] (Thanks, @kares!)
+* [JRuby] Empty NodeSets are now decorated properly. [#1319] (Thanks, @kares!)
+* [JRuby] Merged nodes no longer results in Java exceptions during XPath queries. [#1320] (Thanks, @kares!)
+
+
+# 1.7.2 / 2017-05-09
+
+## Security Notes
+
+[MRI] Upstream libxslt patches are applied to the vendored libxslt 1.1.29 which address CVE-2017-5029 and CVE-2016-4738.
+
+For more information:
+
+* https://github.com/sparklemotion/nokogiri/issues/1634
+* http://people.canonical.com/~ubuntu-security/cve/2017/CVE-2017-5029.html
+* http://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-4738.html
+
+
+# 1.7.1 / 2017-03-19
+
+## Security Notes
+
+[MRI] Upstream libxml2 patches are applied to the vendored libxml 2.9.4 which address CVE-2016-4658 and CVE-2016-5131.
+
+For more information:
+
+* https://github.com/sparklemotion/nokogiri/issues/1615
+* http://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-4658.html
+* http://people.canonical.com/~ubuntu-security/cve/2016/CVE-2016-5131.html
+
+
+# 1.7.0.1 / 2017-01-04
+
+## Bugs
+
+* Fix OpenBSD support. (#1569) (related to #1543)
+
+
+# 1.7.0 / 2016-12-26
+
+## Features
+
+* Remove deprecation warnings in Ruby 2.4.0 (#1545) (Thanks, @matthewd!)
+* Support egcc compiler on OpenBSD (#1543) (Thanks, @frenkel and @knu!)
+
+
+## Backwards incompatibilities.
+
+This release ends support for:
+
+* Ruby 1.9.2, for which official support ended on 2014-07-31
+* Ruby 1.9.3, for which official support ended on 2015-02-23
+* Ruby 2.0.0, for which official support ended on 2016-02-24
+* MacRuby, which hasn't been actively supported since 2015-01-13 (see https://github.com/MacRuby/MacRuby/commit/f76b9d6e99c18236db617e8aceb12c27d593a483)
+
+
+# 1.6.8.1 / 2016-10-03
+
+## Dependency License Notes
 
 Removes required dependency on the `pkg-config` gem. This dependency
 was introduced in v1.6.8 and, because it's distributed under LGPL, was
@@ -11,9 +115,9 @@ installed, it's used; but otherwise Nokogiri will attempt to work
 around its absence.
 
 
-=== 1.6.8 / 2016-06-06
+# 1.6.8 / 2016-06-06
 
-==== Security Notes
+## Security Notes
 
 [MRI] Bundled libxml2 is upgraded to 2.9.4, which fixes many security issues. Many of these had previously been patched in the vendored libxml 2.9.2 in the 1.6.7.x branch, but some are newer.
 
@@ -34,7 +138,7 @@ See this libxslt email post for more:
 * https://mail.gnome.org/archives/xslt/2016-May/msg00004.html
 
 
-==== Features
+## Features
 
 Several changes were made to improve performance:
 
@@ -46,7 +150,7 @@ Several changes were made to improve performance:
 * Set document encoding appropriately even on blank document. (#1043) (Thanks, @batter!)
 
 
-==== Bug Fixes
+## Bug Fixes
 
 * [JRuby] fix slow add_child (#692)
 * [JRuby] fix load errors when deploying to JRuby/Torquebox (#1114) (Thanks, @atambo and @jvshahid!)
@@ -73,7 +177,7 @@ Several changes were made to improve performance:
 
 
 
-==== Other Notes
+## Other Notes
 
 * Removed legacy code remaining from Ruby 1.8.x support.
 * Removed legacy code remaining from REE support.
@@ -81,7 +185,7 @@ Several changes were made to improve performance:
 * Handling C strings in a forward-compatible manner, see https://github.com/ruby/ruby/blob/v2_2_0/NEWS#L319
 
 
-=== 1.6.7.2 / 2016-01-20
+# 1.6.7.2 / 2016-01-20
 
 This version pulls in several upstream patches to the vendored libxml2 and libxslt to address:
 
@@ -92,7 +196,7 @@ Ubuntu classifies this as "Priority: Low", RedHat classifies this as "Impact: Mo
 MITRE record is https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-7499
 
 
-=== 1.6.7.1 / 2015-12-16
+# 1.6.7.1 / 2015-12-16
 
 This version pulls in several upstream patches to the vendored libxml2 and libxslt to address:
 
@@ -108,9 +212,9 @@ This version pulls in several upstream patches to the vendored libxml2 and libxs
 See also http://www.ubuntu.com/usn/usn-2834-1/
 
 
-=== 1.6.7 / 2015-11-29
+# 1.6.7 / 2015-11-29
 
-==== Notes
+## Notes
 
 This version supports native builds on Windows using the RubyInstaller
 DevKit. It also supports Ruby 2.2.x on Windows, as well as making
@@ -121,7 +225,7 @@ This version also includes the security patches already applied in
 v1.6.6.3 and v1.6.6.4 to the vendored libxml2 and libxslt source.
 See #1374 and #1376 for details.
 
-==== Features
+## Features
 
 * Cross-built gems now have a proper ruby version requirement. (#1266)
 * Ruby 2.2.x is supported on Windows.
@@ -130,7 +234,7 @@ See #1374 and #1376 for details.
 * [JRuby] fix error in validating files with jruby (#1355, #1361) (Thanks, @twalpole!)
 * [MRI, OSX] Patch to handle nonstandard location of `iconv.h`. (#1206, #1210, #1218, #1345) (Thanks, @neonichu!)
 
-==== Bug Fixes
+## Bug Fixes
 
 * [JRuby] reset the namespace cache when replacing the document's innerHtml (#1265) (Thanks, @mkristian!)
 * [JRuby] Document#parse should support IO objects that respond to #read. (#1124) (Thanks, Jake Byman!)
@@ -139,7 +243,7 @@ See #1374 and #1376 for details.
 * [JRuby] Namespaced attributes aren't removed by remove_attribute. (#1299)
 
 
-=== 1.6.6.4 / 2015-11-19
+# 1.6.6.4 / 2015-11-19
 
 This version pulls in an upstream patch to the vendored libxml2 to address:
 
@@ -148,7 +252,7 @@ This version pulls in an upstream patch to the vendored libxml2 to address:
 This issue was assigned CVE-2015-8710 after the fact. See http://seclists.org/oss-sec/2015/q4/616 for details.
 
 
-=== 1.6.6.3 / 2015-11-16
+# 1.6.6.3 / 2015-11-16
 
 This version pulls in several upstream patches to the vendored libxml2 and libxslt to address:
 
@@ -163,19 +267,19 @@ This version pulls in several upstream patches to the vendored libxml2 and libxs
 See #1374 for details.
 
 
-=== 1.6.6.2 / 2015-01-23
+# 1.6.6.2 / 2015-01-23
 
-==== Bug fixes
+## Bug fixes
 
 * Fixed installation issue affecting compiler arguments. (#1230)
 
 
-=== 1.6.6.1 / 2015-01-22
+# 1.6.6.1 / 2015-01-22
 
 Note that 1.6.6.0 was not released.
 
 
-==== Features
+## Features
 
 * Unified Node and NodeSet implementations of #search, #xpath and #css.
 * Added Node#lang and Node#lang=.
@@ -186,7 +290,7 @@ Note that 1.6.6.0 was not released.
 * JRuby 9K support.
 
 
-==== Bug fixes
+## Bug fixes
 
 * DocumentFragment#search now matches against root nodes. (#1205)
 * (MRI) More fixes related to handling libxml2 parse errors during DocumentFragment#dup. (#1196)
@@ -198,31 +302,31 @@ Note that 1.6.6.0 was not released.
 * (JRuby) HtmlSaxPushParser now exists. (#1147) (Thanks, Piotr Szmielew!)
 
 
-=== 1.6.5 / 2014-11-26
+# 1.6.5 / 2014-11-26
 
-==== Features
+## Features
 
 * Implement Slop#respond_to_missing?. (#1176)
 * Optimized the XPath query generated by an `an+b` CSS query.
 
 
-==== Bug fixes
+## Bug fixes
 
 * Capture non-parse errors from Document#dup in Document#errors. (#1196)
 * (JRuby) Document#canonicalize parameters are now consistent with MRI. (#1189)
 
 
-=== 1.6.4.1 / 2014-11-05
+# 1.6.4.1 / 2014-11-05
 
-==== Bug fixes
+## Bug fixes
 
 * (MRI) Fix a bug where CFLAGS passed in are dropped. (#1188)
 * Fix a bug where CSS selector :nth(n) did not work. (#1187)
 
 
-=== 1.6.4 / 2014-11-04
+# 1.6.4 / 2014-11-04
 
-==== Features
+## Features
 
 * (MRI) Bundled Libxml2 is upgraded to 2.9.2.
 * (MRI) `nokogiri --version` will include a list of applied patches.
@@ -230,27 +334,27 @@ Note that 1.6.6.0 was not released.
 * (MRI) Detect and help user fix a missing /usr/include/iconv.h on OS X. (#1111)
 * (MRI) Improve the iconv detection for building libxml2.
 
-==== Bug fixes
+## Bug fixes
 
 * (MRI) Fix DocumentFragment#element_children (#1138).
 * Fix a bug with CSS attribute selector without any prefix where "foo [bar]" was treated as "foo[bar]". (#1174)
 
 
-=== 1.6.3.1 / 2014-07-21
+# 1.6.3.1 / 2014-07-21
 
-==== Bug fixes
+## Bug fixes
 
 * Addressing an Apple Macintosh installation problem for GCC users. #1130 (Thanks, @zenspider!)
 
 
-=== 1.6.3 / 2014-07-20
+# 1.6.3 / 2014-07-20
 
-==== Features
+## Features
 
 * Added Node#document? and Node#processing_instruction?
 
 
-==== Bug fixes
+## Bug fixes
 
 * [JRuby] Fix Ruby memory exhaustion vulnerability. #1087 (Thanks, @ocher)
 * [MRI] Fix segfault during GC when using `libxml-ruby` and `nokogiri` together in multi-threaded environment. #895 (Thanks, @ender672!)
@@ -259,18 +363,18 @@ Note that 1.6.6.0 was not released.
 * Processing instructions can now be added via Node#add_next_sibling.
 
 
-=== 1.6.2.1 / 2014-05-13
+# 1.6.2.1 / 2014-05-13
 
-==== Bug fixes
+## Bug fixes
 
 * Fix statically-linked libxml2 installation when using universal builds of Ruby. #1104
 * Patching `mini_portile` to address the git dependency detailed in #1102.
 * Library load fix to address segfault reported on some systems. #1097
 
 
-=== 1.6.2 / 2014-05-12
+# 1.6.2 / 2014-05-12
 
-==== Security Note
+## Security Note
 
 A set of security and bugfix patches have been backported from the libxml2 and libxslt repositories onto the version of 2.8.0 packaged with Nokogiri, including these notable security fixes:
 
@@ -280,11 +384,11 @@ A set of security and bugfix patches have been backported from the libxml2 and l
 
 It is recommended that you upgrade from 1.6.x to this version as soon as possible.
 
-==== Compatibility Note
+## Compatibility Note
 
 Now requires libxml >= 2.6.21 (was previously >= 2.6.17).
 
-==== Features
+## Features
 
 * Add cross building of fat binary gems for 64-Bit Windows (x64-mingw32) and add support for native builds on Windows. #864, #989, #1072
 * (MRI) Alias CP932 to Windows-31J if iconv does not support Windows-31J.
@@ -303,7 +407,7 @@ Now requires libxml >= 2.6.21 (was previously >= 2.6.17).
 * Fix documentation for XML::Node#namespace. #803 #802 (Thanks, Hoylen Sue)
 * Allow Nokogiri::XML::Node#parse from unparented non-element nodes. #407
 
-==== Bugfixes
+## Bugfixes
 
 * Ensure :only-child pseudo class works within :not pseudo class. #858 (Thanks, Yamagishi Kazutoshi!)
 * Don't call pkg_config when using bundled libraries in extconf.rb #931 (Thanks, Shota Fukumori!)
@@ -323,7 +427,7 @@ Now requires libxml >= 2.6.21 (was previously >= 2.6.17).
 * (JRuby) JRuby-Nokogiri has different comment node name #1080
 * (JRuby) JAXPExtensionsProvider / Java 7 / Secure Processing #1070
 
-=== 1.6.1 / 2013-12-14
+# 1.6.1 / 2013-12-14
 
 * Bugfixes
 
@@ -331,7 +435,7 @@ Now requires libxml >= 2.6.21 (was previously >= 2.6.17).
   * (JRuby) Fix regression of billion-laughs vulnerability. #586
 
 
-=== 1.6.0 / 2013-06-08
+# 1.6.0 / 2013-06-08
 
 This release was based on v1.5.10 and 1.6.0.rc1, and contains changes
 mentioned in both.
@@ -341,7 +445,7 @@ mentioned in both.
   * Remove pre 1.9 monitoring from Travis.
 
 
-=== 1.6.0.rc1 / 2013-04-14
+# 1.6.0.rc1 / 2013-04-14
 
 This release was based on v1.5.9, and so does not contain any fixes
 mentioned in the notes for v1.5.10.
@@ -367,7 +471,7 @@ mentioned in the notes for v1.5.10.
   * Support for Ruby 1.8.7 and prior has been dropped
 
 
-=== 1.5.11 / 2013-12-14
+# 1.5.11 / 2013-12-14
 
 * Bugfixes
 
@@ -375,7 +479,7 @@ mentioned in the notes for v1.5.10.
   * (JRuby) Fix regression of billion-laughs vulnerability. #586
 
 
-=== 1.5.10 / 2013-06-07
+# 1.5.10 / 2013-06-07
 
 * Bugfixes
 
@@ -390,7 +494,7 @@ mentioned in the notes for v1.5.10.
   * Fix TypeError when running tests. #900 (Thanks, Cédric Boutillier!)
 
 
-=== 1.5.9 / 2013-03-21
+# 1.5.9 / 2013-03-21
 
 * Bugfixes
 
@@ -399,7 +503,7 @@ mentioned in the notes for v1.5.10.
   * (MRI) Fixed a memory leak in fragment parsing if nodes are not all subsequently reparented. #856
 
 
-=== 1.5.8 / 2013-03-19
+# 1.5.8 / 2013-03-19
 
 * Bugfixes
 
@@ -408,7 +512,7 @@ mentioned in the notes for v1.5.10.
   * Allow use of a prefixed namespace on a root node using Nokogiri::XML::Builder #868
 
 
-=== 1.5.7 / 2013-03-18
+# 1.5.7 / 2013-03-18
 
 * Features
 
@@ -431,7 +535,7 @@ mentioned in the notes for v1.5.10.
   * (MRI) SAX parser handles empty processing instructions. #845
 
 
-=== 1.5.6 / 2012-12-19
+# 1.5.6 / 2012-12-19
 
 * Features
 
@@ -470,7 +574,7 @@ mentioned in the notes for v1.5.10.
   * (JRuby) builder requires textwrappers for valid utf8 in jruby, not in mri. #784
 
 
-=== 1.5.5 / 2012-06-24
+# 1.5.5 / 2012-06-24
 
 * Features
 
@@ -492,7 +596,7 @@ mentioned in the notes for v1.5.10.
   * JRuby's Entity resolving should be consistent with C-Nokogiri #704, #647, #703
 
 
-=== 1.5.4 / 2012-06-12
+# 1.5.4 / 2012-06-12
 
 * Features
 
@@ -518,7 +622,7 @@ mentioned in the notes for v1.5.10.
     Insert your own joke about double-negatives here.
 
 
-=== 1.5.3 / 2012-06-01
+# 1.5.3 / 2012-06-01
 
 * Features
 
@@ -548,12 +652,12 @@ mentioned in the notes for v1.5.10.
   * (JRuby) Concurrency issue in XPath parsing. #682
 
 
-=== 1.5.2 / 2012-03-09
+# 1.5.2 / 2012-03-09
 
 Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631, #632.
 
 
-=== 1.5.1 / 2012-03-09
+# 1.5.1 / 2012-03-09
 
 * Features
 
@@ -598,7 +702,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * C14n cleanup and Node#canonicalize (thanks, Ivan Pirlik!) #563
 
 
-=== 1.5.0 / 2011-07-01
+# 1.5.0 / 2011-07-01
 
 * Notes
 
@@ -619,7 +723,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Add support for <meta charset="...">.
 
 
-=== 1.5.0 beta3 / 2010/12/02
+# 1.5.0 beta3 / 2010/12/02
 
 * Notes
 
@@ -631,14 +735,14 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Node#inner_text no longer returns nil. (JRuby) #264
 
 
-=== 1.5.0 beta2 / 2010/07/30
+# 1.5.0 beta2 / 2010/07/30
 
 * Notes
 
   * See changelog from 1.4.3
 
 
-=== 1.5.0 beta1 / 2010/05/22
+# 1.5.0 beta1 / 2010/05/22
 
 * Notes
 
@@ -651,7 +755,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * FFI support is removed.
 
 
-=== 1.4.7 / 2011-07-01
+# 1.4.7 / 2011-07-01
 
 * Bugfixes
 
@@ -660,7 +764,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
     encoding. Thanks, Timothy Elliott (@ender672)! #478
 
 
-=== 1.4.6 / 2011-06-19
+# 1.4.6 / 2011-06-19
 
 * Notes
 
@@ -668,7 +772,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Ruby 1.8.6 support has been restored.
 
 
-=== 1.4.5 / 2011-05-19
+# 1.4.5 / 2011-05-19
 
 * New Features
 
@@ -691,7 +795,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * XML::Reader no longer segfaults when under GC pressure. #439
 
 
-=== 1.4.4 / 2010-11-15
+# 1.4.4 / 2010-11-15
 
 * New Features
 
@@ -718,7 +822,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Fixed NodeSet#wrap on nodes within a fragment. #331
 
 
-=== 1.4.3 / 2010/07/28
+# 1.4.3 / 2010/07/28
 
 * New Features
 
@@ -742,7 +846,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
     "//F//G[preceding-sibling::E]".
 
 
-=== 1.4.2 / 2010/05/22
+# 1.4.2 / 2010/05/22
 
 * New Features
 
@@ -795,7 +899,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
     were bundled.
 
 
-=== 1.4.1 / 2009/12/10
+# 1.4.1 / 2009/12/10
 
 * New Features
 
@@ -827,7 +931,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Fragments containing leading text nodes with newlines now parse properly. GH #178.
 
 
-=== 1.4.0 / 2009/10/30
+# 1.4.0 / 2009/10/30
 
 * Happy Birthday!
 
@@ -870,7 +974,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Hpricot compatibility layer removed
 
 
-=== 1.3.3 / 2009/07/26
+# 1.3.3 / 2009/07/26
 
 * New Features
 
@@ -891,7 +995,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Hpricot compatibility layer will be removed in 1.4.0
 
 
-=== 1.3.2 / 2009-06-22
+# 1.3.2 / 2009-06-22
 
 * New Features
 
@@ -915,7 +1019,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
     to Nokogiri::XML::SAX::Document#end_element_namespace
 
 
-=== 1.3.1 / 2009-06-07
+# 1.3.1 / 2009-06-07
 
 * Bugfixes
 
@@ -923,7 +1027,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Namespace nodes are added to the Document node cache
 
 
-=== 1.3.0 / 2009-05-30
+# 1.3.0 / 2009-05-30
 
 * New Features
 
@@ -967,7 +1071,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Fixed intolerance of HTML attributes without values in Node#before/after/inner_html=. (GH#35)
 
 
-=== 1.2.3 / 2009-03-22
+# 1.2.3 / 2009-03-22
 
 * Bugfixes
 
@@ -979,7 +1083,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Builder methods take a hash as a second argument
 
 
-=== 1.2.2 / 2009-03-14
+# 1.2.2 / 2009-03-14
 
 * New features
 
@@ -1006,7 +1110,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Document should not have a parent method (LH #64)
 
 
-=== 1.2.1 / 2009-02-23
+# 1.2.1 / 2009-02-23
 
 * Bugfixes
 
@@ -1014,7 +1118,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Fixed Ruby 1.9 String Encoding (Thanks 角谷さん!)
 
 
-=== 1.2.0 / 2009-02-22
+# 1.2.0 / 2009-02-22
 
 * New features
 
@@ -1051,7 +1155,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Nokogiri::HTML.fragment now returns an XML::DocumentFragment (LH #32)
 
 
-=== 1.1.1
+# 1.1.1
 
 * New features
 
@@ -1069,7 +1173,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * XML::NodeSet implements to_xml
 
 
-=== 1.1.0
+# 1.1.0
 
 * New Features
 
@@ -1086,7 +1190,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * XML::Node#add_previous_sibling returns new sibling node.
 
 
-=== 1.0.7
+# 1.0.7
 
 * Bugfixes
 
@@ -1098,7 +1202,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Fixed a bug in complex CSS negation selectors
 
 
-=== 1.0.6
+# 1.0.6
 
 * 5 Bugfixes
 
@@ -1109,7 +1213,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * CSS to XPath conversion is now cached
 
 
-=== 1.0.5
+# 1.0.5
 
 * Bugfixes
 
@@ -1118,7 +1222,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Caching results of NodeSet#[] on Document
 
 
-=== 1.0.4
+# 1.0.4
 
 * Bugfixes
 
@@ -1127,7 +1231,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * Builder blocks can call methods from surrounding contexts
 
 
-=== 1.0.3
+# 1.0.3
 
 * 5 Bugfixes
 
@@ -1138,14 +1242,14 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
   * inner_html fixed. (Thanks Yehuda!)
 
 
-=== 1.0.2
+# 1.0.2
 
 * 1 Bugfix
 
   * extconf.rb should not check for frex and racc
 
 
-=== 1.0.1
+# 1.0.1
 
 * 1 Bugfix
 
@@ -1153,7 +1257,7 @@ Repackaging of 1.5.1 with a gemspec that is compatible with older Rubies. #631,
     will link properly.  Thanks lucsky!
 
 
-=== 1.0.0 / 2008-07-13
+# 1.0.0 / 2008-07-13
 
 * 1 major enhancement
 
diff --git a/Gemfile b/Gemfile
index a6d98f0..c566340 100644
--- a/Gemfile
+++ b/Gemfile
@@ -4,19 +4,20 @@
 
 source "https://rubygems.org/"
 
-gem "mini_portile2", "~>2.1.0"
+gem "mini_portile2", "~>2.2.0"
 
-gem "rdoc", "~>4.0", :group => [:development, :test]
 gem "hoe-bundler", "~>1.2.0", :group => [:development, :test]
-gem "hoe-debugging", "~>1.2.1", :group => [:development, :test]
+gem "hoe-debugging", "~>1.3.0", :group => [:development, :test]
 gem "hoe-gemspec", "~>1.0.0", :group => [:development, :test]
 gem "hoe-git", "~>1.6.0", :group => [:development, :test]
 gem "minitest", "~>5.8.4", :group => [:development, :test]
-gem "rake", "~>10.5.0", :group => [:development, :test]
-gem "rake-compiler", "~>0.9.2", :group => [:development, :test]
-gem "rake-compiler-dock", "~>0.5.1", :group => [:development, :test]
-gem "racc", "~>1.4.14", :group => [:development, :test], :platform => :ruby
-gem "rexical", "~>1.0.5", :group => [:development, :test], :platform => :ruby
-gem "hoe", "~>3.14", :group => [:development, :test]
+gem "rake", "~>12.0", :group => [:development, :test]
+gem "rake-compiler", "~>1.0.3", :group => [:development, :test]
+gem "rake-compiler-dock", "~>0.6.0", :group => [:development, :test]
+gem "racc", "~>1.4.14", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw]
+gem "rexical", "~>1.0.5", :group => [:development, :test], :platform => [:ruby, :mingw, :x64_mingw]
+gem "concourse", "~>0.11", :group => [:development, :test]
+gem "rdoc", "~>4.0", :group => [:development, :test]
+gem "hoe", "~>3.16", :group => [:development, :test]
 
 # vim: syntax=ruby
diff --git a/Gemfile-libxml-ruby b/Gemfile-libxml-ruby
new file mode 100644
index 0000000..6b8190b
--- /dev/null
+++ b/Gemfile-libxml-ruby
@@ -0,0 +1,3 @@
+ENV['TEST_NOKOGIRI_WITH_LIBXML_RUBY'] = "1"
+gem "libxml-ruby", :platform => :mri, :require => false
+eval_gemfile File.join(File.dirname(ENV['BUNDLE_GEMFILE']),"Gemfile")
diff --git a/LICENSE-DEPENDENCIES.md b/LICENSE-DEPENDENCIES.md
new file mode 100644
index 0000000..a20e96a
--- /dev/null
+++ b/LICENSE-DEPENDENCIES.md
@@ -0,0 +1,1612 @@
+Nokogiri ships with some third party dependencies, which are listed
+here along with their licenses.
+
+Note that this document is broken into three sections, each of which
+will apply to different platform releases of Nokogiri:
+
+1. default platform release
+2. `java` platform release
+3. binary windows platform releases (`x86-mingw32` and `x64-mingw32`)
+
+It's encouraged for anyone consuming this file via license-tracking
+software to understand which dependencies are used by your particular
+software, so as not to misinterpret the contents of this file.
+
+In particular, I'm sure somebody's lawyer, somewhere, is going to
+freak out that the LGPL appears in this file; and so I'd like to take
+special note that the dependency covered by LGPL, `libiconv`, is only
+being redistributed in the binary Windows platform release. It's not
+present in any non-Windows releases.
+
+-----
+
+# default platform release
+
+## libxml2
+
+MIT
+
+http://xmlsoft.org/
+
+    Except where otherwise noted in the source code (e.g. the files hash.c,
+    list.c and the trio files, which are covered by a similar licence but
+    with different Copyright notices) all the files are:
+    
+     Copyright (C) 1998-2012 Daniel Veillard.  All Rights Reserved.
+    
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is fur-
+    nished to do so, subject to the following conditions:
+    
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+    NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+    
+
+## libxslt
+
+MIT
+
+http://xmlsoft.org/libxslt/
+
+    Licence for libxslt except libexslt
+    ----------------------------------------------------------------------
+     Copyright (C) 2001-2002 Daniel Veillard.  All Rights Reserved.
+    
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is fur-
+    nished to do so, subject to the following conditions:
+    
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+    NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+    DANIEL VEILLARD BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+    NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+    
+    Except as contained in this notice, the name of Daniel Veillard shall not
+    be used in advertising or otherwise to promote the sale, use or other deal-
+    ings in this Software without prior written authorization from him.
+    
+    ----------------------------------------------------------------------
+    
+    Licence for libexslt
+    ----------------------------------------------------------------------
+     Copyright (C) 2001-2002 Thomas Broyer, Charlie Bozeman and Daniel Veillard.
+     All Rights Reserved.
+    
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is fur-
+    nished to do so, subject to the following conditions:
+    
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FIT-
+    NESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+    AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+    IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CON-
+    NECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+    
+    Except as contained in this notice, the name of the authors shall not
+    be used in advertising or otherwise to promote the sale, use or other deal-
+    ings in this Software without prior written authorization from him.
+    ----------------------------------------------------------------------
+    
+# `java` platform release
+
+## isorelax
+
+MIT
+
+http://iso-relax.sourceforge.net/
+
+    Copyright (c) 2001-2002, SourceForge ISO-RELAX Project (ASAMI
+    Tomoharu, Daisuke Okajima, Kohsuke Kawaguchi, and MURATA Makoto)
+    
+    Permission is hereby granted, free of charge, to any person obtaining
+    a copy of this software and associated documentation files (the
+    "Software"), to deal in the Software without restriction, including
+    without limitation the rights to use, copy, modify, merge, publish,
+    distribute, sublicense, and/or sell copies of the Software, and to
+    permit persons to whom the Software is furnished to do so, subject to
+    the following conditions:
+    
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+    LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+    OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+
+## jing
+
+BSD-3-Clause
+
+http://www.thaiopensource.com/relaxng/jing.html
+
+    Copyright (c) 2001-2003 Thai Open Source Software Center Ltd
+    All rights reserved.
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    
+    * Neither the name of the Thai Open Source Software Center Ltd nor
+      the names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior
+      written permission.
+    
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+    CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+    TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+    THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+    SUCH DAMAGE.
+
+    
+## nekodtd
+
+Apache 1.0-derived
+
+https://people.apache.org/~andyc/neko/doc/dtd/
+
+    The CyberNeko Software License, Version 1.0
+     
+    (C) Copyright 2002-2005, Andy Clark.  All rights reserved.
+     
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions
+    are met:
+    
+    1. Redistributions of source code must retain the above copyright
+       notice, this list of conditions and the following disclaimer. 
+    
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in
+       the documentation and/or other materials provided with the
+       distribution.
+    
+    3. The end-user documentation included with the redistribution,
+       if any, must include the following acknowledgment:  
+         "This product includes software developed by Andy Clark."
+       Alternately, this acknowledgment may appear in the software itself,
+       if and wherever such third-party acknowledgments normally appear.
+    
+    4. The names "CyberNeko" and "NekoHTML" must not be used to endorse
+       or promote products derived from this software without prior 
+       written permission. For written permission, please contact 
+       andyc at cyberneko.net.
+    
+    5. Products derived from this software may not be called "CyberNeko",
+       nor may "CyberNeko" appear in their name, without prior written
+       permission of the author.
+    
+    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+    WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS
+    BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+    OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
+    BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
+    WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 
+    OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+    EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+    
+    ====================================================================
+    
+    This license is based on the Apache Software License, version 1.1.
+
+## nekohtml
+
+Apache 2.0
+
+http://nekohtml.sourceforge.net/
+
+    
+                                     Apache License
+                               Version 2.0, January 2004
+                            http://www.apache.org/licenses/
+    
+       TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+    
+       1. Definitions.
+    
+          "License" shall mean the terms and conditions for use, reproduction,
+          and distribution as defined by Sections 1 through 9 of this document.
+    
+          "Licensor" shall mean the copyright owner or entity authorized by
+          the copyright owner that is granting the License.
+    
+          "Legal Entity" shall mean the union of the acting entity and all
+          other entities that control, are controlled by, or are under common
+          control with that entity. For the purposes of this definition,
+          "control" means (i) the power, direct or indirect, to cause the
+          direction or management of such entity, whether by contract or
+          otherwise, or (ii) ownership of fifty percent (50%) or more of the
+          outstanding shares, or (iii) beneficial ownership of such entity.
+    
+          "You" (or "Your") shall mean an individual or Legal Entity
+          exercising permissions granted by this License.
+    
+          "Source" form shall mean the preferred form for making modifications,
+          including but not limited to software source code, documentation
+          source, and configuration files.
+    
+          "Object" form shall mean any form resulting from mechanical
+          transformation or translation of a Source form, including but
+          not limited to compiled object code, generated documentation,
+          and conversions to other media types.
+    
+          "Work" shall mean the work of authorship, whether in Source or
+          Object form, made available under the License, as indicated by a
+          copyright notice that is included in or attached to the work
+          (an example is provided in the Appendix below).
+    
+          "Derivative Works" shall mean any work, whether in Source or Object
+          form, that is based on (or derived from) the Work and for which the
+          editorial revisions, annotations, elaborations, or other modifications
+          represent, as a whole, an original work of authorship. For the purposes
+          of this License, Derivative Works shall not include works that remain
+          separable from, or merely link (or bind by name) to the interfaces of,
+          the Work and Derivative Works thereof.
+    
+          "Contribution" shall mean any work of authorship, including
+          the original version of the Work and any modifications or additions
+          to that Work or Derivative Works thereof, that is intentionally
+          submitted to Licensor for inclusion in the Work by the copyright owner
+          or by an individual or Legal Entity authorized to submit on behalf of
+          the copyright owner. For the purposes of this definition, "submitted"
+          means any form of electronic, verbal, or written communication sent
+          to the Licensor or its representatives, including but not limited to
+          communication on electronic mailing lists, source code control systems,
+          and issue tracking systems that are managed by, or on behalf of, the
+          Licensor for the purpose of discussing and improving the Work, but
+          excluding communication that is conspicuously marked or otherwise
+          designated in writing by the copyright owner as "Not a Contribution."
+    
+          "Contributor" shall mean Licensor and any individual or Legal Entity
+          on behalf of whom a Contribution has been received by Licensor and
+          subsequently incorporated within the Work.
+    
+       2. Grant of Copyright License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          copyright license to reproduce, prepare Derivative Works of,
+          publicly display, publicly perform, sublicense, and distribute the
+          Work and such Derivative Works in Source or Object form.
+    
+       3. Grant of Patent License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          (except as stated in this section) patent license to make, have made,
+          use, offer to sell, sell, import, and otherwise transfer the Work,
+          where such license applies only to those patent claims licensable
+          by such Contributor that are necessarily infringed by their
+          Contribution(s) alone or by combination of their Contribution(s)
+          with the Work to which such Contribution(s) was submitted. If You
+          institute patent litigation against any entity (including a
+          cross-claim or counterclaim in a lawsuit) alleging that the Work
+          or a Contribution incorporated within the Work constitutes direct
+          or contributory patent infringement, then any patent licenses
+          granted to You under this License for that Work shall terminate
+          as of the date such litigation is filed.
+    
+       4. Redistribution. You may reproduce and distribute copies of the
+          Work or Derivative Works thereof in any medium, with or without
+          modifications, and in Source or Object form, provided that You
+          meet the following conditions:
+    
+          (a) You must give any other recipients of the Work or
+              Derivative Works a copy of this License; and
+    
+          (b) You must cause any modified files to carry prominent notices
+              stating that You changed the files; and
+    
+          (c) You must retain, in the Source form of any Derivative Works
+              that You distribute, all copyright, patent, trademark, and
+              attribution notices from the Source form of the Work,
+              excluding those notices that do not pertain to any part of
+              the Derivative Works; and
+    
+          (d) If the Work includes a "NOTICE" text file as part of its
+              distribution, then any Derivative Works that You distribute must
+              include a readable copy of the attribution notices contained
+              within such NOTICE file, excluding those notices that do not
+              pertain to any part of the Derivative Works, in at least one
+              of the following places: within a NOTICE text file distributed
+              as part of the Derivative Works; within the Source form or
+              documentation, if provided along with the Derivative Works; or,
+              within a display generated by the Derivative Works, if and
+              wherever such third-party notices normally appear. The contents
+              of the NOTICE file are for informational purposes only and
+              do not modify the License. You may add Your own attribution
+              notices within Derivative Works that You distribute, alongside
+              or as an addendum to the NOTICE text from the Work, provided
+              that such additional attribution notices cannot be construed
+              as modifying the License.
+    
+          You may add Your own copyright statement to Your modifications and
+          may provide additional or different license terms and conditions
+          for use, reproduction, or distribution of Your modifications, or
+          for any such Derivative Works as a whole, provided Your use,
+          reproduction, and distribution of the Work otherwise complies with
+          the conditions stated in this License.
+    
+       5. Submission of Contributions. Unless You explicitly state otherwise,
+          any Contribution intentionally submitted for inclusion in the Work
+          by You to the Licensor shall be under the terms and conditions of
+          this License, without any additional terms or conditions.
+          Notwithstanding the above, nothing herein shall supersede or modify
+          the terms of any separate license agreement you may have executed
+          with Licensor regarding such Contributions.
+    
+       6. Trademarks. This License does not grant permission to use the trade
+          names, trademarks, service marks, or product names of the Licensor,
+          except as required for reasonable and customary use in describing the
+          origin of the Work and reproducing the content of the NOTICE file.
+    
+       7. Disclaimer of Warranty. Unless required by applicable law or
+          agreed to in writing, Licensor provides the Work (and each
+          Contributor provides its Contributions) on an "AS IS" BASIS,
+          WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+          implied, including, without limitation, any warranties or conditions
+          of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+          PARTICULAR PURPOSE. You are solely responsible for determining the
+          appropriateness of using or redistributing the Work and assume any
+          risks associated with Your exercise of permissions under this License.
+    
+       8. Limitation of Liability. In no event and under no legal theory,
+          whether in tort (including negligence), contract, or otherwise,
+          unless required by applicable law (such as deliberate and grossly
+          negligent acts) or agreed to in writing, shall any Contributor be
+          liable to You for damages, including any direct, indirect, special,
+          incidental, or consequential damages of any character arising as a
+          result of this License or out of the use or inability to use the
+          Work (including but not limited to damages for loss of goodwill,
+          work stoppage, computer failure or malfunction, or any and all
+          other commercial damages or losses), even if such Contributor
+          has been advised of the possibility of such damages.
+    
+       9. Accepting Warranty or Additional Liability. While redistributing
+          the Work or Derivative Works thereof, You may choose to offer,
+          and charge a fee for, acceptance of support, warranty, indemnity,
+          or other liability obligations and/or rights consistent with this
+          License. However, in accepting such obligations, You may act only
+          on Your own behalf and on Your sole responsibility, not on behalf
+          of any other Contributor, and only if You agree to indemnify,
+          defend, and hold each Contributor harmless for any liability
+          incurred by, or claims asserted against, such Contributor by reason
+          of your accepting any such warranty or additional liability.
+    
+       END OF TERMS AND CONDITIONS
+    
+       APPENDIX: How to apply the Apache License to your work.
+    
+          To apply the Apache License to your work, attach the following
+          boilerplate notice, with the fields enclosed by brackets "[]"
+          replaced with your own identifying information. (Don't include
+          the brackets!)  The text should be enclosed in the appropriate
+          comment syntax for the file format. We also recommend that a
+          file or class name and description of purpose be included on the
+          same "printed page" as the copyright notice for easier
+          identification within third-party archives.
+    
+       Copyright [yyyy] [name of copyright owner]
+    
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+    
+           http://www.apache.org/licenses/LICENSE-2.0
+    
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+
+## xalan
+
+Apache 2.0
+
+https://xml.apache.org/xalan-j/
+
+covers xalan.jar and serializer.jar
+
+                                    Apache License
+                               Version 2.0, January 2004
+                            http://www.apache.org/licenses/
+    
+       TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+    
+       1. Definitions.
+    
+          "License" shall mean the terms and conditions for use, reproduction,
+          and distribution as defined by Sections 1 through 9 of this document.
+    
+          "Licensor" shall mean the copyright owner or entity authorized by
+          the copyright owner that is granting the License.
+    
+          "Legal Entity" shall mean the union of the acting entity and all
+          other entities that control, are controlled by, or are under common
+          control with that entity. For the purposes of this definition,
+          "control" means (i) the power, direct or indirect, to cause the
+          direction or management of such entity, whether by contract or
+          otherwise, or (ii) ownership of fifty percent (50%) or more of the
+          outstanding shares, or (iii) beneficial ownership of such entity.
+    
+          "You" (or "Your") shall mean an individual or Legal Entity
+          exercising permissions granted by this License.
+    
+          "Source" form shall mean the preferred form for making modifications,
+          including but not limited to software source code, documentation
+          source, and configuration files.
+    
+          "Object" form shall mean any form resulting from mechanical
+          transformation or translation of a Source form, including but
+          not limited to compiled object code, generated documentation,
+          and conversions to other media types.
+    
+          "Work" shall mean the work of authorship, whether in Source or
+          Object form, made available under the License, as indicated by a
+          copyright notice that is included in or attached to the work
+          (an example is provided in the Appendix below).
+    
+          "Derivative Works" shall mean any work, whether in Source or Object
+          form, that is based on (or derived from) the Work and for which the
+          editorial revisions, annotations, elaborations, or other modifications
+          represent, as a whole, an original work of authorship. For the purposes
+          of this License, Derivative Works shall not include works that remain
+          separable from, or merely link (or bind by name) to the interfaces of,
+          the Work and Derivative Works thereof.
+    
+          "Contribution" shall mean any work of authorship, including
+          the original version of the Work and any modifications or additions
+          to that Work or Derivative Works thereof, that is intentionally
+          submitted to Licensor for inclusion in the Work by the copyright owner
+          or by an individual or Legal Entity authorized to submit on behalf of
+          the copyright owner. For the purposes of this definition, "submitted"
+          means any form of electronic, verbal, or written communication sent
+          to the Licensor or its representatives, including but not limited to
+          communication on electronic mailing lists, source code control systems,
+          and issue tracking systems that are managed by, or on behalf of, the
+          Licensor for the purpose of discussing and improving the Work, but
+          excluding communication that is conspicuously marked or otherwise
+          designated in writing by the copyright owner as "Not a Contribution."
+    
+          "Contributor" shall mean Licensor and any individual or Legal Entity
+          on behalf of whom a Contribution has been received by Licensor and
+          subsequently incorporated within the Work.
+    
+       2. Grant of Copyright License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          copyright license to reproduce, prepare Derivative Works of,
+          publicly display, publicly perform, sublicense, and distribute the
+          Work and such Derivative Works in Source or Object form.
+    
+       3. Grant of Patent License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          (except as stated in this section) patent license to make, have made,
+          use, offer to sell, sell, import, and otherwise transfer the Work,
+          where such license applies only to those patent claims licensable
+          by such Contributor that are necessarily infringed by their
+          Contribution(s) alone or by combination of their Contribution(s)
+          with the Work to which such Contribution(s) was submitted. If You
+          institute patent litigation against any entity (including a
+          cross-claim or counterclaim in a lawsuit) alleging that the Work
+          or a Contribution incorporated within the Work constitutes direct
+          or contributory patent infringement, then any patent licenses
+          granted to You under this License for that Work shall terminate
+          as of the date such litigation is filed.
+    
+       4. Redistribution. You may reproduce and distribute copies of the
+          Work or Derivative Works thereof in any medium, with or without
+          modifications, and in Source or Object form, provided that You
+          meet the following conditions:
+    
+          (a) You must give any other recipients of the Work or
+              Derivative Works a copy of this License; and
+    
+          (b) You must cause any modified files to carry prominent notices
+              stating that You changed the files; and
+    
+          (c) You must retain, in the Source form of any Derivative Works
+              that You distribute, all copyright, patent, trademark, and
+              attribution notices from the Source form of the Work,
+              excluding those notices that do not pertain to any part of
+              the Derivative Works; and
+    
+          (d) If the Work includes a "NOTICE" text file as part of its
+              distribution, then any Derivative Works that You distribute must
+              include a readable copy of the attribution notices contained
+              within such NOTICE file, excluding those notices that do not
+              pertain to any part of the Derivative Works, in at least one
+              of the following places: within a NOTICE text file distributed
+              as part of the Derivative Works; within the Source form or
+              documentation, if provided along with the Derivative Works; or,
+              within a display generated by the Derivative Works, if and
+              wherever such third-party notices normally appear. The contents
+              of the NOTICE file are for informational purposes only and
+              do not modify the License. You may add Your own attribution
+              notices within Derivative Works that You distribute, alongside
+              or as an addendum to the NOTICE text from the Work, provided
+              that such additional attribution notices cannot be construed
+              as modifying the License.
+    
+          You may add Your own copyright statement to Your modifications and
+          may provide additional or different license terms and conditions
+          for use, reproduction, or distribution of Your modifications, or
+          for any such Derivative Works as a whole, provided Your use,
+          reproduction, and distribution of the Work otherwise complies with
+          the conditions stated in this License.
+    
+       5. Submission of Contributions. Unless You explicitly state otherwise,
+          any Contribution intentionally submitted for inclusion in the Work
+          by You to the Licensor shall be under the terms and conditions of
+          this License, without any additional terms or conditions.
+          Notwithstanding the above, nothing herein shall supersede or modify
+          the terms of any separate license agreement you may have executed
+          with Licensor regarding such Contributions.
+    
+       6. Trademarks. This License does not grant permission to use the trade
+          names, trademarks, service marks, or product names of the Licensor,
+          except as required for reasonable and customary use in describing the
+          origin of the Work and reproducing the content of the NOTICE file.
+    
+       7. Disclaimer of Warranty. Unless required by applicable law or
+          agreed to in writing, Licensor provides the Work (and each
+          Contributor provides its Contributions) on an "AS IS" BASIS,
+          WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+          implied, including, without limitation, any warranties or conditions
+          of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+          PARTICULAR PURPOSE. You are solely responsible for determining the
+          appropriateness of using or redistributing the Work and assume any
+          risks associated with Your exercise of permissions under this License.
+    
+       8. Limitation of Liability. In no event and under no legal theory,
+          whether in tort (including negligence), contract, or otherwise,
+          unless required by applicable law (such as deliberate and grossly
+          negligent acts) or agreed to in writing, shall any Contributor be
+          liable to You for damages, including any direct, indirect, special,
+          incidental, or consequential damages of any character arising as a
+          result of this License or out of the use or inability to use the
+          Work (including but not limited to damages for loss of goodwill,
+          work stoppage, computer failure or malfunction, or any and all
+          other commercial damages or losses), even if such Contributor
+          has been advised of the possibility of such damages.
+    
+       9. Accepting Warranty or Additional Liability. While redistributing
+          the Work or Derivative Works thereof, You may choose to offer,
+          and charge a fee for, acceptance of support, warranty, indemnity,
+          or other liability obligations and/or rights consistent with this
+          License. However, in accepting such obligations, You may act only
+          on Your own behalf and on Your sole responsibility, not on behalf
+          of any other Contributor, and only if You agree to indemnify,
+          defend, and hold each Contributor harmless for any liability
+          incurred by, or claims asserted against, such Contributor by reason
+          of your accepting any such warranty or additional liability.
+    
+       END OF TERMS AND CONDITIONS
+    
+       APPENDIX: How to apply the Apache License to your work.
+    
+          To apply the Apache License to your work, attach the following
+          boilerplate notice, with the fields enclosed by brackets "[]"
+          replaced with your own identifying information. (Don't include
+          the brackets!)  The text should be enclosed in the appropriate
+          comment syntax for the file format. We also recommend that a
+          file or class name and description of purpose be included on the
+          same "printed page" as the copyright notice for easier
+          identification within third-party archives.
+    
+       Copyright [yyyy] [name of copyright owner]
+    
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+    
+           http://www.apache.org/licenses/LICENSE-2.0
+    
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+    
+
+## xerces
+
+Apache 2.0
+
+https://xerces.apache.org/xerces2-j/
+
+    
+                                     Apache License
+                               Version 2.0, January 2004
+                            http://www.apache.org/licenses/
+    
+       TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+    
+       1. Definitions.
+    
+          "License" shall mean the terms and conditions for use, reproduction,
+          and distribution as defined by Sections 1 through 9 of this document.
+    
+          "Licensor" shall mean the copyright owner or entity authorized by
+          the copyright owner that is granting the License.
+    
+          "Legal Entity" shall mean the union of the acting entity and all
+          other entities that control, are controlled by, or are under common
+          control with that entity. For the purposes of this definition,
+          "control" means (i) the power, direct or indirect, to cause the
+          direction or management of such entity, whether by contract or
+          otherwise, or (ii) ownership of fifty percent (50%) or more of the
+          outstanding shares, or (iii) beneficial ownership of such entity.
+    
+          "You" (or "Your") shall mean an individual or Legal Entity
+          exercising permissions granted by this License.
+    
+          "Source" form shall mean the preferred form for making modifications,
+          including but not limited to software source code, documentation
+          source, and configuration files.
+    
+          "Object" form shall mean any form resulting from mechanical
+          transformation or translation of a Source form, including but
+          not limited to compiled object code, generated documentation,
+          and conversions to other media types.
+    
+          "Work" shall mean the work of authorship, whether in Source or
+          Object form, made available under the License, as indicated by a
+          copyright notice that is included in or attached to the work
+          (an example is provided in the Appendix below).
+    
+          "Derivative Works" shall mean any work, whether in Source or Object
+          form, that is based on (or derived from) the Work and for which the
+          editorial revisions, annotations, elaborations, or other modifications
+          represent, as a whole, an original work of authorship. For the purposes
+          of this License, Derivative Works shall not include works that remain
+          separable from, or merely link (or bind by name) to the interfaces of,
+          the Work and Derivative Works thereof.
+    
+          "Contribution" shall mean any work of authorship, including
+          the original version of the Work and any modifications or additions
+          to that Work or Derivative Works thereof, that is intentionally
+          submitted to Licensor for inclusion in the Work by the copyright owner
+          or by an individual or Legal Entity authorized to submit on behalf of
+          the copyright owner. For the purposes of this definition, "submitted"
+          means any form of electronic, verbal, or written communication sent
+          to the Licensor or its representatives, including but not limited to
+          communication on electronic mailing lists, source code control systems,
+          and issue tracking systems that are managed by, or on behalf of, the
+          Licensor for the purpose of discussing and improving the Work, but
+          excluding communication that is conspicuously marked or otherwise
+          designated in writing by the copyright owner as "Not a Contribution."
+    
+          "Contributor" shall mean Licensor and any individual or Legal Entity
+          on behalf of whom a Contribution has been received by Licensor and
+          subsequently incorporated within the Work.
+    
+       2. Grant of Copyright License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          copyright license to reproduce, prepare Derivative Works of,
+          publicly display, publicly perform, sublicense, and distribute the
+          Work and such Derivative Works in Source or Object form.
+    
+       3. Grant of Patent License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          (except as stated in this section) patent license to make, have made,
+          use, offer to sell, sell, import, and otherwise transfer the Work,
+          where such license applies only to those patent claims licensable
+          by such Contributor that are necessarily infringed by their
+          Contribution(s) alone or by combination of their Contribution(s)
+          with the Work to which such Contribution(s) was submitted. If You
+          institute patent litigation against any entity (including a
+          cross-claim or counterclaim in a lawsuit) alleging that the Work
+          or a Contribution incorporated within the Work constitutes direct
+          or contributory patent infringement, then any patent licenses
+          granted to You under this License for that Work shall terminate
+          as of the date such litigation is filed.
+    
+       4. Redistribution. You may reproduce and distribute copies of the
+          Work or Derivative Works thereof in any medium, with or without
+          modifications, and in Source or Object form, provided that You
+          meet the following conditions:
+    
+          (a) You must give any other recipients of the Work or
+              Derivative Works a copy of this License; and
+    
+          (b) You must cause any modified files to carry prominent notices
+              stating that You changed the files; and
+    
+          (c) You must retain, in the Source form of any Derivative Works
+              that You distribute, all copyright, patent, trademark, and
+              attribution notices from the Source form of the Work,
+              excluding those notices that do not pertain to any part of
+              the Derivative Works; and
+    
+          (d) If the Work includes a "NOTICE" text file as part of its
+              distribution, then any Derivative Works that You distribute must
+              include a readable copy of the attribution notices contained
+              within such NOTICE file, excluding those notices that do not
+              pertain to any part of the Derivative Works, in at least one
+              of the following places: within a NOTICE text file distributed
+              as part of the Derivative Works; within the Source form or
+              documentation, if provided along with the Derivative Works; or,
+              within a display generated by the Derivative Works, if and
+              wherever such third-party notices normally appear. The contents
+              of the NOTICE file are for informational purposes only and
+              do not modify the License. You may add Your own attribution
+              notices within Derivative Works that You distribute, alongside
+              or as an addendum to the NOTICE text from the Work, provided
+              that such additional attribution notices cannot be construed
+              as modifying the License.
+    
+          You may add Your own copyright statement to Your modifications and
+          may provide additional or different license terms and conditions
+          for use, reproduction, or distribution of Your modifications, or
+          for any such Derivative Works as a whole, provided Your use,
+          reproduction, and distribution of the Work otherwise complies with
+          the conditions stated in this License.
+    
+       5. Submission of Contributions. Unless You explicitly state otherwise,
+          any Contribution intentionally submitted for inclusion in the Work
+          by You to the Licensor shall be under the terms and conditions of
+          this License, without any additional terms or conditions.
+          Notwithstanding the above, nothing herein shall supersede or modify
+          the terms of any separate license agreement you may have executed
+          with Licensor regarding such Contributions.
+    
+       6. Trademarks. This License does not grant permission to use the trade
+          names, trademarks, service marks, or product names of the Licensor,
+          except as required for reasonable and customary use in describing the
+          origin of the Work and reproducing the content of the NOTICE file.
+    
+       7. Disclaimer of Warranty. Unless required by applicable law or
+          agreed to in writing, Licensor provides the Work (and each
+          Contributor provides its Contributions) on an "AS IS" BASIS,
+          WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+          implied, including, without limitation, any warranties or conditions
+          of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+          PARTICULAR PURPOSE. You are solely responsible for determining the
+          appropriateness of using or redistributing the Work and assume any
+          risks associated with Your exercise of permissions under this License.
+    
+       8. Limitation of Liability. In no event and under no legal theory,
+          whether in tort (including negligence), contract, or otherwise,
+          unless required by applicable law (such as deliberate and grossly
+          negligent acts) or agreed to in writing, shall any Contributor be
+          liable to You for damages, including any direct, indirect, special,
+          incidental, or consequential damages of any character arising as a
+          result of this License or out of the use or inability to use the
+          Work (including but not limited to damages for loss of goodwill,
+          work stoppage, computer failure or malfunction, or any and all
+          other commercial damages or losses), even if such Contributor
+          has been advised of the possibility of such damages.
+    
+       9. Accepting Warranty or Additional Liability. While redistributing
+          the Work or Derivative Works thereof, You may choose to offer,
+          and charge a fee for, acceptance of support, warranty, indemnity,
+          or other liability obligations and/or rights consistent with this
+          License. However, in accepting such obligations, You may act only
+          on Your own behalf and on Your sole responsibility, not on behalf
+          of any other Contributor, and only if You agree to indemnify,
+          defend, and hold each Contributor harmless for any liability
+          incurred by, or claims asserted against, such Contributor by reason
+          of your accepting any such warranty or additional liability.
+    
+       END OF TERMS AND CONDITIONS
+    
+       APPENDIX: How to apply the Apache License to your work.
+    
+          To apply the Apache License to your work, attach the following
+          boilerplate notice, with the fields enclosed by brackets "[]"
+          replaced with your own identifying information. (Don't include
+          the brackets!)  The text should be enclosed in the appropriate
+          comment syntax for the file format. We also recommend that a
+          file or class name and description of purpose be included on the
+          same "printed page" as the copyright notice for easier
+          identification within third-party archives.
+    
+       Copyright [yyyy] [name of copyright owner]
+    
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+    
+           http://www.apache.org/licenses/LICENSE-2.0
+    
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+    
+
+## xml-apis
+
+Apache 2.0
+
+https://xerces.apache.org/xml-commons/
+
+    Unless otherwise noted all files in XML Commons are covered under the
+    Apache License Version 2.0. Please read the LICENSE and NOTICE files.
+    
+    XML Commons contains some software and documentation that is covered
+    under a number of different licenses. This applies particularly to the
+    xml-commons/java/external/ directory. Most files under
+    xml-commons/java/external/ are covered under their respective
+    LICENSE.*.txt files; see the matching README.*.txt files for
+    descriptions.
+
+    
+                                     Apache License
+                               Version 2.0, January 2004
+                            http://www.apache.org/licenses/
+    
+       TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+    
+       1. Definitions.
+    
+          "License" shall mean the terms and conditions for use, reproduction,
+          and distribution as defined by Sections 1 through 9 of this document.
+    
+          "Licensor" shall mean the copyright owner or entity authorized by
+          the copyright owner that is granting the License.
+    
+          "Legal Entity" shall mean the union of the acting entity and all
+          other entities that control, are controlled by, or are under common
+          control with that entity. For the purposes of this definition,
+          "control" means (i) the power, direct or indirect, to cause the
+          direction or management of such entity, whether by contract or
+          otherwise, or (ii) ownership of fifty percent (50%) or more of the
+          outstanding shares, or (iii) beneficial ownership of such entity.
+    
+          "You" (or "Your") shall mean an individual or Legal Entity
+          exercising permissions granted by this License.
+    
+          "Source" form shall mean the preferred form for making modifications,
+          including but not limited to software source code, documentation
+          source, and configuration files.
+    
+          "Object" form shall mean any form resulting from mechanical
+          transformation or translation of a Source form, including but
+          not limited to compiled object code, generated documentation,
+          and conversions to other media types.
+    
+          "Work" shall mean the work of authorship, whether in Source or
+          Object form, made available under the License, as indicated by a
+          copyright notice that is included in or attached to the work
+          (an example is provided in the Appendix below).
+    
+          "Derivative Works" shall mean any work, whether in Source or Object
+          form, that is based on (or derived from) the Work and for which the
+          editorial revisions, annotations, elaborations, or other modifications
+          represent, as a whole, an original work of authorship. For the purposes
+          of this License, Derivative Works shall not include works that remain
+          separable from, or merely link (or bind by name) to the interfaces of,
+          the Work and Derivative Works thereof.
+    
+          "Contribution" shall mean any work of authorship, including
+          the original version of the Work and any modifications or additions
+          to that Work or Derivative Works thereof, that is intentionally
+          submitted to Licensor for inclusion in the Work by the copyright owner
+          or by an individual or Legal Entity authorized to submit on behalf of
+          the copyright owner. For the purposes of this definition, "submitted"
+          means any form of electronic, verbal, or written communication sent
+          to the Licensor or its representatives, including but not limited to
+          communication on electronic mailing lists, source code control systems,
+          and issue tracking systems that are managed by, or on behalf of, the
+          Licensor for the purpose of discussing and improving the Work, but
+          excluding communication that is conspicuously marked or otherwise
+          designated in writing by the copyright owner as "Not a Contribution."
+    
+          "Contributor" shall mean Licensor and any individual or Legal Entity
+          on behalf of whom a Contribution has been received by Licensor and
+          subsequently incorporated within the Work.
+    
+       2. Grant of Copyright License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          copyright license to reproduce, prepare Derivative Works of,
+          publicly display, publicly perform, sublicense, and distribute the
+          Work and such Derivative Works in Source or Object form.
+    
+       3. Grant of Patent License. Subject to the terms and conditions of
+          this License, each Contributor hereby grants to You a perpetual,
+          worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+          (except as stated in this section) patent license to make, have made,
+          use, offer to sell, sell, import, and otherwise transfer the Work,
+          where such license applies only to those patent claims licensable
+          by such Contributor that are necessarily infringed by their
+          Contribution(s) alone or by combination of their Contribution(s)
+          with the Work to which such Contribution(s) was submitted. If You
+          institute patent litigation against any entity (including a
+          cross-claim or counterclaim in a lawsuit) alleging that the Work
+          or a Contribution incorporated within the Work constitutes direct
+          or contributory patent infringement, then any patent licenses
+          granted to You under this License for that Work shall terminate
+          as of the date such litigation is filed.
+    
+       4. Redistribution. You may reproduce and distribute copies of the
+          Work or Derivative Works thereof in any medium, with or without
+          modifications, and in Source or Object form, provided that You
+          meet the following conditions:
+    
+          (a) You must give any other recipients of the Work or
+              Derivative Works a copy of this License; and
+    
+          (b) You must cause any modified files to carry prominent notices
+              stating that You changed the files; and
+    
+          (c) You must retain, in the Source form of any Derivative Works
+              that You distribute, all copyright, patent, trademark, and
+              attribution notices from the Source form of the Work,
+              excluding those notices that do not pertain to any part of
+              the Derivative Works; and
+    
+          (d) If the Work includes a "NOTICE" text file as part of its
+              distribution, then any Derivative Works that You distribute must
+              include a readable copy of the attribution notices contained
+              within such NOTICE file, excluding those notices that do not
+              pertain to any part of the Derivative Works, in at least one
+              of the following places: within a NOTICE text file distributed
+              as part of the Derivative Works; within the Source form or
+              documentation, if provided along with the Derivative Works; or,
+              within a display generated by the Derivative Works, if and
+              wherever such third-party notices normally appear. The contents
+              of the NOTICE file are for informational purposes only and
+              do not modify the License. You may add Your own attribution
+              notices within Derivative Works that You distribute, alongside
+              or as an addendum to the NOTICE text from the Work, provided
+              that such additional attribution notices cannot be construed
+              as modifying the License.
+    
+          You may add Your own copyright statement to Your modifications and
+          may provide additional or different license terms and conditions
+          for use, reproduction, or distribution of Your modifications, or
+          for any such Derivative Works as a whole, provided Your use,
+          reproduction, and distribution of the Work otherwise complies with
+          the conditions stated in this License.
+    
+       5. Submission of Contributions. Unless You explicitly state otherwise,
+          any Contribution intentionally submitted for inclusion in the Work
+          by You to the Licensor shall be under the terms and conditions of
+          this License, without any additional terms or conditions.
+          Notwithstanding the above, nothing herein shall supersede or modify
+          the terms of any separate license agreement you may have executed
+          with Licensor regarding such Contributions.
+    
+       6. Trademarks. This License does not grant permission to use the trade
+          names, trademarks, service marks, or product names of the Licensor,
+          except as required for reasonable and customary use in describing the
+          origin of the Work and reproducing the content of the NOTICE file.
+    
+       7. Disclaimer of Warranty. Unless required by applicable law or
+          agreed to in writing, Licensor provides the Work (and each
+          Contributor provides its Contributions) on an "AS IS" BASIS,
+          WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+          implied, including, without limitation, any warranties or conditions
+          of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+          PARTICULAR PURPOSE. You are solely responsible for determining the
+          appropriateness of using or redistributing the Work and assume any
+          risks associated with Your exercise of permissions under this License.
+    
+       8. Limitation of Liability. In no event and under no legal theory,
+          whether in tort (including negligence), contract, or otherwise,
+          unless required by applicable law (such as deliberate and grossly
+          negligent acts) or agreed to in writing, shall any Contributor be
+          liable to You for damages, including any direct, indirect, special,
+          incidental, or consequential damages of any character arising as a
+          result of this License or out of the use or inability to use the
+          Work (including but not limited to damages for loss of goodwill,
+          work stoppage, computer failure or malfunction, or any and all
+          other commercial damages or losses), even if such Contributor
+          has been advised of the possibility of such damages.
+    
+       9. Accepting Warranty or Additional Liability. While redistributing
+          the Work or Derivative Works thereof, You may choose to offer,
+          and charge a fee for, acceptance of support, warranty, indemnity,
+          or other liability obligations and/or rights consistent with this
+          License. However, in accepting such obligations, You may act only
+          on Your own behalf and on Your sole responsibility, not on behalf
+          of any other Contributor, and only if You agree to indemnify,
+          defend, and hold each Contributor harmless for any liability
+          incurred by, or claims asserted against, such Contributor by reason
+          of your accepting any such warranty or additional liability.
+    
+       END OF TERMS AND CONDITIONS
+    
+       APPENDIX: How to apply the Apache License to your work.
+    
+          To apply the Apache License to your work, attach the following
+          boilerplate notice, with the fields enclosed by brackets "[]"
+          replaced with your own identifying information. (Don't include
+          the brackets!)  The text should be enclosed in the appropriate
+          comment syntax for the file format. We also recommend that a
+          file or class name and description of purpose be included on the
+          same "printed page" as the copyright notice for easier
+          identification within third-party archives.
+    
+       Copyright [yyyy] [name of copyright owner]
+    
+       Licensed under the Apache License, Version 2.0 (the "License");
+       you may not use this file except in compliance with the License.
+       You may obtain a copy of the License at
+    
+           http://www.apache.org/licenses/LICENSE-2.0
+    
+       Unless required by applicable law or agreed to in writing, software
+       distributed under the License is distributed on an "AS IS" BASIS,
+       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+       See the License for the specific language governing permissions and
+       limitations under the License.
+
+
+# binary windows release
+
+NOTE: these libraries are redistributed ONLY with the binary
+cross-compiled Windows platform version of Nokogiri, both x86-mingw32
+and x64-mingw32.
+
+## zlib
+
+zlib license
+
+http://www.zlib.net/zlib_license.html
+
+      Copyright (C) 1995-2017 Jean-loup Gailly and Mark Adler
+    
+      This software is provided 'as-is', without any express or implied
+      warranty.  In no event will the authors be held liable for any damages
+      arising from the use of this software.
+    
+      Permission is granted to anyone to use this software for any purpose,
+      including commercial applications, and to alter it and redistribute it
+      freely, subject to the following restrictions:
+    
+      1. The origin of this software must not be misrepresented; you must not
+         claim that you wrote the original software. If you use this software
+         in a product, an acknowledgment in the product documentation would be
+         appreciated but is not required.
+      2. Altered source versions must be plainly marked as such, and must not be
+         misrepresented as being the original software.
+      3. This notice may not be removed or altered from any source distribution.
+    
+      Jean-loup Gailly        Mark Adler
+      jloup at gzip.org          madler at alumni.caltech.edu
+    
+
+## libiconv
+
+LGPL
+
+https://www.gnu.org/software/libiconv/
+
+    		  GNU LIBRARY GENERAL PUBLIC LICENSE
+    		       Version 2, June 1991
+    
+     Copyright (C) 1991 Free Software Foundation, Inc.
+     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+     Everyone is permitted to copy and distribute verbatim copies
+     of this license document, but changing it is not allowed.
+    
+    [This is the first released version of the library GPL.  It is
+     numbered 2 because it goes with version 2 of the ordinary GPL.]
+    
+    			    Preamble
+    
+      The licenses for most software are designed to take away your
+    freedom to share and change it.  By contrast, the GNU General Public
+    Licenses are intended to guarantee your freedom to share and change
+    free software--to make sure the software is free for all its users.
+    
+      This license, the Library General Public License, applies to some
+    specially designated Free Software Foundation software, and to any
+    other libraries whose authors decide to use it.  You can use it for
+    your libraries, too.
+    
+      When we speak of free software, we are referring to freedom, not
+    price.  Our General Public Licenses are designed to make sure that you
+    have the freedom to distribute copies of free software (and charge for
+    this service if you wish), that you receive source code or can get it
+    if you want it, that you can change the software or use pieces of it
+    in new free programs; and that you know you can do these things.
+    
+      To protect your rights, we need to make restrictions that forbid
+    anyone to deny you these rights or to ask you to surrender the rights.
+    These restrictions translate to certain responsibilities for you if
+    you distribute copies of the library, or if you modify it.
+    
+      For example, if you distribute copies of the library, whether gratis
+    or for a fee, you must give the recipients all the rights that we gave
+    you.  You must make sure that they, too, receive or can get the source
+    code.  If you link a program with the library, you must provide
+    complete object files to the recipients so that they can relink them
+    with the library, after making changes to the library and recompiling
+    it.  And you must show them these terms so they know their rights.
+    
+      Our method of protecting your rights has two steps: (1) copyright
+    the library, and (2) offer you this license which gives you legal
+    permission to copy, distribute and/or modify the library.
+    
+      Also, for each distributor's protection, we want to make certain
+    that everyone understands that there is no warranty for this free
+    library.  If the library is modified by someone else and passed on, we
+    want its recipients to know that what they have is not the original
+    version, so that any problems introduced by others will not reflect on
+    the original authors' reputations.
+    

+      Finally, any free program is threatened constantly by software
+    patents.  We wish to avoid the danger that companies distributing free
+    software will individually obtain patent licenses, thus in effect
+    transforming the program into proprietary software.  To prevent this,
+    we have made it clear that any patent must be licensed for everyone's
+    free use or not licensed at all.
+    
+      Most GNU software, including some libraries, is covered by the ordinary
+    GNU General Public License, which was designed for utility programs.  This
+    license, the GNU Library General Public License, applies to certain
+    designated libraries.  This license is quite different from the ordinary
+    one; be sure to read it in full, and don't assume that anything in it is
+    the same as in the ordinary license.
+    
+      The reason we have a separate public license for some libraries is that
+    they blur the distinction we usually make between modifying or adding to a
+    program and simply using it.  Linking a program with a library, without
+    changing the library, is in some sense simply using the library, and is
+    analogous to running a utility program or application program.  However, in
+    a textual and legal sense, the linked executable is a combined work, a
+    derivative of the original library, and the ordinary General Public License
+    treats it as such.
+    
+      Because of this blurred distinction, using the ordinary General
+    Public License for libraries did not effectively promote software
+    sharing, because most developers did not use the libraries.  We
+    concluded that weaker conditions might promote sharing better.
+    
+      However, unrestricted linking of non-free programs would deprive the
+    users of those programs of all benefit from the free status of the
+    libraries themselves.  This Library General Public License is intended to
+    permit developers of non-free programs to use free libraries, while
+    preserving your freedom as a user of such programs to change the free
+    libraries that are incorporated in them.  (We have not seen how to achieve
+    this as regards changes in header files, but we have achieved it as regards
+    changes in the actual functions of the Library.)  The hope is that this
+    will lead to faster development of free libraries.
+    
+      The precise terms and conditions for copying, distribution and
+    modification follow.  Pay close attention to the difference between a
+    "work based on the library" and a "work that uses the library".  The
+    former contains code derived from the library, while the latter only
+    works together with the library.
+    
+      Note that it is possible for a library to be covered by the ordinary
+    General Public License rather than by this special one.
+    

+    		  GNU LIBRARY GENERAL PUBLIC LICENSE
+       TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+    
+      0. This License Agreement applies to any software library which
+    contains a notice placed by the copyright holder or other authorized
+    party saying it may be distributed under the terms of this Library
+    General Public License (also called "this License").  Each licensee is
+    addressed as "you".
+    
+      A "library" means a collection of software functions and/or data
+    prepared so as to be conveniently linked with application programs
+    (which use some of those functions and data) to form executables.
+    
+      The "Library", below, refers to any such software library or work
+    which has been distributed under these terms.  A "work based on the
+    Library" means either the Library or any derivative work under
+    copyright law: that is to say, a work containing the Library or a
+    portion of it, either verbatim or with modifications and/or translated
+    straightforwardly into another language.  (Hereinafter, translation is
+    included without limitation in the term "modification".)
+    
+      "Source code" for a work means the preferred form of the work for
+    making modifications to it.  For a library, complete source code means
+    all the source code for all modules it contains, plus any associated
+    interface definition files, plus the scripts used to control compilation
+    and installation of the library.
+    
+      Activities other than copying, distribution and modification are not
+    covered by this License; they are outside its scope.  The act of
+    running a program using the Library is not restricted, and output from
+    such a program is covered only if its contents constitute a work based
+    on the Library (independent of the use of the Library in a tool for
+    writing it).  Whether that is true depends on what the Library does
+    and what the program that uses the Library does.
+      
+      1. You may copy and distribute verbatim copies of the Library's
+    complete source code as you receive it, in any medium, provided that
+    you conspicuously and appropriately publish on each copy an
+    appropriate copyright notice and disclaimer of warranty; keep intact
+    all the notices that refer to this License and to the absence of any
+    warranty; and distribute a copy of this License along with the
+    Library.
+    
+      You may charge a fee for the physical act of transferring a copy,
+    and you may at your option offer warranty protection in exchange for a
+    fee.
+    

+      2. You may modify your copy or copies of the Library or any portion
+    of it, thus forming a work based on the Library, and copy and
+    distribute such modifications or work under the terms of Section 1
+    above, provided that you also meet all of these conditions:
+    
+        a) The modified work must itself be a software library.
+    
+        b) You must cause the files modified to carry prominent notices
+        stating that you changed the files and the date of any change.
+    
+        c) You must cause the whole of the work to be licensed at no
+        charge to all third parties under the terms of this License.
+    
+        d) If a facility in the modified Library refers to a function or a
+        table of data to be supplied by an application program that uses
+        the facility, other than as an argument passed when the facility
+        is invoked, then you must make a good faith effort to ensure that,
+        in the event an application does not supply such function or
+        table, the facility still operates, and performs whatever part of
+        its purpose remains meaningful.
+    
+        (For example, a function in a library to compute square roots has
+        a purpose that is entirely well-defined independent of the
+        application.  Therefore, Subsection 2d requires that any
+        application-supplied function or table used by this function must
+        be optional: if the application does not supply it, the square
+        root function must still compute square roots.)
+    
+    These requirements apply to the modified work as a whole.  If
+    identifiable sections of that work are not derived from the Library,
+    and can be reasonably considered independent and separate works in
+    themselves, then this License, and its terms, do not apply to those
+    sections when you distribute them as separate works.  But when you
+    distribute the same sections as part of a whole which is a work based
+    on the Library, the distribution of the whole must be on the terms of
+    this License, whose permissions for other licensees extend to the
+    entire whole, and thus to each and every part regardless of who wrote
+    it.
+    
+    Thus, it is not the intent of this section to claim rights or contest
+    your rights to work written entirely by you; rather, the intent is to
+    exercise the right to control the distribution of derivative or
+    collective works based on the Library.
+    
+    In addition, mere aggregation of another work not based on the Library
+    with the Library (or with a work based on the Library) on a volume of
+    a storage or distribution medium does not bring the other work under
+    the scope of this License.
+    
+      3. You may opt to apply the terms of the ordinary GNU General Public
+    License instead of this License to a given copy of the Library.  To do
+    this, you must alter all the notices that refer to this License, so
+    that they refer to the ordinary GNU General Public License, version 2,
+    instead of to this License.  (If a newer version than version 2 of the
+    ordinary GNU General Public License has appeared, then you can specify
+    that version instead if you wish.)  Do not make any other change in
+    these notices.
+    

+      Once this change is made in a given copy, it is irreversible for
+    that copy, so the ordinary GNU General Public License applies to all
+    subsequent copies and derivative works made from that copy.
+    
+      This option is useful when you wish to copy part of the code of
+    the Library into a program that is not a library.
+    
+      4. You may copy and distribute the Library (or a portion or
+    derivative of it, under Section 2) in object code or executable form
+    under the terms of Sections 1 and 2 above provided that you accompany
+    it with the complete corresponding machine-readable source code, which
+    must be distributed under the terms of Sections 1 and 2 above on a
+    medium customarily used for software interchange.
+    
+      If distribution of object code is made by offering access to copy
+    from a designated place, then offering equivalent access to copy the
+    source code from the same place satisfies the requirement to
+    distribute the source code, even though third parties are not
+    compelled to copy the source along with the object code.
+    
+      5. A program that contains no derivative of any portion of the
+    Library, but is designed to work with the Library by being compiled or
+    linked with it, is called a "work that uses the Library".  Such a
+    work, in isolation, is not a derivative work of the Library, and
+    therefore falls outside the scope of this License.
+    
+      However, linking a "work that uses the Library" with the Library
+    creates an executable that is a derivative of the Library (because it
+    contains portions of the Library), rather than a "work that uses the
+    library".  The executable is therefore covered by this License.
+    Section 6 states terms for distribution of such executables.
+    
+      When a "work that uses the Library" uses material from a header file
+    that is part of the Library, the object code for the work may be a
+    derivative work of the Library even though the source code is not.
+    Whether this is true is especially significant if the work can be
+    linked without the Library, or if the work is itself a library.  The
+    threshold for this to be true is not precisely defined by law.
+    
+      If such an object file uses only numerical parameters, data
+    structure layouts and accessors, and small macros and small inline
+    functions (ten lines or less in length), then the use of the object
+    file is unrestricted, regardless of whether it is legally a derivative
+    work.  (Executables containing this object code plus portions of the
+    Library will still fall under Section 6.)
+    
+      Otherwise, if the work is a derivative of the Library, you may
+    distribute the object code for the work under the terms of Section 6.
+    Any executables containing that work also fall under Section 6,
+    whether or not they are linked directly with the Library itself.
+    

+      6. As an exception to the Sections above, you may also compile or
+    link a "work that uses the Library" with the Library to produce a
+    work containing portions of the Library, and distribute that work
+    under terms of your choice, provided that the terms permit
+    modification of the work for the customer's own use and reverse
+    engineering for debugging such modifications.
+    
+      You must give prominent notice with each copy of the work that the
+    Library is used in it and that the Library and its use are covered by
+    this License.  You must supply a copy of this License.  If the work
+    during execution displays copyright notices, you must include the
+    copyright notice for the Library among them, as well as a reference
+    directing the user to the copy of this License.  Also, you must do one
+    of these things:
+    
+        a) Accompany the work with the complete corresponding
+        machine-readable source code for the Library including whatever
+        changes were used in the work (which must be distributed under
+        Sections 1 and 2 above); and, if the work is an executable linked
+        with the Library, with the complete machine-readable "work that
+        uses the Library", as object code and/or source code, so that the
+        user can modify the Library and then relink to produce a modified
+        executable containing the modified Library.  (It is understood
+        that the user who changes the contents of definitions files in the
+        Library will not necessarily be able to recompile the application
+        to use the modified definitions.)
+    
+        b) Accompany the work with a written offer, valid for at
+        least three years, to give the same user the materials
+        specified in Subsection 6a, above, for a charge no more
+        than the cost of performing this distribution.
+    
+        c) If distribution of the work is made by offering access to copy
+        from a designated place, offer equivalent access to copy the above
+        specified materials from the same place.
+    
+        d) Verify that the user has already received a copy of these
+        materials or that you have already sent this user a copy.
+    
+      For an executable, the required form of the "work that uses the
+    Library" must include any data and utility programs needed for
+    reproducing the executable from it.  However, as a special exception,
+    the source code distributed need not include anything that is normally
+    distributed (in either source or binary form) with the major
+    components (compiler, kernel, and so on) of the operating system on
+    which the executable runs, unless that component itself accompanies
+    the executable.
+    
+      It may happen that this requirement contradicts the license
+    restrictions of other proprietary libraries that do not normally
+    accompany the operating system.  Such a contradiction means you cannot
+    use both them and the Library together in an executable that you
+    distribute.
+    

+      7. You may place library facilities that are a work based on the
+    Library side-by-side in a single library together with other library
+    facilities not covered by this License, and distribute such a combined
+    library, provided that the separate distribution of the work based on
+    the Library and of the other library facilities is otherwise
+    permitted, and provided that you do these two things:
+    
+        a) Accompany the combined library with a copy of the same work
+        based on the Library, uncombined with any other library
+        facilities.  This must be distributed under the terms of the
+        Sections above.
+    
+        b) Give prominent notice with the combined library of the fact
+        that part of it is a work based on the Library, and explaining
+        where to find the accompanying uncombined form of the same work.
+    
+      8. You may not copy, modify, sublicense, link with, or distribute
+    the Library except as expressly provided under this License.  Any
+    attempt otherwise to copy, modify, sublicense, link with, or
+    distribute the Library is void, and will automatically terminate your
+    rights under this License.  However, parties who have received copies,
+    or rights, from you under this License will not have their licenses
+    terminated so long as such parties remain in full compliance.
+    
+      9. You are not required to accept this License, since you have not
+    signed it.  However, nothing else grants you permission to modify or
+    distribute the Library or its derivative works.  These actions are
+    prohibited by law if you do not accept this License.  Therefore, by
+    modifying or distributing the Library (or any work based on the
+    Library), you indicate your acceptance of this License to do so, and
+    all its terms and conditions for copying, distributing or modifying
+    the Library or works based on it.
+    
+      10. Each time you redistribute the Library (or any work based on the
+    Library), the recipient automatically receives a license from the
+    original licensor to copy, distribute, link with or modify the Library
+    subject to these terms and conditions.  You may not impose any further
+    restrictions on the recipients' exercise of the rights granted herein.
+    You are not responsible for enforcing compliance by third parties to
+    this License.
+    

+      11. If, as a consequence of a court judgment or allegation of patent
+    infringement or for any other reason (not limited to patent issues),
+    conditions are imposed on you (whether by court order, agreement or
+    otherwise) that contradict the conditions of this License, they do not
+    excuse you from the conditions of this License.  If you cannot
+    distribute so as to satisfy simultaneously your obligations under this
+    License and any other pertinent obligations, then as a consequence you
+    may not distribute the Library at all.  For example, if a patent
+    license would not permit royalty-free redistribution of the Library by
+    all those who receive copies directly or indirectly through you, then
+    the only way you could satisfy both it and this License would be to
+    refrain entirely from distribution of the Library.
+    
+    If any portion of this section is held invalid or unenforceable under any
+    particular circumstance, the balance of the section is intended to apply,
+    and the section as a whole is intended to apply in other circumstances.
+    
+    It is not the purpose of this section to induce you to infringe any
+    patents or other property right claims or to contest validity of any
+    such claims; this section has the sole purpose of protecting the
+    integrity of the free software distribution system which is
+    implemented by public license practices.  Many people have made
+    generous contributions to the wide range of software distributed
+    through that system in reliance on consistent application of that
+    system; it is up to the author/donor to decide if he or she is willing
+    to distribute software through any other system and a licensee cannot
+    impose that choice.
+    
+    This section is intended to make thoroughly clear what is believed to
+    be a consequence of the rest of this License.
+    
+      12. If the distribution and/or use of the Library is restricted in
+    certain countries either by patents or by copyrighted interfaces, the
+    original copyright holder who places the Library under this License may add
+    an explicit geographical distribution limitation excluding those countries,
+    so that distribution is permitted only in or among countries not thus
+    excluded.  In such case, this License incorporates the limitation as if
+    written in the body of this License.
+    
+      13. The Free Software Foundation may publish revised and/or new
+    versions of the Library General Public License from time to time.
+    Such new versions will be similar in spirit to the present version,
+    but may differ in detail to address new problems or concerns.
+    
+    Each version is given a distinguishing version number.  If the Library
+    specifies a version number of this License which applies to it and
+    "any later version", you have the option of following the terms and
+    conditions either of that version or of any later version published by
+    the Free Software Foundation.  If the Library does not specify a
+    license version number, you may choose any version ever published by
+    the Free Software Foundation.
+    

+      14. If you wish to incorporate parts of the Library into other free
+    programs whose distribution conditions are incompatible with these,
+    write to the author to ask for permission.  For software which is
+    copyrighted by the Free Software Foundation, write to the Free
+    Software Foundation; we sometimes make exceptions for this.  Our
+    decision will be guided by the two goals of preserving the free status
+    of all derivatives of our free software and of promoting the sharing
+    and reuse of software generally.
+    
+    			    NO WARRANTY
+    
+      15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+    WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+    EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+    OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+    PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+    LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+    THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+    
+      16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+    WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+    AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+    FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+    CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+    LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+    RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+    FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+    SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+    DAMAGES.
+    
+    		     END OF TERMS AND CONDITIONS
+    

+         Appendix: How to Apply These Terms to Your New Libraries
+    
+      If you develop a new library, and you want it to be of the greatest
+    possible use to the public, we recommend making it free software that
+    everyone can redistribute and change.  You can do so by permitting
+    redistribution under these terms (or, alternatively, under the terms of the
+    ordinary General Public License).
+    
+      To apply these terms, attach the following notices to the library.  It is
+    safest to attach them to the start of each source file to most effectively
+    convey the exclusion of warranty; and each file should have at least the
+    "copyright" line and a pointer to where the full notice is found.
+    
+        <one line to give the library's name and a brief idea of what it does.>
+        Copyright (C) <year>  <name of author>
+    
+        This library is free software; you can redistribute it and/or
+        modify it under the terms of the GNU Library General Public
+        License as published by the Free Software Foundation; either
+        version 2 of the License, or (at your option) any later version.
+    
+        This library is distributed in the hope that it will be useful,
+        but WITHOUT ANY WARRANTY; without even the implied warranty of
+        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+        Library General Public License for more details.
+    
+        You should have received a copy of the GNU Library General Public
+        License along with this library; if not, write to the Free
+        Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+        MA 02110-1301, USA
+    
+    Also add information on how to contact you by electronic and paper mail.
+    
+    You should also get your employer (if you work as a programmer) or your
+    school, if any, to sign a "copyright disclaimer" for the library, if
+    necessary.  Here is a sample; alter the names:
+    
+      Yoyodyne, Inc., hereby disclaims all copyright interest in the
+      library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+    
+      <signature of Ty Coon>, 1 April 1990
+      Ty Coon, President of Vice
+    
+    That's all there is to it!
diff --git a/LICENSE.txt b/LICENSE.md
similarity index 98%
rename from LICENSE.txt
rename to LICENSE.md
index a19c086..c9c7d63 100644
--- a/LICENSE.txt
+++ b/LICENSE.md
@@ -1,6 +1,6 @@
 (The MIT License)
 
-Copyright (c) 2008 - 2016:
+Copyright (c) 2008 - 2017:
 
 * [Aaron Patterson](http://tenderlovemaking.com)
 * [Mike Dalessio](http://mike.daless.io)
diff --git a/Manifest.txt b/Manifest.txt
index 7f515c4..e996f8c 100644
--- a/Manifest.txt
+++ b/Manifest.txt
@@ -3,11 +3,13 @@
 .editorconfig
 .gemtest
 .travis.yml
-CHANGELOG.rdoc
+CHANGELOG.md
 CONTRIBUTING.md
 C_CODING_STYLE.rdoc
 Gemfile
-LICENSE.txt
+Gemfile-libxml-ruby
+LICENSE-DEPENDENCIES.md
+LICENSE.md
 Manifest.txt
 README.md
 ROADMAP.md
@@ -54,7 +56,6 @@ ext/java/nokogiri/internals/ClosedStreamException.java
 ext/java/nokogiri/internals/HtmlDomParserContext.java
 ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java
 ext/java/nokogiri/internals/NokogiriBlockingQueueInputStream.java
-ext/java/nokogiri/internals/NokogiriDocumentCache.java
 ext/java/nokogiri/internals/NokogiriDomParser.java
 ext/java/nokogiri/internals/NokogiriEncodingReaderWrapper.java
 ext/java/nokogiri/internals/NokogiriEntityResolver.java
@@ -75,10 +76,10 @@ ext/java/nokogiri/internals/ReaderNode.java
 ext/java/nokogiri/internals/SaveContextVisitor.java
 ext/java/nokogiri/internals/SchemaErrorHandler.java
 ext/java/nokogiri/internals/UncloseableInputStream.java
+ext/java/nokogiri/internals/XalanDTMManagerPatch.java
 ext/java/nokogiri/internals/XmlDeclHandler.java
 ext/java/nokogiri/internals/XmlDomParserContext.java
 ext/java/nokogiri/internals/XmlSaxParser.java
-ext/java/nokogiri/internals/XsltExtensionFunction.java
 ext/java/nokogiri/internals/c14n/AttrCompare.java
 ext/java/nokogiri/internals/c14n/C14nHelper.java
 ext/java/nokogiri/internals/c14n/CanonicalFilter.java
@@ -106,6 +107,7 @@ ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java
 ext/java/nokogiri/internals/c14n/NodeFilter.java
 ext/java/nokogiri/internals/c14n/UtfHelpper.java
 ext/java/nokogiri/internals/c14n/XMLUtils.java
+ext/java/org/apache/xml/dtm/ref/dom2dtm/DOM2DTMExt.java
 ext/nokogiri/depend
 ext/nokogiri/extconf.rb
 ext/nokogiri/html_document.c
@@ -246,12 +248,13 @@ lib/xalan.jar
 lib/xercesImpl.jar
 lib/xml-apis.jar
 lib/xsd/xmlparser/nokogiri.rb
+patches/libxml2/0001-Fix-comparison-with-root-node-in-xmlXPathCmpNodes.patch
+patches/libxml2/0002-Fix-XPointer-paths-beginning-with-range-to.patch
+patches/libxml2/0003-Disallow-namespace-nodes-in-XPointer-ranges.patch
+patches/libxslt/0001-Fix-heap-overread-in-xsltFormatNumberConversion.patch
+patches/libxslt/0002-Check-for-integer-overflow-in-xsltAddTextString.patch
 patches/sort-patches-by-date
 suppressions/README.txt
-suppressions/nokogiri_ree-1.8.7.358.supp
-suppressions/nokogiri_ruby-1.8.7.370.supp
-suppressions/nokogiri_ruby-1.9.2.320.supp
-suppressions/nokogiri_ruby-1.9.3.327.supp
 tasks/test.rb
 test/css/test_nthiness.rb
 test/css/test_parser.rb
@@ -361,4 +364,3 @@ test/xml/test_xinclude.rb
 test/xml/test_xpath.rb
 test/xslt/test_custom_functions.rb
 test/xslt/test_exception_handling.rb
-test_all
diff --git a/README.md b/README.md
index 0933667..bb3b321 100644
--- a/README.md
+++ b/README.md
@@ -10,10 +10,13 @@
 
 ## Status
 
-[![Travis Build Status](https://travis-ci.org/sparklemotion/nokogiri.svg?branch=master)](https://travis-ci.org/sparklemotion/nokogiri)
-[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/github/sparklemotion/nokogiri?branch=master&svg=true)](https://ci.appveyor.com/project/flavorjones/nokogiri?branch=master)
-[![Code Climate](https://codeclimate.com/github/sparklemotion/nokogiri.png)](https://codeclimate.com/github/sparklemotion/nokogiri)
-[![Version Eye](https://www.versioneye.com/ruby/nokogiri/badge.png)](https://www.versioneye.com/ruby/nokogiri)
+|System|Status|
+|--|--|
+| Concourse | [![Concourse CI](https://ci.nokogiri.org/api/v1/teams/nokogiri-core/pipelines/nokogiri/jobs/ruby-2.4-system/badge)](https://ci.nokogiri.org/teams/nokogiri-core/pipelines/nokogiri?groups=master) |
+| Travis | [![Travis Build Status](https://travis-ci.org/sparklemotion/nokogiri.svg?branch=master)](https://travis-ci.org/sparklemotion/nokogiri) |
+| Appveyor | [![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/github/sparklemotion/nokogiri?branch=master&svg=true)](https://ci.appveyor.com/project/flavorjones/nokogiri?branch=master) |
+| Code Climate | [![Code Climate](https://codeclimate.com/github/sparklemotion/nokogiri.svg)](https://codeclimate.com/github/sparklemotion/nokogiri) |
+| Version Eye | [![Version Eye](https://www.versioneye.com/ruby/nokogiri/badge.png)](https://www.versioneye.com/ruby/nokogiri) |
 
 
 ## Description
@@ -110,13 +113,17 @@ end
 
 ## Requirements
 
-* Ruby 1.9.3 or higher, including any development packages necessary
+* Ruby 2.1.0 or higher, including any development packages necessary
   to compile native extensions.
 
 * In Nokogiri 1.6.0 and later libxml2 and libxslt are bundled with the
   gem, but if you want to use the system versions:
 
-  * at install time, set the environment variable
+  * First, check out [the long list](http://www.xmlsoft.org/news.html)
+    of fixes and changes between releases before deciding to use any
+    version older than is bundled with Nokogiri.
+
+  * At install time, set the environment variable
     `NOKOGIRI_USE_SYSTEM_LIBRARIES` or else use the
     `--use-system-libraries` argument. (See
     http://nokogiri.org/tutorials/installing_nokogiri.html#using_your_system_libraries
@@ -163,4 +170,4 @@ explicitly setting the encoding to EUC-JP on the parser:
 
 ## License
 
-MIT. See the `LICENSE.txt` file.
+MIT. See the `LICENSE.md` file.
diff --git a/Rakefile b/Rakefile
index 49de8b0..5e21da9 100644
--- a/Rakefile
+++ b/Rakefile
@@ -31,8 +31,6 @@ CrossRuby = Struct.new(:version, :host) {
     case minor_ver
     when nil
       raise "unsupported version: #{ver}"
-    when '1.9'
-      '191'
     else
       minor_ver.delete('.') << '0'
     end
@@ -113,7 +111,7 @@ HOE = Hoe.spec 'nokogiri' do
   license "MIT"
 
   self.readme_file  = "README.md"
-  self.history_file = ['CHANGELOG', ENV['HLANG'], 'rdoc'].compact.join('.')
+  self.history_file = "CHANGELOG.md"
 
   self.extra_rdoc_files = FileList['*.rdoc','ext/nokogiri/*.c']
 
@@ -127,29 +125,33 @@ HOE = Hoe.spec 'nokogiri' do
 
   unless java?
     self.extra_deps += [
-      ["mini_portile2",    "~> 2.1.0"], # keep version in sync with extconf.rb
+      ["mini_portile2",    "~> 2.2.0"], # keep version in sync with extconf.rb
     ]
   end
 
   self.extra_dev_deps += [
     ["hoe-bundler",        "~> 1.2.0"],
-    ["hoe-debugging",      "~> 1.2.1"],
+    ["hoe-debugging",      "~> 1.3.0"],
     ["hoe-gemspec",        "~> 1.0.0"],
     ["hoe-git",            "~> 1.6.0"],
     ["minitest",           "~> 5.8.4"],
-    ["rake",               "~> 10.5.0"],
-    ["rake-compiler",      "~> 0.9.2"],
-    ["rake-compiler-dock", "~> 0.5.1"],
+    ["rake",               "~> 12.0"],
+    ["rake-compiler",      "~> 1.0.3"],
+    ["rake-compiler-dock", "~> 0.6.0"],
     ["racc",               "~> 1.4.14"],
-    ["rexical",            "~> 1.0.5"]
+    ["rexical",            "~> 1.0.5"],
+    ["concourse",          "~> 0.11"],
   ]
 
   if java?
-    self.spec_extras = { :platform => 'java' }
+    self.spec_extras = {
+        :platform => 'java',
+        :required_ruby_version => '>= 1.9.3' # JRuby >= 1.7
+    }
   else
     self.spec_extras = {
       :extensions => ["ext/nokogiri/extconf.rb"],
-      :required_ruby_version => '>= 1.9.2'
+      :required_ruby_version => '>= 2.1.0'
     }
   end
 
@@ -232,11 +234,6 @@ else
       ext.cross_compiling do |spec|
         libs = dependencies.map { |name, dep| "#{name}-#{dep["version"]}" }.join(', ')
 
-        spec.required_ruby_version = [
-          '>= 1.9.2',
-          "< #{CROSS_RUBIES.max_by(&:ver).minor_ver.succ}"
-        ]
-
         spec.post_install_message = <<-EOS
 Nokogiri is built with the packaged libraries: #{libs}.
         EOS
@@ -261,7 +258,7 @@ task 'bundler:gemfile' do
   old_gemfile_task.invoke if old_gemfile_task
 
   lines = File.open('Gemfile', 'r') { |f| f.readlines }.map do |line|
-    line =~ /racc|rexical/ ? "#{line.strip}, :platform => :ruby" : line
+    line =~ /racc|rexical/ ? "#{line.strip}, :platform => [:ruby, :mingw, :x64_mingw]" : line
   end
   File.open('Gemfile', 'w') { |f| lines.each { |line| f.puts line } }
 end
@@ -316,23 +313,8 @@ if Hoe.plugins.include?(:debugging)
   end
 end
 
-task "test:libxml-ruby" do
-  ENV['TEST_NOKOGIRI_WITH_LIBXML_RUBY'] = "1"
-  warn "#{__FILE__}:#{__LINE__}: --- running tests with libxml-ruby loaded ---"
-  Rake::Task[:test].execute
-  ENV['TEST_NOKOGIRI_WITH_LIBXML_RUBY'] = nil
-end
-
-Rake::Task["test:libxml-ruby"].prerequisites << :compile
-
-task "test:valgrind:libxml-ruby" do
-  ENV['TEST_NOKOGIRI_WITH_LIBXML_RUBY'] = "1"
-  warn "#{__FILE__}:#{__LINE__}: --- running tests with libxml-ruby loaded ---"
-  Rake::Task["test:valgrind"].execute
-  ENV['TEST_NOKOGIRI_WITH_LIBXML_RUBY'] = nil
-end
-
-Rake::Task["test:valgrind:libxml-ruby"].prerequisites << :compile
+require 'concourse'
+Concourse.new("nokogiri").create_tasks!
 
 # ----------------------------------------
 
@@ -354,7 +336,7 @@ end
 task :cross do
   rake_compiler_config_path = File.expand_path("~/.rake-compiler/config.yml")
   unless File.exists? rake_compiler_config_path
-    raise "rake-compiler has not installed any cross rubies. Try using rake-compiler-dev-box for building binary windows gems.'"
+    raise "rake-compiler has not installed any cross rubies. Use rake-compiler-dock or 'rake gem:windows' for building binary windows gems."
   end
 
   CROSS_RUBIES.each do |cross_ruby|
diff --git a/Y_U_NO_GEMSPEC.md b/Y_U_NO_GEMSPEC.md
index 7c3cbb4..710e2ae 100644
--- a/Y_U_NO_GEMSPEC.md
+++ b/Y_U_NO_GEMSPEC.md
@@ -22,7 +22,7 @@ the historical record:
 * [A nokogiri-talk thread](http://groups.google.com/group/nokogiri-talk/browse_thread/thread/4706b002e492d23f)
 * [Another nokogiri-talk thread](http://groups.google.com/group/nokogiri-talk/browse_thread/thread/0b201bb80ea3eea0)
 
-Sometimes people imply that we've forgotten, or that we don't how to
+Sometimes people imply that we've forgotten, or that we don't know how to
 properly manage our codebase. Those people are super fun to respond
 to!
 
diff --git a/appveyor.yml b/appveyor.yml
index 15216a5..a838745 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -13,6 +13,8 @@ test_script:
 
 environment:
   matrix:
+    - ruby_version: "23"
+    - ruby_version: "23-x64"
     - ruby_version: "22"
     - ruby_version: "22-x64"
     - ruby_version: "21"
diff --git a/build_all b/build_all
index 9be6a7a..49a27dd 100755
--- a/build_all
+++ b/build_all
@@ -16,7 +16,6 @@ else
 fi
 
 set -o errexit
-#set -x
 
 rm -rf tmp pkg
 bundle exec rake clean clobber
diff --git a/dependencies.yml b/dependencies.yml
index fccaeef..2356802 100644
--- a/dependencies.yml
+++ b/dependencies.yml
@@ -1,6 +1,6 @@
 libxml2:
   version: "2.9.4"
-  md5: "ae249165c173b1ff386ee8ad676815f5" # manually confirmed via `gpg --verify`
+  sha256: "ffb911191e509b966deb55de705387f14156e1a56b21824357cdf0053233633c" # manually confirmed via `gpg --verify`
   # gpg: Signature made Mon 23 May 2016 04:02:13 AM EDT using DSA key ID DE95BC1F
   # gpg: Good signature from "Daniel Veillard (Red Hat work email) <veillard at redhat.com>"
   # gpg:                 aka "Daniel Veillard <Daniel.Veillard at w3.org>"
@@ -10,7 +10,7 @@ libxml2:
 
 libxslt:
   version: "1.1.29"
-  md5: "a129d3c44c022de3b9dcf6d6f288d72e"
+  sha256: "b5976e3857837e7617b29f2249ebb5eeac34e249208d31f1fbf7a6ba7a4090ce"
   # gpg: Signature made Mon 23 May 2016 09:58:52 PM EDT using DSA key ID DE95BC1F
   # gpg: Good signature from "Daniel Veillard (Red Hat work email) <veillard at redhat.com>"
   # gpg:                 aka "Daniel Veillard <Daniel.Veillard at w3.org>"
@@ -19,11 +19,16 @@ libxslt:
   # Primary key fingerprint: C744 15BA 7C9C 7F78 F02E  1DC3 4606 B8A5 DE95 BC1F
 
 zlib:
-  version: "1.2.8"
-  md5: "44d667c142d7cda120332623eab69f40"
+  version: "1.2.11"
+  sha256: "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1"
+  # SHA-256 hash provided on http://zlib.net/
 
 libiconv:
-  version: "1.14"
-  md5: "e34509b1623cec449dfeb73d7ce9c6c6"
-  # gpg: Signature made Sun 07 Aug 2011 01:58:18 PM EDT using DSA key ID F059B1D1
-  # gpg: BAD signature from "Bruno Haible (Open Source Development) <bruno at clisp.org>"
+  version: "1.15"
+  sha256: "ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178"
+  # gpg: Signature made Fri Feb  3 00:38:12 2017 CET
+  # gpg:                using RSA key 4F494A942E4616C2
+  # gpg: Good signature from "Bruno Haible (Open Source Development) <bruno at clisp.org>" [unknown]
+  # gpg: WARNING: This key is not certified with a trusted signature!
+  # gpg:          There is no indication that the signature belongs to the owner.
+  # Primary key fingerprint: 68D9 4D8A AEEA D48A E7DC  5B90 4F49 4A94 2E46 16C2
diff --git a/ext/nokogiri/extconf.rb b/ext/nokogiri/extconf.rb
index c6b51a4..be98b7f 100644
--- a/ext/nokogiri/extconf.rb
+++ b/ext/nokogiri/extconf.rb
@@ -20,6 +20,10 @@ def darwin?
   RbConfig::CONFIG['target_os'] =~ /darwin/
 end
 
+def openbsd?
+  RbConfig::CONFIG['target_os'] =~ /openbsd/
+end
+
 def nix?
   ! (windows? || solaris? || darwin?)
 end
@@ -62,7 +66,7 @@ usage: ruby #{$0} [options]
         Use the zlib library placed under DIR.
 
     --use-system-libraries
-        Use system libraries intead of building and using the bundled
+        Use system libraries instead of building and using the bundled
         libraries.
 
     --with-xml2-dir=DIR / --with-xml2-config=CONFIG
@@ -131,12 +135,7 @@ def package_config pkg, options={}
 end
 
 def nokogiri_try_compile
-  args = if defined?(RUBY_VERSION) && RUBY_VERSION <= "1.9.2"
-           ["int main() {return 0;}"]
-         else
-           ["int main() {return 0;}", "", {werror: true}]
-         end
-  try_compile(*args)
+  try_compile "int main() {return 0;}", "", {werror: true}
 end
 
 def check_libxml_version version=nil
@@ -224,8 +223,8 @@ def iconv_configure_flags
 
       return [
         '--with-iconv=yes',
-        *("CPPFLAGS=#{idirs.map { |dir| '-I' << dir }.join(' ')}" if idirs),
-        *("LDFLAGS=#{ldirs.map { |dir| '-L' << dir }.join(' ')}" if ldirs),
+        *("CPPFLAGS=#{idirs.map { |dir| '-I' + dir }.join(' ')}" if idirs),
+        *("LDFLAGS=#{ldirs.map { |dir| '-L' + dir }.join(' ')}" if ldirs),
       ]
     end
   end
@@ -261,11 +260,12 @@ end
 
 def process_recipe(name, version, static_p, cross_p)
   MiniPortile.new(name, version).tap do |recipe|
-    recipe.target = portsdir = File.join(ROOT, "ports")
+    recipe.target = File.join(ROOT, "ports")
     # Prefer host_alias over host in order to use i586-mingw32msvc as
     # correct compiler prefix for cross build, but use host if not set.
     recipe.host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"]
     recipe.patch_files = Dir[File.join(ROOT, "patches", name, "*.patch")].sort
+    recipe.configure_options << "--libdir=#{File.join(recipe.path, "lib")}"
 
     yield recipe
 
@@ -308,7 +308,7 @@ def process_recipe(name, version, static_p, cross_p)
     if RbConfig::CONFIG['target_cpu'] == 'universal'
       %w[CFLAGS LDFLAGS].each do |key|
         unless env[key].include?('-arch')
-          env[key] << ' ' << RbConfig::CONFIG['ARCH_FLAG']
+          env[key] += ' ' + RbConfig::CONFIG['ARCH_FLAG']
         end
       end
     end
@@ -382,14 +382,6 @@ def using_system_libraries?
 end
 
 #
-# monkey patches
-#
-
-# Workaround for Ruby bug #8074, introduced in Ruby 2.0.0, fixed in Ruby 2.1.0
-# https://bugs.ruby-lang.org/issues/8074
- at libdir_basename = "lib" if RUBY_VERSION < '2.1.0'
-
-#
 # main
 #
 
@@ -400,15 +392,15 @@ when arg_config('--clean')
   do_clean
 end
 
+if openbsd? && !using_system_libraries?
+  ENV['CC'] ||= find_executable('egcc') or
+    abort "Please install gcc 4.9+ from ports using `pkg_add -v gcc`"
+end
+
 RbConfig::MAKEFILE_CONFIG['CC'] = ENV['CC'] if ENV['CC']
 # use same c compiler for libxml and libxslt
 ENV['CC'] = RbConfig::MAKEFILE_CONFIG['CC']
 
-# TODO: deprecate MacRuby: https://github.com/sparklemotion/nokogiri/issues/1474
-if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'macruby'
-  $LIBRUBYARG_STATIC.gsub!(/-static/, '')
-end
-
 $LIBS << " #{ENV["LIBS"]}"
 
 # Read CFLAGS from ENV and make sure compiling works.
@@ -465,7 +457,7 @@ else
   # The gem version constraint in the Rakefile is not respected at install time.
   # Keep this version in sync with the one in the Rakefile !
   require 'rubygems'
-  gem 'mini_portile2', '~> 2.1.0'
+  gem 'mini_portile2', '~> 2.2.0'
   require 'mini_portile2'
   message "Using mini_portile version #{MiniPortile::VERSION}\n"
 
@@ -482,8 +474,8 @@ else
   if cross_build_p || windows?
     zlib_recipe = process_recipe("zlib", dependencies["zlib"]["version"], static_p, cross_build_p) do |recipe|
       recipe.files = [{
-          url: "http://zlib.net/#{recipe.name}-#{recipe.version}.tar.gz",
-          md5: dependencies["zlib"]["md5"]
+          url: "http://zlib.net/fossils/#{recipe.name}-#{recipe.version}.tar.gz",
+          sha256: dependencies["zlib"]["sha256"]
         }]
       class << recipe
         attr_accessor :cross_build_p
@@ -521,7 +513,7 @@ else
     libiconv_recipe = process_recipe("libiconv", dependencies["libiconv"]["version"], static_p, cross_build_p) do |recipe|
       recipe.files = [{
           url: "http://ftp.gnu.org/pub/gnu/libiconv/#{recipe.name}-#{recipe.version}.tar.gz",
-          md5: dependencies["libiconv"]["md5"]
+          sha256: dependencies["libiconv"]["sha256"]
         }]
       recipe.configure_options += [
         "CPPFLAGS=-Wall",
@@ -556,7 +548,7 @@ EOM
   libxml2_recipe = process_recipe("libxml2", dependencies["libxml2"]["version"], static_p, cross_build_p) do |recipe|
     recipe.files = [{
         url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
-        md5: dependencies["libxml2"]["md5"]
+        sha256: dependencies["libxml2"]["sha256"]
       }]
     recipe.configure_options += [
       "--without-python",
@@ -572,7 +564,7 @@ EOM
   libxslt_recipe = process_recipe("libxslt", dependencies["libxslt"]["version"], static_p, cross_build_p) do |recipe|
     recipe.files = [{
         url: "http://xmlsoft.org/sources/#{recipe.name}-#{recipe.version}.tar.gz",
-        md5: dependencies["libxslt"]["md5"]
+        sha256: dependencies["libxslt"]["sha256"]
       }]
     recipe.configure_options += [
       "--without-python",
@@ -666,12 +658,6 @@ have_func('xmlRelaxNGSetValidStructuredErrors')
 have_func('xmlSchemaSetValidStructuredErrors')
 have_func('xmlSchemaSetParserStructuredErrors')
 
-if ENV['CPUPROFILE']
-  unless find_library('profiler', 'ProfilerEnable', *LIB_DIRS)
-    abort "google performance tools are not installed"
-  end
-end
-
 create_makefile('nokogiri/nokogiri')
 
 if enable_config('clean', true)
diff --git a/ext/nokogiri/nokogiri.c b/ext/nokogiri/nokogiri.c
index bbd79ad..d4dedee 100644
--- a/ext/nokogiri/nokogiri.c
+++ b/ext/nokogiri/nokogiri.c
@@ -36,10 +36,8 @@ void vasprintf_free (void *p)
 #ifdef HAVE_RUBY_UTIL_H
 #include "ruby/util.h"
 #else
-#ifndef __MACRUBY__
 #include "util.h"
 #endif
-#endif
 
 void nokogiri_root_node(xmlNodePtr node)
 {
@@ -63,14 +61,12 @@ void nokogiri_root_nsdef(xmlNsPtr ns, xmlDocPtr doc)
 
 void Init_nokogiri()
 {
-#ifndef __MACRUBY__
   xmlMemSetup(
       (xmlFreeFunc)ruby_xfree,
       (xmlMallocFunc)ruby_xmalloc,
       (xmlReallocFunc)ruby_xrealloc,
       ruby_strdup
   );
-#endif
 
   mNokogiri         = rb_define_module("Nokogiri");
   mNokogiriXml      = rb_define_module_under(mNokogiri, "XML");
diff --git a/ext/nokogiri/nokogiri.h b/ext/nokogiri/nokogiri.h
index f2b407c..a018519 100644
--- a/ext/nokogiri/nokogiri.h
+++ b/ext/nokogiri/nokogiri.h
@@ -34,16 +34,6 @@ int vasprintf (char **strp, const char *fmt, va_list ap);
 #include <ruby/st.h>
 #include <ruby/encoding.h>
 
-#ifndef UNUSED
-# if defined(__GNUC__)
-#  define MAYBE_UNUSED(name) name __attribute__((unused))
-#  define UNUSED(name) MAYBE_UNUSED(UNUSED_ ## name)
-# else
-#  define MAYBE_UNUSED(name) name
-#  define UNUSED(name) name
-# endif
-#endif
-
 #ifndef NORETURN
 # if defined(__GNUC__)
 #  define NORETURN(name) __attribute__((noreturn)) name
diff --git a/ext/nokogiri/xml_attr.c b/ext/nokogiri/xml_attr.c
index ed5345a..1e1e1de 100644
--- a/ext/nokogiri/xml_attr.c
+++ b/ext/nokogiri/xml_attr.c
@@ -11,11 +11,11 @@ static VALUE set_value(VALUE self, VALUE content)
   xmlAttrPtr attr;
   Data_Get_Struct(self, xmlAttr, attr);
 
-  if(attr->children) xmlFreeNodeList(attr->children);
+  if (attr->children) { xmlFreeNodeList(attr->children); }
 
   attr->children = attr->last = NULL;
 
-  if(content) {
+  if (content) {
     xmlChar *buffer;
     xmlNode *tmp;
 
@@ -30,7 +30,7 @@ static VALUE set_value(VALUE self, VALUE content)
     for(tmp = attr->children; tmp; tmp = tmp->next) {
       tmp->parent = (xmlNode *)attr;
       tmp->doc = attr->doc;
-      if(tmp->next == NULL) attr->last = tmp;
+      if (tmp->next == NULL) { attr->last = tmp; }
     }
 
     /* Free up memory */
@@ -57,20 +57,24 @@ static VALUE new(int argc, VALUE *argv, VALUE klass)
 
   rb_scan_args(argc, argv, "2*", &document, &name, &rest);
 
+  if (! rb_obj_is_kind_of(document, cNokogiriXmlDocument)) {
+    rb_raise(rb_eArgError, "parameter must be a Nokogiri::XML::Document");
+  }
+
   Data_Get_Struct(document, xmlDoc, xml_doc);
 
   node = xmlNewDocProp(
-      xml_doc,
-      (const xmlChar *)StringValueCStr(name),
-      NULL
-  );
+           xml_doc,
+           (const xmlChar *)StringValueCStr(name),
+           NULL
+         );
 
   nokogiri_root_node((xmlNodePtr)node);
 
   rb_node = Nokogiri_wrap_xml_node(klass, (xmlNodePtr)node);
   rb_obj_call_init(rb_node, argc, argv);
 
-  if(rb_block_given_p()) rb_yield(rb_node);
+  if (rb_block_given_p()) { rb_yield(rb_node); }
 
   return rb_node;
 }
diff --git a/ext/nokogiri/xml_node.c b/ext/nokogiri/xml_node.c
index caaa49e..9bdef4d 100644
--- a/ext/nokogiri/xml_node.c
+++ b/ext/nokogiri/xml_node.c
@@ -833,37 +833,40 @@ static VALUE set(VALUE self, VALUE property, VALUE value)
 static VALUE get(VALUE self, VALUE rattribute)
 {
   xmlNodePtr node;
-  xmlChar* value = 0;
-  VALUE rvalue ;
-  char* attribute = 0;
-  char *colon = 0, *attr_name = 0, *prefix = 0;
+  const xmlChar *value = 0;
+  VALUE rvalue;
+  xmlChar *colon;
+  const xmlChar *attribute, *attr_name, *prefix;
   xmlNsPtr ns;
 
   if (NIL_P(rattribute)) return Qnil;
 
   Data_Get_Struct(self, xmlNode, node);
-  attribute = strdup(StringValueCStr(rattribute));
+  attribute = xmlCharStrdup(StringValueCStr(rattribute));
 
-  colon = strchr(attribute, ':');
+  colon = (xmlChar *)xmlStrchr(attribute, (const xmlChar)':');
   if (colon) {
-    (*colon) = 0 ; /* create two null-terminated strings of the prefix and attribute name */
-    prefix = attribute ;
-    attr_name = colon + 1 ;
-    ns = xmlSearchNs(node->doc, node, (const xmlChar *)(prefix));
+    /* split the attribute string into separate prefix and name by
+     * null-terminating the prefix at the colon */
+    prefix = attribute;
+    attr_name = colon + 1;
+    (*colon) = 0;
+
+    ns = xmlSearchNs(node->doc, node, prefix);
     if (ns) {
-      value = xmlGetNsProp(node, (xmlChar*)(attr_name), ns->href);
+      value = xmlGetNsProp(node, attr_name, ns->href);
     } else {
       value = xmlGetProp(node, (xmlChar*)StringValueCStr(rattribute));
     }
   } else {
-    value = xmlGetNoNsProp(node, (xmlChar*)attribute);
+    value = xmlGetNoNsProp(node, attribute);
   }
 
-  free(attribute);
+  xmlFree((void *)attribute);
   if (!value) return Qnil;
 
   rvalue = NOKOGIRI_STR_NEW2(value);
-  xmlFree(value);
+  xmlFree((void *)value);
 
   return rvalue ;
 }
diff --git a/ext/nokogiri/xml_sax_push_parser.c b/ext/nokogiri/xml_sax_push_parser.c
index f6107f2..dac0a24 100644
--- a/ext/nokogiri/xml_sax_push_parser.c
+++ b/ext/nokogiri/xml_sax_push_parser.c
@@ -3,7 +3,7 @@
 static void deallocate(xmlParserCtxtPtr ctx)
 {
   NOKOGIRI_DEBUG_START(ctx);
-  if(ctx != NULL) {
+  if (ctx != NULL) {
     NOKOGIRI_SAX_TUPLE_DESTROY(ctx->userData);
     xmlFreeParserCtxt(ctx);
   }
@@ -30,12 +30,12 @@ static VALUE native_write(VALUE self, VALUE _chunk, VALUE _last_chunk)
 
   Data_Get_Struct(self, xmlParserCtxt, ctx);
 
-  if(Qnil != _chunk) {
+  if (Qnil != _chunk) {
     chunk = StringValuePtr(_chunk);
     size = (int)RSTRING_LEN(_chunk);
   }
 
-  if(xmlParseChunk(ctx, chunk, size, Qtrue == _last_chunk ? 1 : 0)) {
+  if (xmlParseChunk(ctx, chunk, size, Qtrue == _last_chunk ? 1 : 0)) {
     if (!(ctx->options & XML_PARSE_RECOVER)) {
       xmlErrorPtr e = xmlCtxtGetLastError(ctx);
       Nokogiri_error_raise(NULL, e);
@@ -59,17 +59,18 @@ static VALUE initialize_native(VALUE self, VALUE _xml_sax, VALUE _filename)
 
   Data_Get_Struct(_xml_sax, xmlSAXHandler, sax);
 
-  if(_filename != Qnil) filename = StringValueCStr(_filename);
+  if (_filename != Qnil) { filename = StringValueCStr(_filename); }
 
   ctx = xmlCreatePushParserCtxt(
-      sax,
-      NULL,
-      NULL,
-      0,
-      filename
-  );
-  if(ctx == NULL)
+          sax,
+          NULL,
+          NULL,
+          0,
+          filename
+        );
+  if (ctx == NULL) {
     rb_raise(rb_eRuntimeError, "Could not create a parser context");
+  }
 
   ctx->userData = NOKOGIRI_SAX_TUPLE_NEW(ctx, self);
 
@@ -91,12 +92,53 @@ static VALUE set_options(VALUE self, VALUE options)
   xmlParserCtxtPtr ctx;
   Data_Get_Struct(self, xmlParserCtxt, ctx);
 
-  if (xmlCtxtUseOptions(ctx, (int)NUM2INT(options)) != 0)
+  if (xmlCtxtUseOptions(ctx, (int)NUM2INT(options)) != 0) {
     rb_raise(rb_eRuntimeError, "Cannot set XML parser context options");
+  }
 
   return Qnil;
 }
 
+/*
+ * call-seq:
+ *  replace_entities
+ *
+ * Should this parser replace entities?  & will get converted to '&' if
+ * set to true
+ */
+static VALUE get_replace_entities(VALUE self)
+{
+  xmlParserCtxtPtr ctx;
+  Data_Get_Struct(self, xmlParserCtxt, ctx);
+
+  if (0 == ctx->replaceEntities) {
+    return Qfalse;
+  } else {
+    return Qtrue;
+  }
+}
+
+/*
+ * call-seq:
+ *  replace_entities=(boolean)
+ *
+ * Should this parser replace entities?  & will get converted to '&' if
+ * set to true
+ */
+static VALUE set_replace_entities(VALUE self, VALUE value)
+{
+  xmlParserCtxtPtr ctx;
+  Data_Get_Struct(self, xmlParserCtxt, ctx);
+
+  if (Qfalse == value) {
+    ctx->replaceEntities = 0;
+  } else {
+    ctx->replaceEntities = 1;
+  }
+
+  return value;
+}
+
 VALUE cNokogiriXmlSaxPushParser ;
 void init_xml_sax_push_parser()
 {
@@ -112,4 +154,6 @@ void init_xml_sax_push_parser()
   rb_define_private_method(klass, "native_write", native_write, 2);
   rb_define_method(klass, "options", get_options, 0);
   rb_define_method(klass, "options=", set_options, 1);
+  rb_define_method(klass, "replace_entities", get_replace_entities, 0);
+  rb_define_method(klass, "replace_entities=", set_replace_entities, 1);
 }
diff --git a/lib/nokogiri.rb b/lib/nokogiri.rb
index 47b3c26..f86536e 100644
--- a/lib/nokogiri.rb
+++ b/lib/nokogiri.rb
@@ -26,7 +26,7 @@ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
 end
 
 begin
-  RUBY_VERSION =~ /(\d+.\d+)/
+  RUBY_VERSION =~ /(\d+\.\d+)/
   require "nokogiri/#{$1}/nokogiri"
 rescue LoadError
   require 'nokogiri/nokogiri'
diff --git a/lib/nokogiri/html/document.rb b/lib/nokogiri/html/document.rb
index c9693ed..d3792bc 100644
--- a/lib/nokogiri/html/document.rb
+++ b/lib/nokogiri/html/document.rb
@@ -161,7 +161,7 @@ module Nokogiri
         # Nokogiri::XML::ParseOptions.
         def parse string_or_io, url = nil, encoding = nil, options = XML::ParseOptions::DEFAULT_HTML
 
-          options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
+          options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
           # Give the options to the user
           yield options if block_given?
 
diff --git a/lib/nokogiri/html/sax/parser.rb b/lib/nokogiri/html/sax/parser.rb
index b69c45f..2c3c2ef 100644
--- a/lib/nokogiri/html/sax/parser.rb
+++ b/lib/nokogiri/html/sax/parser.rb
@@ -37,6 +37,16 @@ module Nokogiri
         end
 
         ###
+        # Parse given +io+
+        def parse_io io, encoding = 'UTF-8'
+          check_encoding(encoding)
+          @encoding = encoding
+          ctx = ParserContext.io(io, ENCODINGS[encoding])
+          yield ctx if block_given?
+          ctx.parse_with self
+        end
+
+        ###
         # Parse a file with +filename+
         def parse_file filename, encoding = 'UTF-8'
           raise ArgumentError unless filename
diff --git a/lib/nokogiri/version.rb b/lib/nokogiri/version.rb
index ba84a31..d92e7a0 100644
--- a/lib/nokogiri/version.rb
+++ b/lib/nokogiri/version.rb
@@ -1,6 +1,6 @@
 module Nokogiri
   # The version of Nokogiri you are using
-  VERSION = '1.6.8.1'
+  VERSION = '1.8.0'
 
   class VersionInfo # :nodoc:
     def jruby?
@@ -12,9 +12,10 @@ module Nokogiri
     end
 
     def loaded_parser_version
-      LIBXML_PARSER_VERSION.scan(/^(\d+)(\d\d)(\d\d)(?!\d)/).first.collect{ |j|
-        j.to_i
-      }.join(".")
+      LIBXML_PARSER_VERSION.
+        scan(/^(\d+)(\d\d)(\d\d)(?!\d)/).first.
+        collect(&:to_i).
+        join(".")
     end
 
     def compiled_parser_version
diff --git a/lib/nokogiri/xml.rb b/lib/nokogiri/xml.rb
index b391f01..a298e74 100644
--- a/lib/nokogiri/xml.rb
+++ b/lib/nokogiri/xml.rb
@@ -48,7 +48,7 @@ module Nokogiri
       # Nokogiri::XML::Reader for mor information
       def Reader string_or_io, url = nil, encoding = nil, options = ParseOptions::STRICT
 
-        options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
+        options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
         # Give the options to the user
         yield options if block_given?
 
diff --git a/lib/nokogiri/xml/document.rb b/lib/nokogiri/xml/document.rb
index ee4119b..71a94ff 100644
--- a/lib/nokogiri/xml/document.rb
+++ b/lib/nokogiri/xml/document.rb
@@ -33,15 +33,16 @@ module Nokogiri
       # +block+ (optional) is passed a configuration object on which
       # parse options may be set.
       #
-      # When parsing untrusted documents, it's recommended that the
-      # +nonet+ option be used, as shown in this example code:
-      #
-      #   Nokogiri::XML::Document.parse(xml_string) { |config| config.nonet }
+      # By default, Nokogiri treats documents as untrusted, and so
+      # does not attempt to load DTDs or access the network. See
+      # Nokogiri::XML::ParseOptions for a complete list of options;
+      # and that module's DEFAULT_XML constant for what's set (and not
+      # set) by default.
       #
       # Nokogiri.XML() is a convenience method which will call this method.
       #
       def self.parse string_or_io, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML, &block
-        options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
+        options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
         # Give the options to the user
         yield options if block_given?
 
@@ -239,10 +240,10 @@ module Nokogiri
       undef_method :namespace_definitions, :line, :add_namespace
 
       def add_child node_or_tags
-        raise "Document already has a root node" if root && root.name != 'nokogiri_text_wrapper'
+        raise "A document may not have multiple root nodes." if (root && root.name != 'nokogiri_text_wrapper') && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
         node_or_tags = coerce(node_or_tags)
         if node_or_tags.is_a?(XML::NodeSet)
-          raise "Document cannot have multiple root nodes" if node_or_tags.size > 1
+          raise "A document may not have multiple root nodes." if node_or_tags.size > 1
           super(node_or_tags.first)
         else
           super
@@ -273,9 +274,8 @@ module Nokogiri
           (string_or_io.respond_to?(:eof?) && string_or_io.eof?)
       end
 
-      def implied_xpath_contexts # :nodoc:
-        ["//"]
-      end
+      # @private
+      IMPLIED_XPATH_CONTEXTS = [ '//'.freeze ].freeze # :nodoc:
 
       def inspect_attributes
         [:name, :children]
diff --git a/lib/nokogiri/xml/node.rb b/lib/nokogiri/xml/node.rb
index a381bcf..6e2bd76 100644
--- a/lib/nokogiri/xml/node.rb
+++ b/lib/nokogiri/xml/node.rb
@@ -154,7 +154,7 @@ module Nokogiri
       def prepend_child node_or_tags
         if first = children.first
           # Mimic the error add_child would raise.
-          raise RuntimeError, "Document already has a root node" if document? && !node_or_tags.processing_instruction?
+          raise RuntimeError, "Document already has a root node" if document? && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
           first.__send__(:add_sibling, :previous, node_or_tags)
         else
           add_child(node_or_tags)
@@ -172,6 +172,7 @@ module Nokogiri
         add_child node_or_tags
         self
       end
+
       ###
       # Insert +node_or_tags+ before this Node (as a sibling).
       # +node_or_tags+ can be a Nokogiri::XML::Node, a ::DocumentFragment, a ::NodeSet, or a string containing markup.
@@ -180,7 +181,7 @@ module Nokogiri
       #
       # Also see related method +before+.
       def add_previous_sibling node_or_tags
-        raise ArgumentError.new("A document may not have multiple root nodes.") if (parent && parent.document?) && !node_or_tags.processing_instruction?
+        raise ArgumentError.new("A document may not have multiple root nodes.") if (parent && parent.document?) && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
 
         add_sibling :previous, node_or_tags
       end
@@ -193,7 +194,7 @@ module Nokogiri
       #
       # Also see related method +after+.
       def add_next_sibling node_or_tags
-        raise ArgumentError.new("A document may not have multiple root nodes.") if (parent && parent.document?) && !node_or_tags.processing_instruction?
+        raise ArgumentError.new("A document may not have multiple root nodes.") if (parent && parent.document?) && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
 
         add_sibling :next, node_or_tags
       end
@@ -387,7 +388,7 @@ module Nokogiri
         end
 
         options ||= (document.html? ? ParseOptions::DEFAULT_HTML : ParseOptions::DEFAULT_XML)
-        if Fixnum === options
+        if Integer === options
           options = Nokogiri::XML::ParseOptions.new(options)
         end
         # Give the options to the user
@@ -622,7 +623,7 @@ module Nokogiri
         encoding = options[:encoding] || document.encoding
         options[:encoding] = encoding
 
-        outstring = ""
+        outstring = String.new
         if encoding && outstring.respond_to?(:force_encoding)
           outstring.force_encoding(Encoding.find(encoding))
         end
@@ -739,7 +740,7 @@ module Nokogiri
       # Nokogiri::XML::ParseOptions object initialized from +options+, will be
       # passed to it, allowing more convenient modification of the parser options.
       def do_xinclude options = XML::ParseOptions::DEFAULT_XML, &block
-        options = Nokogiri::XML::ParseOptions.new(options) if Fixnum === options
+        options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
 
         # give options to user
         yield options if block_given?
@@ -818,9 +819,8 @@ Requires a Node, NodeSet or String argument, and cannot accept a #{data.class}.
         EOERR
       end
 
-      def implied_xpath_contexts # :nodoc:
-        [".//"]
-      end
+      # @private
+      IMPLIED_XPATH_CONTEXTS = [ './/'.freeze ].freeze # :nodoc:
 
       def add_child_node_and_reparent_attrs node # :nodoc:
         add_child_node node
diff --git a/lib/nokogiri/xml/node_set.rb b/lib/nokogiri/xml/node_set.rb
index f66829d..9871825 100644
--- a/lib/nokogiri/xml/node_set.rb
+++ b/lib/nokogiri/xml/node_set.rb
@@ -11,6 +11,8 @@ module Nokogiri
       # The Document this NodeSet is associated with
       attr_accessor :document
 
+      alias :clone :dup
+
       # Create a NodeSet with +document+ defaulting to +list+
       def initialize document, list = []
         @document = document
@@ -71,9 +73,10 @@ module Nokogiri
       # For more information see Nokogiri::XML::Searchable#css
       def css *args
         rules, handler, ns, _ = extract_params(args)
+        paths = css_rules_to_xpath(rules, ns)
 
         inject(NodeSet.new(document)) do |set, node|
-          set += css_internal node, rules, handler, ns
+          set + xpath_internal(node, paths, handler, ns, nil)
         end
       end
 
@@ -88,7 +91,7 @@ module Nokogiri
         paths, handler, ns, binds = extract_params(args)
 
         inject(NodeSet.new(document)) do |set, node|
-          set += node.xpath(*(paths + [ns, handler, binds].compact))
+          set + xpath_internal(node, paths, handler, ns, binds)
         end
       end
 
@@ -190,6 +193,17 @@ module Nokogiri
 
       ###
       # Get the inner text of all contained Node objects
+      #
+      # Note: This joins the text of all Node objects in the NodeSet:
+      #
+      #    doc = Nokogiri::XML('<xml><a><d>foo</d><d>bar</d></a></xml>')
+      #    doc.css('d').text # => "foobar"
+      #
+      # Instead, if you want to return the text of all nodes in the NodeSet:
+      #
+      #    doc.css('d').map(&:text) # => ["foo", "bar"]
+      #
+      # See Nokogiri::XML::Node#content for more information.
       def inner_text
         collect(&:inner_text).join('')
       end
@@ -279,7 +293,11 @@ module Nokogiri
       # Returns a new NodeSet containing all the children of all the nodes in
       # the NodeSet
       def children
-        inject(NodeSet.new(document)) { |set, node| set += node.children }
+        node_set = NodeSet.new(document)
+        each do |node|
+          node.children.each { |n| node_set.push(n) }
+        end
+        node_set
       end
 
       ###
@@ -301,11 +319,9 @@ module Nokogiri
 
       alias :+ :|
 
-      private
+      # @private
+      IMPLIED_XPATH_CONTEXTS = [ './/'.freeze, 'self::'.freeze ].freeze # :nodoc:
 
-      def implied_xpath_contexts # :nodoc:
-        [".//", "self::"]
-      end
     end
   end
 end
diff --git a/lib/nokogiri/xml/parse_options.rb b/lib/nokogiri/xml/parse_options.rb
index 9533632..8969578 100644
--- a/lib/nokogiri/xml/parse_options.rb
+++ b/lib/nokogiri/xml/parse_options.rb
@@ -7,11 +7,11 @@ module Nokogiri
     # You can build your own combinations of these parse options by using any of the following methods:
     # *Note*: All examples attempt to set the +RECOVER+ & +NOENT+ options. All examples use Ruby 2 optional parameter syntax.
     # [Ruby's bitwise operators] You can use the Ruby bitwise operators to set various combinations.
-    #   <code>Nokogiri.XML('<content>Chapter 1</content', options: Nokogiri::XML::ParseOptions.new((1 << 0) | (1 << 1)))</code>
+    #   Nokogiri.XML('<content>Chapter 1</content', options: Nokogiri::XML::ParseOptions.new((1 << 0) | (1 << 1)))
     # [Method chaining] Every option has an equivalent method in lowercase. You can chain these methods together to set various combinations.
-    #   <code>Nokogiri.XML('<content>Chapter 1</content', options: Nokogiri::XML::ParseOptions.new.recover.noent)</code>
+    #   Nokogiri.XML('<content>Chapter 1</content', options: Nokogiri::XML::ParseOptions.new.recover.noent)
     # [Using Ruby Blocks] You can also setup parse combinations in the block passed to Nokogiri.XML or Nokogiri.HTML
-    #   <code>Nokogiri.XML('<content>Chapter 1</content') {|config| config.recover.noent}</code>
+    #   Nokogiri.XML('<content>Chapter 1</content') {|config| config.recover.noent}
     #
     # == Removing particular parse options
     # You can also remove options from an instance of +ParseOptions+ dynamically.
diff --git a/lib/nokogiri/xml/sax/parser.rb b/lib/nokogiri/xml/sax/parser.rb
index 4c306a9..43f68f5 100644
--- a/lib/nokogiri/xml/sax/parser.rb
+++ b/lib/nokogiri/xml/sax/parser.rb
@@ -68,8 +68,7 @@ module Nokogiri
 
         # Create a new Parser with +doc+ and +encoding+
         def initialize doc = Nokogiri::XML::SAX::Document.new, encoding = 'UTF-8'
-          check_encoding(encoding)
-          @encoding = encoding
+          @encoding = check_encoding(encoding)
           @document = doc
           @warned   = false
         end
@@ -88,9 +87,8 @@ module Nokogiri
         ###
         # Parse given +io+
         def parse_io io, encoding = 'ASCII'
-          check_encoding(encoding)
-          @encoding = encoding
-          ctx = ParserContext.io(io, ENCODINGS[encoding])
+          @encoding = check_encoding(encoding)
+          ctx = ParserContext.io(io, ENCODINGS[@encoding])
           yield ctx if block_given?
           ctx.parse_with self
         end
@@ -114,8 +112,9 @@ module Nokogiri
 
         private
         def check_encoding(encoding)
-          encoding.upcase!
-          raise ArgumentError.new("'#{encoding}' is not a valid encoding") unless ENCODINGS[encoding]
+          encoding.upcase.tap do |enc|
+            raise ArgumentError.new("'#{enc}' is not a valid encoding") unless ENCODINGS[enc]
+          end
         end
       end
     end
diff --git a/lib/nokogiri/xml/searchable.rb b/lib/nokogiri/xml/searchable.rb
index 726d228..1b49005 100644
--- a/lib/nokogiri/xml/searchable.rb
+++ b/lib/nokogiri/xml/searchable.rb
@@ -149,30 +149,9 @@ module Nokogiri
       #   }.new)
       #
       def xpath *args
-        return NodeSet.new(document) unless document
-
         paths, handler, ns, binds = extract_params(args)
 
-        sets = paths.map do |path|
-          ctx = XPathContext.new(self)
-          ctx.register_namespaces(ns)
-          path = path.gsub(/xmlns:/, ' :') unless Nokogiri.uses_libxml?
-
-          binds.each do |key,value|
-            ctx.register_variable key.to_s, value
-          end if binds
-
-          ctx.evaluate(path, handler)
-        end
-        return sets.first if sets.length == 1
-
-        NodeSet.new(document) do |combined|
-          sets.each do |set|
-            set.each do |node|
-              combined << node
-            end
-          end
-        end
+        xpath_internal self, paths, handler, ns, binds
       end
 
       ##
@@ -189,12 +168,42 @@ module Nokogiri
       private
 
       def css_internal node, rules, handler, ns
-        xpaths = rules.map { |rule| xpath_query_from_css_rule(rule, ns) }
-        node.xpath(*(xpaths + [ns, handler].compact))
+        xpath_internal node, css_rules_to_xpath(rules, ns), handler, ns, nil
+      end
+
+      def xpath_internal node, paths, handler, ns, binds
+        document = node.document
+        return NodeSet.new(document) unless document
+
+        if paths.length == 1
+          return xpath_impl(node, paths.first, handler, ns, binds)
+        end
+
+        NodeSet.new(document) do |combined|
+          paths.each do |path|
+            xpath_impl(node, path, handler, ns, binds).each { |set| combined << set }
+          end
+        end
+      end
+
+      def xpath_impl node, path, handler, ns, binds
+        ctx = XPathContext.new(node)
+        ctx.register_namespaces(ns)
+        path = path.gsub(/xmlns:/, ' :') unless Nokogiri.uses_libxml?
+
+        binds.each do |key,value|
+          ctx.register_variable key.to_s, value
+        end if binds
+
+        ctx.evaluate(path, handler)
+      end
+
+      def css_rules_to_xpath(rules, ns)
+        rules.map { |rule| xpath_query_from_css_rule(rule, ns) }
       end
 
       def xpath_query_from_css_rule rule, ns
-        implied_xpath_contexts.map do |implied_xpath_context|
+        self.class::IMPLIED_XPATH_CONTEXTS.map do |implied_xpath_context|
           CSS.xpath_for(rule.to_s, :prefix => implied_xpath_context, :ns => ns)
         end.join(' | ')
       end
diff --git a/lib/nokogiri/xml/syntax_error.rb b/lib/nokogiri/xml/syntax_error.rb
index 4121ebe..65adbef 100644
--- a/lib/nokogiri/xml/syntax_error.rb
+++ b/lib/nokogiri/xml/syntax_error.rb
@@ -40,7 +40,30 @@ module Nokogiri
       end
 
       def to_s
-        super.chomp
+        message = super.chomp
+        [location_to_s, level_to_s, message].
+          compact.join(": ").
+          force_encoding(message.encoding)
+      end
+
+      private
+
+      def level_to_s
+        case level
+        when 3 then "FATAL"
+        when 2 then "ERROR"
+        when 1 then "WARNING"
+        else nil
+        end
+      end
+
+      def nil_or_zero?(attribute)
+        attribute.nil? || attribute.zero?
+      end
+
+      def location_to_s
+        return nil if nil_or_zero?(line) && nil_or_zero?(column)
+        "#{line}:#{column}"
       end
     end
   end
diff --git a/nokogiri.gemspec b/nokogiri.gemspec
index 3c418ef..3a23bc0 100644
--- a/nokogiri.gemspec
+++ b/nokogiri.gemspec
@@ -5,22 +5,22 @@
 
 Gem::Specification.new do |s|
   s.name = "nokogiri"
-  s.version = "1.6.8.1"
+  s.version = "1.8.0"
 
   s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
   s.authors = ["Aaron Patterson", "Mike Dalessio", "Yoko Harada", "Tim Elliott", "Akinori MUSHA"]
-  s.date = "2016-10-03"
+  s.date = "2017-06-05"
   s.description = "Nokogiri (\u{92f8}) is an HTML, XML, SAX, and Reader parser.  Among\nNokogiri's many features is the ability to search documents via XPath\nor CSS3 selectors."
   s.email = ["aaronp at rubyforge.org", "mike.dalessio at gmail.com", "yokolet at gmail.com", "tle at holymonkey.com", "knu at idaemons.org"]
   s.executables = ["nokogiri"]
   s.extensions = ["ext/nokogiri/extconf.rb"]
-  s.extra_rdoc_files = ["CHANGELOG.rdoc", "CONTRIBUTING.md", "C_CODING_STYLE.rdoc", "LICENSE.txt", "Manifest.txt", "README.md", "ROADMAP.md", "STANDARD_RESPONSES.md", "Y_U_NO_GEMSPEC.md", "ext/nokogiri/html_document.c", "ext/nokogiri/html_element_description.c", "ext/nokogiri/html_entity_lookup.c", "ext/nokogiri/html_sax_parser_context.c", "ext/nokogiri/html_sax_push_parser.c", "ext/nokogiri/nokogiri.c", "ext/nokogiri/xml_attr.c", "ext/nokogiri/xml_attribute_decl.c", "ext/nokogiri/xml_cd [...]
-  s.files = [".autotest", ".cross_rubies", ".editorconfig", ".gemtest", ".travis.yml", "CHANGELOG.rdoc", "CONTRIBUTING.md", "C_CODING_STYLE.rdoc", "Gemfile", "LICENSE.txt", "Manifest.txt", "README.md", "ROADMAP.md", "Rakefile", "STANDARD_RESPONSES.md", "Y_U_NO_GEMSPEC.md", "appveyor.yml", "bin/nokogiri", "build_all", "dependencies.yml", "ext/nokogiri/depend", "ext/nokogiri/extconf.rb", "ext/nokogiri/html_document.c", "ext/nokogiri/html_document.h", "ext/nokogiri/html_element_description. [...]
+  s.extra_rdoc_files = ["CHANGELOG.md", "CONTRIBUTING.md", "C_CODING_STYLE.rdoc", "LICENSE-DEPENDENCIES.md", "LICENSE.md", "Manifest.txt", "README.md", "ROADMAP.md", "STANDARD_RESPONSES.md", "Y_U_NO_GEMSPEC.md", "ext/nokogiri/html_document.c", "ext/nokogiri/html_element_description.c", "ext/nokogiri/html_entity_lookup.c", "ext/nokogiri/html_sax_parser_context.c", "ext/nokogiri/html_sax_push_parser.c", "ext/nokogiri/nokogiri.c", "ext/nokogiri/xml_attr.c", "ext/nokogiri/xml_attribute_decl. [...]
+  s.files = [".autotest", ".cross_rubies", ".editorconfig", ".gemtest", ".travis.yml", "CHANGELOG.md", "CONTRIBUTING.md", "C_CODING_STYLE.rdoc", "Gemfile", "Gemfile-libxml-ruby", "LICENSE-DEPENDENCIES.md", "LICENSE.md", "Manifest.txt", "README.md", "ROADMAP.md", "Rakefile", "STANDARD_RESPONSES.md", "Y_U_NO_GEMSPEC.md", "appveyor.yml", "bin/nokogiri", "build_all", "dependencies.yml", "ext/nokogiri/depend", "ext/nokogiri/extconf.rb", "ext/nokogiri/html_document.c", "ext/nokogiri/html_docum [...]
   s.homepage = "http://nokogiri.org"
   s.licenses = ["MIT"]
   s.rdoc_options = ["--main", "README.md"]
   s.require_paths = ["lib"]
-  s.required_ruby_version = Gem::Requirement.new(">= 1.9.2")
+  s.required_ruby_version = Gem::Requirement.new(">= 2.1.0")
   s.rubygems_version = "1.8.23"
   s.summary = "Nokogiri (\u{92f8}) is an HTML, XML, SAX, and Reader parser"
 
@@ -28,46 +28,49 @@ Gem::Specification.new do |s|
     s.specification_version = 4
 
     if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
-      s.add_development_dependency(%q<hoe>, ["~> 3.15"])
+      s.add_development_dependency(%q<concourse>, ["~> 0.11"])
+      s.add_development_dependency(%q<hoe>, ["~> 3.16"])
       s.add_development_dependency(%q<hoe-bundler>, ["~> 1.2.0"])
-      s.add_development_dependency(%q<hoe-debugging>, ["~> 1.2.1"])
+      s.add_development_dependency(%q<hoe-debugging>, ["~> 1.3.0"])
       s.add_development_dependency(%q<hoe-gemspec>, ["~> 1.0.0"])
       s.add_development_dependency(%q<hoe-git>, ["~> 1.6.0"])
-      s.add_runtime_dependency(%q<mini_portile2>, ["~> 2.1.0"])
+      s.add_runtime_dependency(%q<mini_portile2>, ["~> 2.2.0"])
       s.add_development_dependency(%q<minitest>, ["~> 5.8.4"])
       s.add_development_dependency(%q<racc>, ["~> 1.4.14"])
-      s.add_development_dependency(%q<rake>, ["~> 10.5.0"])
-      s.add_development_dependency(%q<rake-compiler>, ["~> 0.9.2"])
-      s.add_development_dependency(%q<rake-compiler-dock>, ["~> 0.5.1"])
+      s.add_development_dependency(%q<rake>, ["~> 12.0"])
+      s.add_development_dependency(%q<rake-compiler>, ["~> 1.0.3"])
+      s.add_development_dependency(%q<rake-compiler-dock>, ["~> 0.6.0"])
       s.add_development_dependency(%q<rdoc>, ["~> 4.0"])
       s.add_development_dependency(%q<rexical>, ["~> 1.0.5"])
     else
-      s.add_dependency(%q<hoe>, ["~> 3.15"])
+      s.add_dependency(%q<concourse>, ["~> 0.11"])
+      s.add_dependency(%q<hoe>, ["~> 3.16"])
       s.add_dependency(%q<hoe-bundler>, ["~> 1.2.0"])
-      s.add_dependency(%q<hoe-debugging>, ["~> 1.2.1"])
+      s.add_dependency(%q<hoe-debugging>, ["~> 1.3.0"])
       s.add_dependency(%q<hoe-gemspec>, ["~> 1.0.0"])
       s.add_dependency(%q<hoe-git>, ["~> 1.6.0"])
-      s.add_dependency(%q<mini_portile2>, ["~> 2.1.0"])
+      s.add_dependency(%q<mini_portile2>, ["~> 2.2.0"])
       s.add_dependency(%q<minitest>, ["~> 5.8.4"])
       s.add_dependency(%q<racc>, ["~> 1.4.14"])
-      s.add_dependency(%q<rake>, ["~> 10.5.0"])
-      s.add_dependency(%q<rake-compiler>, ["~> 0.9.2"])
-      s.add_dependency(%q<rake-compiler-dock>, ["~> 0.5.1"])
+      s.add_dependency(%q<rake>, ["~> 12.0"])
+      s.add_dependency(%q<rake-compiler>, ["~> 1.0.3"])
+      s.add_dependency(%q<rake-compiler-dock>, ["~> 0.6.0"])
       s.add_dependency(%q<rdoc>, ["~> 4.0"])
       s.add_dependency(%q<rexical>, ["~> 1.0.5"])
     end
   else
-    s.add_dependency(%q<hoe>, ["~> 3.15"])
+    s.add_dependency(%q<concourse>, ["~> 0.11"])
+    s.add_dependency(%q<hoe>, ["~> 3.16"])
     s.add_dependency(%q<hoe-bundler>, ["~> 1.2.0"])
-    s.add_dependency(%q<hoe-debugging>, ["~> 1.2.1"])
+    s.add_dependency(%q<hoe-debugging>, ["~> 1.3.0"])
     s.add_dependency(%q<hoe-gemspec>, ["~> 1.0.0"])
     s.add_dependency(%q<hoe-git>, ["~> 1.6.0"])
-    s.add_dependency(%q<mini_portile2>, ["~> 2.1.0"])
+    s.add_dependency(%q<mini_portile2>, ["~> 2.2.0"])
     s.add_dependency(%q<minitest>, ["~> 5.8.4"])
     s.add_dependency(%q<racc>, ["~> 1.4.14"])
-    s.add_dependency(%q<rake>, ["~> 10.5.0"])
-    s.add_dependency(%q<rake-compiler>, ["~> 0.9.2"])
-    s.add_dependency(%q<rake-compiler-dock>, ["~> 0.5.1"])
+    s.add_dependency(%q<rake>, ["~> 12.0"])
+    s.add_dependency(%q<rake-compiler>, ["~> 1.0.3"])
+    s.add_dependency(%q<rake-compiler-dock>, ["~> 0.6.0"])
     s.add_dependency(%q<rdoc>, ["~> 4.0"])
     s.add_dependency(%q<rexical>, ["~> 1.0.5"])
   end
diff --git a/patches/libxml2/0001-Fix-comparison-with-root-node-in-xmlXPathCmpNodes.patch b/patches/libxml2/0001-Fix-comparison-with-root-node-in-xmlXPathCmpNodes.patch
new file mode 100644
index 0000000..0dbca44
--- /dev/null
+++ b/patches/libxml2/0001-Fix-comparison-with-root-node-in-xmlXPathCmpNodes.patch
@@ -0,0 +1,34 @@
+From a005199330b86dada19d162cae15ef9bdcb6baa8 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer at aevum.de>
+Date: Tue, 28 Jun 2016 14:19:58 +0200
+Subject: [PATCH] Fix comparison with root node in xmlXPathCmpNodes
+
+This change has already been made in xmlXPathCmpNodesExt but not in
+xmlXPathCmpNodes.
+---
+ xpath.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/xpath.c b/xpath.c
+index 751665b..d992841 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -3342,13 +3342,13 @@ xmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
+      * compute depth to root
+      */
+     for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
+-	if (cur == node1)
++	if (cur->parent == node1)
+ 	    return(1);
+ 	depth2++;
+     }
+     root = cur;
+     for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
+-	if (cur == node2)
++	if (cur->parent == node2)
+ 	    return(-1);
+ 	depth1++;
+     }
+-- 
+2.9.3
+
diff --git a/patches/libxml2/0002-Fix-XPointer-paths-beginning-with-range-to.patch b/patches/libxml2/0002-Fix-XPointer-paths-beginning-with-range-to.patch
new file mode 100644
index 0000000..ae4f1eb
--- /dev/null
+++ b/patches/libxml2/0002-Fix-XPointer-paths-beginning-with-range-to.patch
@@ -0,0 +1,174 @@
+From 9ab01a277d71f54d3143c2cf333c5c2e9aaedd9e Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer at aevum.de>
+Date: Tue, 28 Jun 2016 14:22:23 +0200
+Subject: [PATCH] Fix XPointer paths beginning with range-to
+
+The old code would invoke the broken xmlXPtrRangeToFunction. range-to
+isn't really a function but a special kind of location step. Remove
+this function and always handle range-to in the XPath code.
+
+The old xmlXPtrRangeToFunction could also be abused to trigger a
+use-after-free error with the potential for remote code execution.
+
+Found with afl-fuzz.
+
+Fixes CVE-2016-5131.
+---
+ result/XPath/xptr/vidbase | 13 ++++++++
+ test/XPath/xptr/vidbase   |  1 +
+ xpath.c                   |  7 ++++-
+ xpointer.c                | 76 ++++-------------------------------------------
+ 4 files changed, 26 insertions(+), 71 deletions(-)
+
+diff --git a/result/XPath/xptr/vidbase b/result/XPath/xptr/vidbase
+index 8b9e92d..f19193e 100644
+--- a/result/XPath/xptr/vidbase
++++ b/result/XPath/xptr/vidbase
+@@ -17,3 +17,16 @@ Object is a Location Set:
+   To node
+     ELEMENT p
+ 
++
++========================
++Expression: xpointer(range-to(id('chapter2')))
++Object is a Location Set:
++1 :   Object is a range :
++  From node
++     /
++  To node
++    ELEMENT chapter
++      ATTRIBUTE id
++        TEXT
++          content=chapter2
++
+diff --git a/test/XPath/xptr/vidbase b/test/XPath/xptr/vidbase
+index b146383..884b106 100644
+--- a/test/XPath/xptr/vidbase
++++ b/test/XPath/xptr/vidbase
+@@ -1,2 +1,3 @@
+ xpointer(id('chapter1')/p)
+ xpointer(id('chapter1')/p[1]/range-to(following-sibling::p[2]))
++xpointer(range-to(id('chapter2')))
+diff --git a/xpath.c b/xpath.c
+index d992841..5a01b1b 100644
+--- a/xpath.c
++++ b/xpath.c
+@@ -10691,13 +10691,18 @@ xmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
+ 		    lc = 1;
+ 		    break;
+ 		} else if ((NXT(len) == '(')) {
+-		    /* Note Type or Function */
++		    /* Node Type or Function */
+ 		    if (xmlXPathIsNodeType(name)) {
+ #ifdef DEBUG_STEP
+ 		        xmlGenericError(xmlGenericErrorContext,
+ 				"PathExpr: Type search\n");
+ #endif
+ 			lc = 1;
++#ifdef LIBXML_XPTR_ENABLED
++                    } else if (ctxt->xptr &&
++                               xmlStrEqual(name, BAD_CAST "range-to")) {
++                        lc = 1;
++#endif
+ 		    } else {
+ #ifdef DEBUG_STEP
+ 		        xmlGenericError(xmlGenericErrorContext,
+diff --git a/xpointer.c b/xpointer.c
+index 676c510..d74174a 100644
+--- a/xpointer.c
++++ b/xpointer.c
+@@ -1332,8 +1332,6 @@ xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {
+     ret->here = here;
+     ret->origin = origin;
+ 
+-    xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
+-	                 xmlXPtrRangeToFunction);
+     xmlXPathRegisterFunc(ret, (xmlChar *)"range",
+ 	                 xmlXPtrRangeFunction);
+     xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
+@@ -2243,76 +2241,14 @@ xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+  * @nargs:  the number of args
+  *
+  * Implement the range-to() XPointer function
++ *
++ * Obsolete. range-to is not a real function but a special type of location
++ * step which is handled in xpath.c.
+  */
+ void
+-xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+-    xmlXPathObjectPtr range;
+-    const xmlChar *cur;
+-    xmlXPathObjectPtr res, obj;
+-    xmlXPathObjectPtr tmp;
+-    xmlLocationSetPtr newset = NULL;
+-    xmlNodeSetPtr oldset;
+-    int i;
+-
+-    if (ctxt == NULL) return;
+-    CHECK_ARITY(1);
+-    /*
+-     * Save the expression pointer since we will have to evaluate
+-     * it multiple times. Initialize the new set.
+-     */
+-    CHECK_TYPE(XPATH_NODESET);
+-    obj = valuePop(ctxt);
+-    oldset = obj->nodesetval;
+-    ctxt->context->node = NULL;
+-
+-    cur = ctxt->cur;
+-    newset = xmlXPtrLocationSetCreate(NULL);
+-
+-    for (i = 0; i < oldset->nodeNr; i++) {
+-	ctxt->cur = cur;
+-
+-	/*
+-	 * Run the evaluation with a node list made of a single item
+-	 * in the nodeset.
+-	 */
+-	ctxt->context->node = oldset->nodeTab[i];
+-	tmp = xmlXPathNewNodeSet(ctxt->context->node);
+-	valuePush(ctxt, tmp);
+-
+-	xmlXPathEvalExpr(ctxt);
+-	CHECK_ERROR;
+-
+-	/*
+-	 * The result of the evaluation need to be tested to
+-	 * decided whether the filter succeeded or not
+-	 */
+-	res = valuePop(ctxt);
+-	range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
+-	if (range != NULL) {
+-	    xmlXPtrLocationSetAdd(newset, range);
+-	}
+-
+-	/*
+-	 * Cleanup
+-	 */
+-	if (res != NULL)
+-	    xmlXPathFreeObject(res);
+-	if (ctxt->value == tmp) {
+-	    res = valuePop(ctxt);
+-	    xmlXPathFreeObject(res);
+-	}
+-
+-	ctxt->context->node = NULL;
+-    }
+-
+-    /*
+-     * The result is used as the new evaluation set.
+-     */
+-    xmlXPathFreeObject(obj);
+-    ctxt->context->node = NULL;
+-    ctxt->context->contextSize = -1;
+-    ctxt->context->proximityPosition = -1;
+-    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
++xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt,
++                       int nargs ATTRIBUTE_UNUSED) {
++    XP_ERROR(XPATH_EXPR_ERROR);
+ }
+ 
+ /**
+-- 
+2.9.3
+
diff --git a/patches/libxml2/0003-Disallow-namespace-nodes-in-XPointer-ranges.patch b/patches/libxml2/0003-Disallow-namespace-nodes-in-XPointer-ranges.patch
new file mode 100644
index 0000000..24bf328
--- /dev/null
+++ b/patches/libxml2/0003-Disallow-namespace-nodes-in-XPointer-ranges.patch
@@ -0,0 +1,249 @@
+From c1d1f7121194036608bf555f08d3062a36fd344b Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer at aevum.de>
+Date: Tue, 28 Jun 2016 18:34:52 +0200
+Subject: [PATCH] Disallow namespace nodes in XPointer ranges
+
+Namespace nodes must be copied to avoid use-after-free errors.
+But they don't necessarily have a physical representation in a
+document, so simply disallow them in XPointer ranges.
+
+Found with afl-fuzz.
+
+Fixes CVE-2016-4658.
+---
+ xpointer.c | 149 +++++++++++++++++++++++--------------------------------------
+ 1 file changed, 56 insertions(+), 93 deletions(-)
+
+diff --git a/xpointer.c b/xpointer.c
+index a7b03fb..694d120 100644
+--- a/xpointer.c
++++ b/xpointer.c
+@@ -319,6 +319,45 @@ xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
+     return(1);
+ }
+ 
++/**
++ * xmlXPtrNewRangeInternal:
++ * @start:  the starting node
++ * @startindex:  the start index
++ * @end:  the ending point
++ * @endindex:  the ending index
++ *
++ * Internal function to create a new xmlXPathObjectPtr of type range
++ *
++ * Returns the newly created object.
++ */
++static xmlXPathObjectPtr
++xmlXPtrNewRangeInternal(xmlNodePtr start, int startindex,
++                        xmlNodePtr end, int endindex) {
++    xmlXPathObjectPtr ret;
++
++    /*
++     * Namespace nodes must be copied (see xmlXPathNodeSetDupNs).
++     * Disallow them for now.
++     */
++    if ((start != NULL) && (start->type == XML_NAMESPACE_DECL))
++	return(NULL);
++    if ((end != NULL) && (end->type == XML_NAMESPACE_DECL))
++	return(NULL);
++
++    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
++    if (ret == NULL) {
++        xmlXPtrErrMemory("allocating range");
++	return(NULL);
++    }
++    memset(ret, 0, sizeof(xmlXPathObject));
++    ret->type = XPATH_RANGE;
++    ret->user = start;
++    ret->index = startindex;
++    ret->user2 = end;
++    ret->index2 = endindex;
++    return(ret);
++}
++
+ /**
+  * xmlXPtrNewRange:
+  * @start:  the starting node
+@@ -344,17 +383,7 @@ xmlXPtrNewRange(xmlNodePtr start, int startindex,
+     if (endindex < 0)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = startindex;
+-    ret->user2 = end;
+-    ret->index2 = endindex;
++    ret = xmlXPtrNewRangeInternal(start, startindex, end, endindex);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -381,17 +410,8 @@ xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
+     if (end->type != XPATH_POINT)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start->user;
+-    ret->index = start->index;
+-    ret->user2 = end->user;
+-    ret->index2 = end->index;
++    ret = xmlXPtrNewRangeInternal(start->user, start->index, end->user,
++                                  end->index);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -416,17 +436,7 @@ xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
+     if (start->type != XPATH_POINT)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start->user;
+-    ret->index = start->index;
+-    ret->user2 = end;
+-    ret->index2 = -1;
++    ret = xmlXPtrNewRangeInternal(start->user, start->index, end, -1);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -453,17 +463,7 @@ xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
+     if (end->type != XPATH_POINT)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = -1;
+-    ret->user2 = end->user;
+-    ret->index2 = end->index;
++    ret = xmlXPtrNewRangeInternal(start, -1, end->user, end->index);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -486,17 +486,7 @@ xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
+     if (end == NULL)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = -1;
+-    ret->user2 = end;
+-    ret->index2 = -1;
++    ret = xmlXPtrNewRangeInternal(start, -1, end, -1);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+@@ -516,17 +506,7 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
+     if (start == NULL)
+ 	return(NULL);
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = -1;
+-    ret->user2 = NULL;
+-    ret->index2 = -1;
++    ret = xmlXPtrNewRangeInternal(start, -1, NULL, -1);
+     return(ret);
+ }
+ 
+@@ -541,6 +521,8 @@ xmlXPtrNewCollapsedRange(xmlNodePtr start) {
+  */
+ xmlXPathObjectPtr
+ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
++    xmlNodePtr endNode;
++    int endIndex;
+     xmlXPathObjectPtr ret;
+ 
+     if (start == NULL)
+@@ -549,7 +531,12 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
+ 	return(NULL);
+     switch (end->type) {
+ 	case XPATH_POINT:
++	    endNode = end->user;
++	    endIndex = end->index;
++	    break;
+ 	case XPATH_RANGE:
++	    endNode = end->user2;
++	    endIndex = end->index2;
+ 	    break;
+ 	case XPATH_NODESET:
+ 	    /*
+@@ -557,39 +544,15 @@ xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
+ 	     */
+ 	    if (end->nodesetval->nodeNr <= 0)
+ 		return(NULL);
++	    endNode = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
++	    endIndex = -1;
+ 	    break;
+ 	default:
+ 	    /* TODO */
+ 	    return(NULL);
+     }
+ 
+-    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
+-    if (ret == NULL) {
+-        xmlXPtrErrMemory("allocating range");
+-	return(NULL);
+-    }
+-    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
+-    ret->type = XPATH_RANGE;
+-    ret->user = start;
+-    ret->index = -1;
+-    switch (end->type) {
+-	case XPATH_POINT:
+-	    ret->user2 = end->user;
+-	    ret->index2 = end->index;
+-	    break;
+-	case XPATH_RANGE:
+-	    ret->user2 = end->user2;
+-	    ret->index2 = end->index2;
+-	    break;
+-	case XPATH_NODESET: {
+-	    ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
+-	    ret->index2 = -1;
+-	    break;
+-	}
+-	default:
+-	    STRANGE
+-	    return(NULL);
+-    }
++    ret = xmlXPtrNewRangeInternal(start, -1, endNode, endIndex);
+     xmlXPtrRangeCheckOrder(ret);
+     return(ret);
+ }
+-- 
+2.9.3
+
diff --git a/patches/libxslt/0001-Fix-heap-overread-in-xsltFormatNumberConversion.patch b/patches/libxslt/0001-Fix-heap-overread-in-xsltFormatNumberConversion.patch
new file mode 100644
index 0000000..9bf818e
--- /dev/null
+++ b/patches/libxslt/0001-Fix-heap-overread-in-xsltFormatNumberConversion.patch
@@ -0,0 +1,31 @@
+From eb1030de31165b68487f288308f9d1810fed6880 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer at aevum.de>
+Date: Fri, 10 Jun 2016 14:23:58 +0200
+Subject: [PATCH] Fix heap overread in xsltFormatNumberConversion
+
+An empty decimal-separator could cause a heap overread. This can be
+exploited to leak a couple of bytes after the buffer that holds the
+pattern string.
+
+Found with afl-fuzz and ASan.
+---
+ libxslt/numbers.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libxslt/numbers.c b/libxslt/numbers.c
+index d1549b4..e78c46b 100644
+--- a/libxslt/numbers.c
++++ b/libxslt/numbers.c
+@@ -1090,7 +1090,8 @@ xsltFormatNumberConversion(xsltDecimalFormatPtr self,
+     }
+ 
+     /* We have finished the integer part, now work on fraction */
+-    if (xsltUTF8Charcmp(the_format, self->decimalPoint) == 0) {
++    if ( (*the_format != 0) &&
++         (xsltUTF8Charcmp(the_format, self->decimalPoint) == 0) ) {
+         format_info.add_decimal = TRUE;
+ 	the_format += xsltUTF8Size(the_format);	/* Skip over the decimal */
+     }
+-- 
+2.9.3
+
diff --git a/patches/libxslt/0002-Check-for-integer-overflow-in-xsltAddTextString.patch b/patches/libxslt/0002-Check-for-integer-overflow-in-xsltAddTextString.patch
new file mode 100644
index 0000000..82b3327
--- /dev/null
+++ b/patches/libxslt/0002-Check-for-integer-overflow-in-xsltAddTextString.patch
@@ -0,0 +1,74 @@
+From 08ab2774b870de1c7b5a48693df75e8154addae5 Mon Sep 17 00:00:00 2001
+From: Nick Wellnhofer <wellnhofer at aevum.de>
+Date: Thu, 12 Jan 2017 15:39:52 +0100
+Subject: [PATCH] Check for integer overflow in xsltAddTextString
+
+Limit buffer size in xsltAddTextString to INT_MAX. The issue can be
+exploited to trigger an out of bounds write on 64-bit systems.
+
+Originally reported to Chromium:
+
+https://crbug.com/676623
+---
+ libxslt/transform.c     | 25 ++++++++++++++++++++++---
+ libxslt/xsltInternals.h |  4 ++--
+ 2 files changed, 24 insertions(+), 5 deletions(-)
+
+diff --git a/libxslt/transform.c b/libxslt/transform.c
+index 519133f..02bff34 100644
+--- a/libxslt/transform.c
++++ b/libxslt/transform.c
+@@ -813,13 +813,32 @@ xsltAddTextString(xsltTransformContextPtr ctxt, xmlNodePtr target,
+         return(target);
+ 
+     if (ctxt->lasttext == target->content) {
++        int minSize;
+ 
+-	if (ctxt->lasttuse + len >= ctxt->lasttsize) {
++        /* Check for integer overflow accounting for NUL terminator. */
++        if (len >= INT_MAX - ctxt->lasttuse) {
++            xsltTransformError(ctxt, NULL, target,
++                "xsltCopyText: text allocation failed\n");
++            return(NULL);
++        }
++        minSize = ctxt->lasttuse + len + 1;
++
++        if (ctxt->lasttsize < minSize) {
+ 	    xmlChar *newbuf;
+ 	    int size;
++            int extra;
++
++            /* Double buffer size but increase by at least 100 bytes. */
++            extra = minSize < 100 ? 100 : minSize;
++
++            /* Check for integer overflow. */
++            if (extra > INT_MAX - ctxt->lasttsize) {
++                size = INT_MAX;
++            }
++            else {
++                size = ctxt->lasttsize + extra;
++            }
+ 
+-	    size = ctxt->lasttsize + len + 100;
+-	    size *= 2;
+ 	    newbuf = (xmlChar *) xmlRealloc(target->content,size);
+ 	    if (newbuf == NULL) {
+ 		xsltTransformError(ctxt, NULL, target,
+diff --git a/libxslt/xsltInternals.h b/libxslt/xsltInternals.h
+index 060b178..5ad1771 100644
+--- a/libxslt/xsltInternals.h
++++ b/libxslt/xsltInternals.h
+@@ -1754,8 +1754,8 @@ struct _xsltTransformContext {
+      * Speed optimization when coalescing text nodes
+      */
+     const xmlChar  *lasttext;		/* last text node content */
+-    unsigned int    lasttsize;		/* last text node size */
+-    unsigned int    lasttuse;		/* last text node use */
++    int             lasttsize;		/* last text node size */
++    int             lasttuse;		/* last text node use */
+     /*
+      * Per Context Debugging
+      */
+-- 
+2.9.3
+
diff --git a/ports/archives/libxml2-2.9.4.tar.gz b/ports/archives/libxml2-2.9.4.tar.gz
new file mode 100644
index 0000000..dbe16ea
Binary files /dev/null and b/ports/archives/libxml2-2.9.4.tar.gz differ
diff --git a/ports/archives/libxslt-1.1.29.tar.gz b/ports/archives/libxslt-1.1.29.tar.gz
new file mode 100644
index 0000000..4723fd3
Binary files /dev/null and b/ports/archives/libxslt-1.1.29.tar.gz differ
diff --git a/suppressions/nokogiri_ree-1.8.7.358.supp b/suppressions/nokogiri_ree-1.8.7.358.supp
deleted file mode 100644
index afae853..0000000
--- a/suppressions/nokogiri_ree-1.8.7.358.supp
+++ /dev/null
@@ -1,61 +0,0 @@
-{
-   <insert_a_suppression_name_here>
-   Memcheck:Addr8
-   fun:garbage_collect
-   fun:rb_newobj
-   fun:rb_node_newnode
-   fun:ruby_yyparse
-   fun:yycompile
-   fun:load_file
-   fun:rb_load
-   fun:rb_require_safe
-   fun:rb_call0
-   fun:rb_call
-   fun:eval_fcall
-   fun:rb_eval
-   fun:rb_load
-   fun:rb_require_safe
-   fun:rb_call0
-   fun:rb_call
-   fun:eval_fcall
-   fun:rb_eval
-   fun:rb_load
-   fun:rb_require_safe
-   fun:rb_protect
-   fun:require_libraries
-   fun:proc_options
-   fun:ruby_process_options
-}
-{
-   <insert_a_suppression_name_here>
-   Memcheck:Addr8
-   fun:garbage_collect_0
-   fun:rb_newobj
-   fun:rb_node_newnode
-   fun:ruby_yyparse
-   fun:yycompile
-   fun:load_file
-   fun:rb_load
-   fun:rb_require_safe
-   fun:rb_call0
-   fun:rb_call
-   fun:eval_fcall
-   fun:rb_eval
-   fun:rb_load
-   fun:rb_require_safe
-   fun:rb_call0
-   fun:rb_call
-   fun:eval_fcall
-   fun:rb_eval
-   fun:rb_load
-   fun:rb_require_safe
-   fun:rb_protect
-   fun:require_libraries
-   fun:proc_options
-   fun:ruby_process_options
-}
-{
-   <insert_a_suppression_name_here>
-   Memcheck:Addr8
-   fun:rb_gc_wipe_stack
-}
diff --git a/suppressions/nokogiri_ruby-1.8.7.370.supp b/suppressions/nokogiri_ruby-1.8.7.370.supp
deleted file mode 100644
index e69de29..0000000
diff --git a/suppressions/nokogiri_ruby-1.9.2.320.supp b/suppressions/nokogiri_ruby-1.9.2.320.supp
deleted file mode 100644
index 80664a1..0000000
--- a/suppressions/nokogiri_ruby-1.9.2.320.supp
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-   <insert_a_suppression_name_here>
-   Memcheck:Addr4
-   fun:glob_helper
-   fun:ruby_glob0
-   fun:rb_push_glob
-   fun:vm_call_method
-   fun:vm_exec_core
-   fun:vm_exec
-   fun:rb_yield
-   fun:rb_ary_each
-   fun:vm_call_method
-   fun:vm_exec_core
-   fun:vm_exec
-   fun:vm_call0
-   fun:rb_iterate
-   fun:rb_block_call
-   fun:enum_find_all
-   fun:vm_call_method
-   fun:vm_exec_core
-   fun:vm_exec
-   fun:vm_call0
-   fun:rb_class_new_instance
-   fun:vm_call_method
-   fun:vm_exec_core
-   fun:vm_exec
-   fun:vm_call0
-}
diff --git a/suppressions/nokogiri_ruby-1.9.3.327.supp b/suppressions/nokogiri_ruby-1.9.3.327.supp
deleted file mode 100644
index 80664a1..0000000
--- a/suppressions/nokogiri_ruby-1.9.3.327.supp
+++ /dev/null
@@ -1,28 +0,0 @@
-{
-   <insert_a_suppression_name_here>
-   Memcheck:Addr4
-   fun:glob_helper
-   fun:ruby_glob0
-   fun:rb_push_glob
-   fun:vm_call_method
-   fun:vm_exec_core
-   fun:vm_exec
-   fun:rb_yield
-   fun:rb_ary_each
-   fun:vm_call_method
-   fun:vm_exec_core
-   fun:vm_exec
-   fun:vm_call0
-   fun:rb_iterate
-   fun:rb_block_call
-   fun:enum_find_all
-   fun:vm_call_method
-   fun:vm_exec_core
-   fun:vm_exec
-   fun:vm_call0
-   fun:rb_class_new_instance
-   fun:vm_call_method
-   fun:vm_exec_core
-   fun:vm_exec
-   fun:vm_call0
-}
diff --git a/test/decorators/test_slop.rb b/test/decorators/test_slop.rb
index d025889..da5c28d 100644
--- a/test/decorators/test_slop.rb
+++ b/test/decorators/test_slop.rb
@@ -9,10 +9,13 @@ module Nokogiri
           <description>this is the foo thing</description>
         </item>
       eoxml
+
       assert doc.item.respond_to?(:title)
       assert_equal 'foo', doc.item.title.text
+
       assert doc.item.respond_to?(:_description), 'should have description'
-      assert 'this is the foo thing', doc.item._description.text
+      assert_equal 'this is the foo thing', doc.item._description.text
+
       assert !doc.item.respond_to?(:foo)
       assert_raise(NoMethodError) { doc.item.foo }
     end
diff --git a/test/helper.rb b/test/helper.rb
index fc84b82..2a58127 100644
--- a/test/helper.rb
+++ b/test/helper.rb
@@ -7,7 +7,17 @@ require 'tempfile'
 require 'pp'
 
 require 'nokogiri'
+
 if ENV['TEST_NOKOGIRI_WITH_LIBXML_RUBY']
+  #
+  #  if you'd like to test with the libxml-ruby gem loaded, it's
+  #  recommended that you set
+  #
+  #    BUNDLE_GEMFILE=Gemfile-libxml-ruby
+  #
+  #  which will a) bundle that gem, and b) set the appropriate env var to
+  #  trigger this block
+  #
   require 'libxml'
   warn "#{__FILE__}:#{__LINE__}: loaded libxml-ruby '#{LibXML::XML::VERSION}'"
 end
diff --git a/test/html/sax/test_parser.rb b/test/html/sax/test_parser.rb
index 420ba14..6af9bca 100644
--- a/test/html/sax/test_parser.rb
+++ b/test/html/sax/test_parser.rb
@@ -132,6 +132,33 @@ module Nokogiri
           ], @parser.document.start_elements
         end
 
+        HTML_WITH_BR_TAG = <<-EOF
+        <html>
+          <head></head>
+          <body>
+            <div>
+              hello
+              <br>
+            </div>
+
+            <div>
+              hello again
+            </div>
+          </body>
+        </html>
+        EOF
+
+        def test_parsing_dom_error_from_string
+          @parser.parse(HTML_WITH_BR_TAG)
+          assert_equal 6, @parser.document.start_elements.length
+        end
+
+        def test_parsing_dom_error_from_io
+          @parser.parse(StringIO.new(HTML_WITH_BR_TAG))
+          assert_equal 6, @parser.document.start_elements.length
+        end
+
+
         def test_empty_processing_instruction
           @parser.parse_memory("<strong>this will segfault<?strong>")
         end
diff --git a/test/html/test_document.rb b/test/html/test_document.rb
index 108b6ce..1a88080 100644
--- a/test/html/test_document.rb
+++ b/test/html/test_document.rb
@@ -15,7 +15,7 @@ module Nokogiri
       end
 
       def test_does_not_fail_with_illformatted_html
-        doc = Nokogiri::HTML('"</html>";'.force_encoding(Encoding::BINARY))
+        doc = Nokogiri::HTML('"</html>";'.dup.force_encoding(Encoding::BINARY))
         assert_not_nil doc
       end
 
@@ -696,6 +696,17 @@ eohtml
         node = html.xpath("//style").first
         assert_equal("tr > div { display:block; }", node.inner_html)
       end
+
+      it "does not fail when converting to_html using explicit encoding" do
+        html_fragment=<<-eos
+  <img width="16" height="16" src="images/icon.gif" border="0" alt="Inactive hide details for "User" ---19/05/2015 12:55:29---Provvediamo subito nell’integrare">
+        eos
+        doc = Nokogiri::HTML(html_fragment, nil, 'ISO-8859-1')
+        html = doc.to_html
+        assert html.index("src=\"images/icon.gif\"")
+        assert_equal 'ISO-8859-1', html.encoding.name
+      end
+
     end
   end
 end
diff --git a/test/html/test_document_encoding.rb b/test/html/test_document_encoding.rb
index 10cc5d4..9f6292b 100644
--- a/test/html/test_document_encoding.rb
+++ b/test/html/test_document_encoding.rb
@@ -128,9 +128,7 @@ module Nokogiri
           assert_equal(title, doc_from_string_enc.at('//title/text()').text)
           assert_equal(title, doc_from_string.at('//title/text()').text)
           assert_equal(title, doc_from_file_enc.at('//title/text()').text)
-          unless Nokogiri.jruby? && file == ENCODING_HTML_FILE
-            assert_equal(title, doc_from_file.at('//title/text()').text)
-          end
+          assert_equal(title, doc_from_file.at('//title/text()').text)
 
           evil = (0..72).map { |i| '超' * i + '悪い事を構想中。' }
 
diff --git a/test/html/test_document_fragment.rb b/test/html/test_document_fragment.rb
index 54e4a0a..bdf999b 100644
--- a/test/html/test_document_fragment.rb
+++ b/test/html/test_document_fragment.rb
@@ -234,6 +234,9 @@ module Nokogiri
       end
 
       def test_element_children_counts
+        if Nokogiri.uses_libxml? && Nokogiri::VERSION_INFO['libxml']['loaded'] <= "2.9.1"
+          skip "#elements doesn't work in 2.9.1, see 1793a5a for history"
+        end
         doc = Nokogiri::HTML::DocumentFragment.parse("   <div>  </div>\n   ")
         assert_equal 1, doc.element_children.count
       end
diff --git a/test/xml/sax/test_push_parser.rb b/test/xml/sax/test_push_parser.rb
index 282954b..d2fac2e 100644
--- a/test/xml/sax/test_push_parser.rb
+++ b/test/xml/sax/test_push_parser.rb
@@ -151,6 +151,54 @@ module Nokogiri
           assert_equal "Gau\337", @parser.document.data.join
           assert_equal [["r"]], @parser.document.end_elements
         end
+
+        def test_replace_entities_attribute_behavior
+          if Nokogiri.uses_libxml?
+            # initially false
+            assert_equal false, @parser.replace_entities
+
+            # can be set to true
+            @parser.replace_entities = true
+            assert_equal true, @parser.replace_entities
+
+            # can be set to false
+            @parser.replace_entities = false
+            assert_equal false, @parser.replace_entities
+          else
+            # initially true
+            assert_equal true, @parser.replace_entities
+
+            # ignore attempts to set to false
+            @parser.replace_entities = false # TODO: should we raise an exception here?
+            assert_equal true, @parser.replace_entities
+          end
+        end
+
+        def test_untouched_entities
+          skip("entities are always replaced in pure Java version") if Nokogiri.jruby?
+          @parser.<<(<<-eoxml)
+            <p id="asdf&asdf">
+              <!-- This is a comment -->
+              Paragraph 1 & 2
+            </p>
+          eoxml
+          @parser.finish
+          assert_equal [["p", [["id", "asdf&asdf"]]]], @parser.document.start_elements
+          assert_equal "Paragraph 1 & 2", @parser.document.data.join.strip
+        end
+
+        def test_replaced_entities
+          @parser.replace_entities = true
+          @parser.<<(<<-eoxml)
+            <p id="asdf&asdf">
+              <!-- This is a comment -->
+              Paragraph 1 & 2
+            </p>
+          eoxml
+          @parser.finish
+          assert_equal [["p", [["id", "asdf&asdf"]]]], @parser.document.start_elements
+          assert_equal "Paragraph 1 & 2", @parser.document.data.join.strip
+        end
       end
     end
   end
diff --git a/test/xml/test_attr.rb b/test/xml/test_attr.rb
index 2a81626..12082a3 100644
--- a/test/xml/test_attr.rb
+++ b/test/xml/test_attr.rb
@@ -11,6 +11,13 @@ module Nokogiri
         }
       end
 
+      def test_new_raises_argerror_on_nondocument
+        document = Nokogiri::XML "<root><foo/></root>"
+        assert_raises ArgumentError do
+          Nokogiri::XML::Attr.new document.at_css("foo"), "bar"
+        end
+      end
+
       def test_content=
         xml = Nokogiri::XML.parse(File.read(XML_FILE), XML_FILE)
         address = xml.xpath('//address')[3]
diff --git a/test/xml/test_document.rb b/test/xml/test_document.rb
index bd67a94..fc30d8a 100644
--- a/test/xml/test_document.rb
+++ b/test/xml/test_document.rb
@@ -221,7 +221,7 @@ module Nokogiri
       end
 
       def test_pp
-        out = StringIO.new('')
+        out = StringIO.new(String.new)
         ::PP.pp @xml, out
         assert_operator out.string.length, :>, 0
       end
diff --git a/test/xml/test_document_fragment.rb b/test/xml/test_document_fragment.rb
index 738bc64..c919ee2 100644
--- a/test/xml/test_document_fragment.rb
+++ b/test/xml/test_document_fragment.rb
@@ -136,6 +136,23 @@ module Nokogiri
         assert_equal expected, search_xpath
       end
 
+      def test_fragment_css_search_with_whitespace_and_node_removal
+        # The same xml without leading whitespace in front of the first line
+        # does not expose the error. Putting both nodes on the same line
+        # instead also fixes the crash.
+        fragment = Nokogiri::XML::DocumentFragment.parse <<-EOXML
+          <p id="content">hi</p> x <!--y--> <p>another paragraph</p>
+        EOXML
+        children = fragment.css('p')
+        assert_equal 2, children.length
+        # removing the last node instead does not yield the error. Probably the
+        # node removal leaves around two consecutive text nodes which make the
+        # css search crash?
+        children.first.remove
+        assert_equal 1, fragment.xpath('.//p | self::p').length
+        assert_equal 1, fragment.css('p').length
+      end
+
       def test_fragment_search_three_ways
         frag = Nokogiri::XML::Document.new.fragment '<p id="content">foo</p><p id="content">bar</p>'
         expected = frag.xpath('./*[@id = "content"]')
@@ -219,6 +236,16 @@ module Nokogiri
         assert fragment.children.respond_to?(:awesome!), fragment.children.class
       end
 
+      def test_decorator_is_applied_to_empty_set
+        x = Module.new do
+          def awesome!
+          end
+        end
+        util_decorate(@xml, x)
+        fragment = Nokogiri::XML::DocumentFragment.new(@xml, "")
+        assert fragment.children.respond_to?(:awesome!), fragment.children.class
+      end
+
       def test_add_node_to_doc_fragment_segfault
         frag = Nokogiri::XML::DocumentFragment.new(@xml, '<p>hello world</p>')
         Nokogiri::XML::Comment.new(frag,'moo')
diff --git a/test/xml/test_entity_reference.rb b/test/xml/test_entity_reference.rb
index 04e2490..aae9875 100644
--- a/test/xml/test_entity_reference.rb
+++ b/test/xml/test_entity_reference.rb
@@ -141,7 +141,7 @@ EOF
         end
         assert_kind_of Nokogiri::XML::EntityReference, doc.xpath('//body').first.children.first
         if Nokogiri.uses_libxml?
-          assert_equal ["Entity 'bar' not defined"], doc.errors.map(&:to_s)
+          assert_equal ["5:14: ERROR: Entity 'bar' not defined"], doc.errors.map(&:to_s)
         end
       end
 
@@ -159,7 +159,7 @@ EOF
         end
         assert_kind_of Nokogiri::XML::EntityReference, doc.xpath('//body').first.children.first
         if Nokogiri.uses_libxml?
-          assert_equal ["Attempt to load network entity http://foo.bar.com/", "Entity 'bar' not defined"], doc.errors.map(&:to_s)
+          assert_equal ["ERROR: Attempt to load network entity http://foo.bar.com/", "4:34: ERROR: Entity 'bar' not defined"], doc.errors.map(&:to_s)
         else
           assert_equal ["Attempt to load network entity http://foo.bar.com/"], doc.errors.map(&:to_s)
         end
diff --git a/test/xml/test_node.rb b/test/xml/test_node.rb
index a8a306a..e14d9ce 100644
--- a/test/xml/test_node.rb
+++ b/test/xml/test_node.rb
@@ -91,12 +91,14 @@ module Nokogiri
         assert_equal Nokogiri::XML::ParseOptions::DEFAULT_XML, options.to_i
       end
 
-      # descriptive, not prescriptive.
-      def test_parse_invalid_html_markup_results_in_empty_nodeset
-        doc = Nokogiri::HTML("<html></html>")
-        nodeset = doc.root.parse "<div><div>a</div><snippet>b</snippet></div>"
-        assert_equal 1, doc.errors.length # "Tag snippet invalid"
+      def test_node_context_parsing_of_malformed_html_fragment
+        doc = HTML.parse "<html><body><div></div></body></html>"
+        context_node = doc.at_css "div"
+        nodeset = context_node.parse("<div </div>")
+
+        assert_equal 1, doc.errors.length
         assert_equal 1, nodeset.length
+        assert_equal "<div></div>", nodeset.to_s
       end
 
       def test_node_context_parsing_of_malformed_html_fragment_with_recover_is_corrected
@@ -105,9 +107,10 @@ module Nokogiri
         nodeset = context_node.parse("<div </div>") do |options|
           options.recover
         end
-        assert_equal "<div></div>", nodeset.to_s
+
         assert_equal 1, doc.errors.length
         assert_equal 1, nodeset.length
+        assert_equal "<div></div>", nodeset.to_s
       end
 
       def test_node_context_parsing_of_malformed_html_fragment_without_recover_is_not_corrected
@@ -116,6 +119,7 @@ module Nokogiri
         nodeset = context_node.parse("<div </div>") do |options|
           options.strict
         end
+
         assert_equal 1, doc.errors.length
         assert_equal 0, nodeset.length
       end
@@ -125,7 +129,7 @@ module Nokogiri
         @xml.root.parse('<hello>')
         assert(error_count < @xml.errors.length, "errors should have increased")
       end
-      
+
       def test_parse_error_on_fragment_with_empty_document
         doc = Document.new
         fragment = DocumentFragment.new(doc, '<foo><bar/></foo>')
@@ -326,8 +330,9 @@ module Nokogiri
       end
 
       def test_document_compare
+        skip "underlying libxml2 behavior changed in libxml2 at a005199"
         nodes = @xml.xpath('//employee')
-        assert_equal(-1, (nodes.first <=> @xml))
+        assert_equal(-1, (nodes.first <=> @xml)) # post-libxml2 at a005199, returns 1
       end
 
       def test_different_document_compare
@@ -689,14 +694,7 @@ module Nokogiri
       end
 
       def test_find_by_css_class_with_nonstandard_whitespace
-        doc = Nokogiri::HTML '
-<html>
-  <body>
-    <div class="a 
-b"></div>
-  </body>
-</html>
-'
+        doc = Nokogiri::HTML "<div class='a\nb'></div>"
         assert_not_nil doc.at_css(".b")
       end
 
diff --git a/test/xml/test_node_reparenting.rb b/test/xml/test_node_reparenting.rb
index 38fcfc3..c67f87e 100644
--- a/test/xml/test_node_reparenting.rb
+++ b/test/xml/test_node_reparenting.rb
@@ -418,6 +418,20 @@ module Nokogiri
             assert_equal "text nodefoo <p></p> bar", xml.root.children.to_html
           end
 
+          it 'should append a text node before an existing non text node' do
+            xml = Nokogiri::XML %Q(<root><p>foo</p><p>bar</p></root>)
+            p = xml.at_css 'p'
+            p.add_next_sibling 'a'
+            assert_equal '<root><p>foo</p>a<p>bar</p></root>', xml.root.to_s
+          end
+
+          it 'should append a text node before an existing text node' do
+            xml = Nokogiri::XML %Q(<root><p>foo</p>after</root>)
+            p = xml.at_css 'p'
+            p.add_next_sibling 'x'
+            assert_equal '<root><p>foo</p>xafter</root>', xml.root.to_s
+          end
+
           describe "with a text node after" do
             it "should not defensively dup the 'after' text node" do
               xml = Nokogiri::XML %Q(<root>before<p></p>after</root>)
diff --git a/test/xml/test_node_set.rb b/test/xml/test_node_set.rb
index e000269..29b62c5 100644
--- a/test/xml/test_node_set.rb
+++ b/test/xml/test_node_set.rb
@@ -252,12 +252,14 @@ module Nokogiri
         assert_equal 2, node_set.first(2).length
       end
 
-      def test_dup
-        assert node_set = @xml.xpath('//employee')
-        dup = node_set.dup
-        assert_equal node_set.length, dup.length
-        node_set.zip(dup).each do |a,b|
-          assert_equal a, b
+      [:dup, :clone].each do |method_name|
+        define_method "test_#{method_name}" do
+          assert node_set = @xml.xpath('//employee')
+          duplicate = node_set.send(method_name)
+          assert_equal node_set.length, duplicate.length
+          node_set.zip(duplicate).each do |a,b|
+            assert_equal a, b
+          end
         end
       end
 
diff --git a/test/xml/test_reader.rb b/test/xml/test_reader.rb
index c310ad3..afc2922 100644
--- a/test/xml/test_reader.rb
+++ b/test/xml/test_reader.rb
@@ -185,6 +185,25 @@ module Nokogiri
         assert 1, reader.errors.length
       end
 
+      def test_errors_is_an_array
+        reader = Nokogiri::XML::Reader(StringIO.new('&bogus;'))
+        assert_raises(SyntaxError) {
+          reader.read
+        }
+        assert_equal [SyntaxError], reader.errors.map(&:class)
+      end
+
+      def test_pushing_to_non_array_raises_TypeError
+        skip "TODO: JRuby ext does not internally call `errors`" if Nokogiri.jruby?
+        reader = Nokogiri::XML::Reader(StringIO.new('&bogus;'))
+        def reader.errors
+          1
+        end
+        assert_raises(TypeError) {
+          reader.read
+        }
+      end
+
       def test_attributes?
         reader = Nokogiri::XML::Reader.from_memory(<<-eoxml)
         <x xmlns:tenderlove='http://tenderlovemaking.com/'>
diff --git a/test/xml/test_syntax_error.rb b/test/xml/test_syntax_error.rb
index 3375c07..31a57db 100644
--- a/test/xml/test_syntax_error.rb
+++ b/test/xml/test_syntax_error.rb
@@ -8,23 +8,29 @@ module Nokogiri
         assert_equal 'hello', error.message
       end
 
-      def test_pushing_to_array
-        reader = Nokogiri::XML::Reader(StringIO.new('&bogus;'))
-        assert_raises(SyntaxError) {
-          reader.read
-        }
-        assert_equal [SyntaxError], reader.errors.map(&:class) unless Nokogiri.jruby? # needs investigation
+      def test_line_column_level_libxml
+        skip unless Nokogiri.uses_libxml?
+
+        bad_doc = Nokogiri::XML('test')
+        error = bad_doc.errors.first
+
+        assert_equal "1:1: FATAL: Start tag expected, '<' not found", error.message
+        assert_equal 1, error.line
+        assert_equal 1, error.column
+        assert_equal 3, error.level
       end
 
-      def test_pushing_to_non_array
-        reader = Nokogiri::XML::Reader(StringIO.new('&bogus;'))
-        def reader.errors
-          1
-        end
-        assert_raises(TypeError) {
-          reader.read
-        }
-      end unless Nokogiri.jruby? # which does not internally call `errors`
+      def test_line_column_level_jruby
+        skip unless Nokogiri.jruby?
+
+        bad_doc = Nokogiri::XML('<root>test</bar>')
+        error = bad_doc.errors.first
+
+        assert_equal "The element type \"root\" must be terminated by the matching end-tag \"</root>\".", error.message
+        assert_equal nil, error.line
+        assert_equal nil, error.column
+        assert_equal nil, error.level
+      end
     end
   end
 end
diff --git a/test/xml/test_unparented_node.rb b/test/xml/test_unparented_node.rb
index e1b7868..08bb1c5 100644
--- a/test/xml/test_unparented_node.rb
+++ b/test/xml/test_unparented_node.rb
@@ -223,12 +223,12 @@ module Nokogiri
         right_space.add_next_sibling(left_space)
         assert_equal left_space, right_space
       end
-      
+
       def test_add_next_sibling_to_root_raises_exception
         xml = Nokogiri::XML(<<-eoxml)
         <root />
         eoxml
-        
+
         node = Nokogiri::XML::Node.new 'child', xml
 
         assert_raise(ArgumentError) do
@@ -240,7 +240,7 @@ module Nokogiri
         xml = Nokogiri::XML(<<-eoxml)
         <root />
         eoxml
-        
+
         node = Nokogiri::XML::Node.new 'child', xml
 
         assert_raise(ArgumentError) do
@@ -248,17 +248,60 @@ module Nokogiri
         end
       end
 
-      def test_add_pi_as_previous_and_next_sibling_to_root_is_ok
+      def test_document_root_can_have_a_comment_sibling_via_add_child
+        doc = Nokogiri::XML "<root>foo</root>"
+        comment = Nokogiri::XML::Comment.new(doc, "this is a comment")
+        doc.add_child comment
+        assert_equal [doc.root, comment], doc.children.to_a
+      end
+
+      def test_document_root_can_have_a_comment_sibling_via_prepend_child
+        doc = Nokogiri::XML "<root>foo</root>"
+        comment = Nokogiri::XML::Comment.new(doc, "this is a comment")
+        doc.prepend_child comment
+        assert_equal [comment, doc.root], doc.children.to_a
+      end
+
+      def test_document_root_can_have_a_comment_sibling_via_add_next_sibling
+        doc = Nokogiri::XML "<root>foo</root>"
+        comment = Nokogiri::XML::Comment.new(doc, "this is a comment")
+        doc.root.add_next_sibling comment
+        assert_equal [doc.root, comment], doc.children.to_a
+      end
+
+      def test_document_root_can_have_a_comment_sibling_via_add_previous_sibling
+        doc = Nokogiri::XML "<root>foo</root>"
+        comment = Nokogiri::XML::Comment.new(doc, "this is a comment")
+        doc.root.add_previous_sibling comment
+        assert_equal [comment, doc.root], doc.children.to_a
+      end
+
+      def test_document_root_can_have_a_processing_instruction_sibling_via_add_child
         doc = Nokogiri::XML "<root>foo</root>"
         pi = Nokogiri::XML::ProcessingInstruction.new(doc, "xml-stylesheet", %q{type="text/xsl" href="foo.xsl"})
-        doc.root.add_previous_sibling pi
-        expected_doc = %Q{<?xml version="1.0"?>\n<?xml-stylesheet type="text/xsl" href="foo.xsl"?>\n<root>foo</root>}
-        assert_includes doc.to_xml, expected_doc
+        doc.add_child pi
+        assert_equal [doc.root, pi], doc.children.to_a
+      end
+
+      def test_document_root_can_have_a_processing_instruction_sibling_via_prepend_child
+        doc = Nokogiri::XML "<root>foo</root>"
+        pi = Nokogiri::XML::ProcessingInstruction.new(doc, "xml-stylesheet", %q{type="text/xsl" href="foo.xsl"})
+        doc.prepend_child pi
+        assert_equal [pi, doc.root], doc.children.to_a
+      end
 
-        pi2 = Nokogiri::XML::ProcessingInstruction.new(doc, "xml-stylesheet", %q{type="text/xsl" href="foo2.xsl"})
-        pi.add_next_sibling pi2
-        expected_doc = %Q{<?xml version="1.0"?>\n<?xml-stylesheet type="text/xsl" href="foo.xsl"?>\n<?xml-stylesheet type="text/xsl" href="foo2.xsl"?>\n<root>foo</root>}
-        assert_includes doc.to_xml, expected_doc
+      def test_document_root_can_have_a_processing_instruction_sibling_via_add_next_sibling
+        doc = Nokogiri::XML "<root>foo</root>"
+        pi = Nokogiri::XML::ProcessingInstruction.new(doc, "xml-stylesheet", %q{type="text/xsl" href="foo.xsl"})
+        doc.root.add_next_sibling pi
+        assert_equal [doc.root, pi], doc.children.to_a
+      end
+
+      def test_document_root_can_have_a_processing_instruction_sibling_via_add_previous_sibling
+        doc = Nokogiri::XML "<root>foo</root>"
+        pi = Nokogiri::XML::ProcessingInstruction.new(doc, "xml-stylesheet", %q{type="text/xsl" href="foo.xsl"})
+        doc.root.add_previous_sibling pi
+        assert_equal [pi, doc.root], doc.children.to_a
       end
 
       def test_find_by_css_with_tilde_eql
diff --git a/test/xml/test_xpath.rb b/test/xml/test_xpath.rb
index 9c5e1a2..f253aa5 100644
--- a/test/xml/test_xpath.rb
+++ b/test/xml/test_xpath.rb
@@ -56,6 +56,10 @@ module Nokogiri
           def value
             123.456
           end
+
+          def anint
+            1230456
+          end
         }.new
       end
 
@@ -186,7 +190,7 @@ module Nokogiri
 
       # issue #741 (xpath() around 10x slower in JRuby)
       def test_slow_jruby_xpath
-        skip("MRI will exceed this timeout when running under valgrind") unless Nokogiri.jruby?
+        skip("testing against an absolute time is brittle. help make this better! see https://github.com/sparklemotion/nokogiri/issues/741")
 
         doc = Nokogiri::XML(File.open(XPATH_FILE))
         start = Time.now
@@ -200,12 +204,7 @@ module Nokogiri
         end
         stop = Time.now
         elapsed_time = stop - start
-        time_limit =
-          if ENV['TRAVIS'] && ENV['CI']
-            20 # Travis CI box slowness
-          else
-            10
-          end
+        time_limit = 20
         assert_send [elapsed_time, :<, time_limit], "XPath is taking too long"
       end
 
@@ -346,6 +345,15 @@ module Nokogiri
         assert_equal 123.456, value
       end
 
+      def test_custom_xpath_without_arguments_returning_int
+        if Nokogiri.uses_libxml?
+          value = @xml.xpath('anint()', @handler)
+        else
+          value = @xml.xpath('nokogiri:anint()', @ns, @handler)
+        end
+        assert_equal 1230456, value
+      end
+
       def test_custom_xpath_with_bullshit_arguments
         xml = %q{<foo> </foo>}
         doc = Nokogiri::XML.parse(xml)
@@ -440,6 +448,15 @@ XML
         assert_equal 1, sections.size
         assert_equal "[TEXT_INSIDE_SECTION]", sections.first.text
       end
+
+      def test_xpath_syntax_error
+        doc = Nokogiri::XML('<ns1:Root></ns1:Root>')
+        begin
+          doc.xpath('//ns1:Root')
+        rescue => e
+          assert_equal false, e.message.include?('0:0')
+        end
+      end
     end
   end
 end
diff --git a/test_all b/test_all
deleted file mode 100755
index affb35d..0000000
--- a/test_all
+++ /dev/null
@@ -1,107 +0,0 @@
-#! /usr/bin/env bash
-#
-#  script to run tests on all relevant rubies, and valgrind on supported rubies.
-#  outputs tests to `test.log` and valgrind output to `valgrind.log`.
-#
-#  requires `rvm` to be installed. sorry about that, multiruby dudes.
-#
-#  it's worth periodically using hoe-debugger's ability to generate
-#  valgrind suppression files to remove spurious valgrind messages
-#  (e.g., 1.9.3's glob_helper). ["rake test:valgrind:suppression"]
-#
-
-# I'd add rubinius, but rvm errors when building it on my machine. :(
-RUBIES="\
-  ruby-2.3 \
-  ruby-2.2 \
-  ruby-2.1 \
-  ruby-2.0.0-p648 \
-  ruby-1.9.3-p551 \
-  ruby-1.9.2-p330 \
-  jruby-9.0.4.0 \
-  jruby-1.7.19
-  "
-
-TEST_LOG=test.log
-VALGRIND_LOG=valgrind.log
-
-# make sure we can test with libxml-ruby installed
-export BUNDLE_GEMFILE="$(pwd)/Gemfile_test_all"
-cat > $BUNDLE_GEMFILE <<EOF
-gem "libxml-ruby", :platform => :mri, :require => false
-eval_gemfile File.join(File.dirname(ENV['BUNDLE_GEMFILE']),"Gemfile")
-EOF
-
-# Load RVM into a shell session *as a function*
-if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then
-    source "$HOME/.rvm/scripts/rvm"
-elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then
-    source "/usr/local/rvm/scripts/rvm"
-else
-    echo "ERROR: An RVM installation was not found.\n"
-fi
-
-> $TEST_LOG
-> $VALGRIND_LOG
-set -o errexit
-
-function rvm_use {
-    current_ruby=$1
-    rvm use "${1}@nokogiri" --create
-}
-
-function clean {
-    bundle exec rake clean clobber 2>&1 > /dev/null
-}
-
-function compile {
-    echo "** compiling ..."
-    bundle exec rake compile 2>&1 > /dev/null
-}
-
-# quick check that we have All The Rubies
-for ruby in $RUBIES ; do
-  rvm_use ${ruby}
-done
-
-for ruby in $RUBIES ; do
-  rvm_use ${ruby}
-  if ! [[ $(bundle -v) =~ "1.12." ]] ; then
-    yes | gem uninstall --force bundler
-    gem install bundler -v 1.12.5
-    bundle -v
-  fi
-  bundle install --quiet --local || bundle install
-  clean
-done
-
-for ruby in $RUBIES ; do
-  rvm_use ${ruby}
-  echo -e "**\n** testing nokogiri on ${ruby}\n**"
-  clean
-  compile
-  echo "** running tests ..."
-  bundle exec rake test 2>&1
-  if [[ ! $ruby =~ "jruby" ]] ; then
-    echo "** running tests again with libxml-ruby loaded ..."
-    if ! gem list libxml-ruby | fgrep 2.8.0 ; then
-      gem install libxml-ruby
-    fi
-    bundle exec rake test:libxml-ruby 2>&1
-  fi
-  clean
-done | tee -a $TEST_LOG
-
-for ruby in $RUBIES ; do
-  if [[ ! $ruby =~ "jruby" ]] ; then
-    rvm_use ${ruby}
-    echo -e "**\n** nokogiri prerelease: ${ruby}\n**"
-    clean
-    compile
-    echo "** running valgrind on tests ..."
-    bundle exec rake test:valgrind 2>&1
-    echo "** running valgrind again with libxml-ruby loaded ..."
-    bundle exec rake test:valgrind:libxml-ruby 2>&1
-    clean
-  fi
-done | tee -a $VALGRIND_LOG

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



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