Merge branch 'release/3.0.1'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 334dec2..257bee8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,12 +4,12 @@
 ## PROJECT
 ## name and version
 ##
-project(nlohmann_json VERSION 3.0.0 LANGUAGES CXX)
+project(nlohmann_json VERSION 3.0.1 LANGUAGES CXX)
 
 ##
 ## OPTIONS
 ##
-option(JSON_BuildTests "Build the unit tests" ON)
+option(JSON_BuildTests "Build the unit tests when BUILD_TESTING is enabled." ON)
 
 ##
 ## CONFIGURATION
@@ -54,7 +54,9 @@
 ## TESTS
 ## create and configure the unit test target
 ##
-if(JSON_BuildTests)
+include(CTest) #adds option BUILD_TESTING (default ON)
+
+if(BUILD_TESTING AND JSON_BuildTests)
     enable_testing()
     include_directories(${NLOHMANN_JSON_SOURCE_DIR})
     add_subdirectory(test)
diff --git a/ChangeLog.md b/ChangeLog.md
index 9db2783..bb95f93 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,6 +1,29 @@
 # Change Log
 All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).
 
+## [v3.0.1](https://github.com/nlohmann/json/releases/tag/v3.0.1) (2017-12-29)
+[Full Changelog](https://github.com/nlohmann/json/compare/v3.0.0...v3.0.1)
+
+- Problem parsing array to global vector [\#896](https://github.com/nlohmann/json/issues/896)
+- Invalid RFC6902 copy operation succeeds [\#894](https://github.com/nlohmann/json/issues/894)
+- How to rename a key during looping? [\#893](https://github.com/nlohmann/json/issues/893)
+- clang++-6.0 \(6.0.0-svn321357-1\) warning [\#892](https://github.com/nlohmann/json/issues/892)
+- Make json.hpp aware of the modules TS? [\#891](https://github.com/nlohmann/json/issues/891)
+- All enum values not handled in switch cases. \( -Wswitch-enum \) [\#889](https://github.com/nlohmann/json/issues/889)
+- JSON Pointer resolve failure resulting in incorrect exception code [\#888](https://github.com/nlohmann/json/issues/888)
+- Unexpected nested arrays from std::vector [\#886](https://github.com/nlohmann/json/issues/886)
+- erase multiple elements from a json object [\#884](https://github.com/nlohmann/json/issues/884)
+- Container function overview in Doxygen is not updated [\#883](https://github.com/nlohmann/json/issues/883)
+- How to use this for binary file uploads [\#881](https://github.com/nlohmann/json/issues/881)
+- Allow setting JSON\_BuildTests=OFF from parent CMakeLists.txt [\#846](https://github.com/nlohmann/json/issues/846)
+- Unit test fails for local-independent str-to-num [\#845](https://github.com/nlohmann/json/issues/845)
+- Another idea about type support [\#774](https://github.com/nlohmann/json/issues/774)
+
+- Includes CTest module/adds BUILD\_TESTING option [\#885](https://github.com/nlohmann/json/pull/885) ([TinyTinni](https://github.com/TinyTinni))
+- Fix MSVC warning C4819 [\#882](https://github.com/nlohmann/json/pull/882) ([erengy](https://github.com/erengy))
+- Merge branch 'develop' into coverity\_scan [\#880](https://github.com/nlohmann/json/pull/880) ([nlohmann](https://github.com/nlohmann))
+- :wrench: Fix up a few more effc++ items [\#858](https://github.com/nlohmann/json/pull/858) ([mattismyname](https://github.com/mattismyname))
+
 ## [v3.0.0](https://github.com/nlohmann/json/releases/tag/v3.0.0) (2017-12-17)
 [Full Changelog](https://github.com/nlohmann/json/compare/v2.1.1...v3.0.0)
 
diff --git a/README.md b/README.md
index 37fd024..256409e 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
 [![Coverage Status](https://img.shields.io/coveralls/nlohmann/json.svg)](https://coveralls.io/r/nlohmann/json)
 [![Coverity Scan Build Status](https://scan.coverity.com/projects/5550/badge.svg)](https://scan.coverity.com/projects/nlohmann-json)
 [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f3732b3327e34358a0e9d1fe9f661f08)](https://www.codacy.com/app/nlohmann/json?utm_source=github.com&utm_medium=referral&utm_content=nlohmann/json&utm_campaign=Badge_Grade)
-[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/TZS6TQdqmEUcN8WW)
+[![Try online](https://img.shields.io/badge/try-online-blue.svg)](https://wandbox.org/permlink/Op57X0V7fTf2tdwl)
 [![Documentation](https://img.shields.io/badge/docs-doxygen-blue.svg)](http://nlohmann.github.io/json)
 [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/nlohmann/json/master/LICENSE.MIT)
 [![Github Releases](https://img.shields.io/github/release/nlohmann/json.svg)](https://github.com/nlohmann/json/releases)
@@ -75,8 +75,6 @@
 
 If you are using [vcpkg](https://github.com/Microsoft/vcpkg/) on your project for external dependencies, then you can use the [nlohmann-json package](https://github.com/Microsoft/vcpkg/tree/master/ports/nlohmann-json). Please see the vcpkg project for any issues regarding the packaging.
 
-:warning: [Version 3.0.0](https://github.com/nlohmann/json/wiki/Road-toward-3.0.0) is currently under development. Branch `develop` is used for the ongoing work and is probably **unstable**. Please use the `master` branch for the last stable version 2.1.1.
-
 
 ## Examples
 
@@ -917,6 +915,7 @@
 - [Jorrit Wronski](https://github.com/jowr) updated the Hunter package links.
 - [Matthias Möller](https://github.com/TinyTinni) added a `.natvis` for the MSVC debug view.
 - [bogemic](https://github.com/bogemic) fixed some C++17 deprecation warnings.
+- [Eren Okka](https://github.com/erengy) fixed some MSVC warnings.
 
 
 Thanks a lot for helping out! Please [let me know](mailto:mail@nlohmann.me) if I forgot someone.
@@ -947,7 +946,7 @@
 - [**send_to_wandbox**](https://github.com/nlohmann/json/blob/develop/doc/scripts/send_to_wandbox.py) to send code examples to [Wandbox](http://melpon.org/wandbox)
 - [**Travis**](https://travis-ci.org) for [continuous integration](https://travis-ci.org/nlohmann/json) on Linux and macOS
 - [**Valgrind**](http://valgrind.org) to check for correct memory management
-- [**Wandbox**](http://melpon.org/wandbox) for [online examples](https://wandbox.org/permlink/TZS6TQdqmEUcN8WW)
+- [**Wandbox**](http://melpon.org/wandbox) for [online examples](https://wandbox.org/permlink/Op57X0V7fTf2tdwl)
 
 
 ## Projects using JSON for Modern C++
@@ -979,7 +978,7 @@
 $ cd build
 $ cmake ..
 $ cmake --build .
-$ ctest
+$ ctest --output-on-failure
 ```
 
 For more information, have a look at the file [.travis.yml](https://github.com/nlohmann/json/blob/master/.travis.yml).
diff --git a/doc/Doxyfile b/doc/Doxyfile
index 56a8c58..878ee2a 100644
--- a/doc/Doxyfile
+++ b/doc/Doxyfile
@@ -5,7 +5,7 @@
 #---------------------------------------------------------------------------
 DOXYFILE_ENCODING      = UTF-8
 PROJECT_NAME           = "JSON for Modern C++"
-PROJECT_NUMBER         = 3.0.0
+PROJECT_NUMBER         = 3.0.1
 PROJECT_BRIEF          =
 PROJECT_LOGO           =
 OUTPUT_DIRECTORY       = .
diff --git a/doc/avatars.png b/doc/avatars.png
index b416a28..4551317 100644
--- a/doc/avatars.png
+++ b/doc/avatars.png
Binary files differ
diff --git a/doc/examples/README.link b/doc/examples/README.link
index 06add2a..5403e0d 100644
--- a/doc/examples/README.link
+++ b/doc/examples/README.link
@@ -1 +1 @@
-<a target="_blank" href="https://wandbox.org/permlink/TZS6TQdqmEUcN8WW"><b>online</b></a>
\ No newline at end of file
+<a target="_blank" href="https://wandbox.org/permlink/Op57X0V7fTf2tdwl"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/at_json_pointer.cpp b/doc/examples/at_json_pointer.cpp
index 80ed6c1..f43b1bc 100644
--- a/doc/examples/at_json_pointer.cpp
+++ b/doc/examples/at_json_pointer.cpp
@@ -79,6 +79,17 @@
         std::cout << e.what() << '\n';
     }
 
+    // out_of_range.403
+    try
+    {
+        // try to use a JSON pointer to an nonexistent object key
+        json::const_reference ref = j.at("/foo"_json_pointer);
+    }
+    catch (json::out_of_range& e)
+    {
+        std::cout << e.what() << '\n';
+    }
+
     // out_of_range.404
     try
     {
diff --git a/doc/examples/at_json_pointer.link b/doc/examples/at_json_pointer.link
index 61a4410..99ebf01 100644
--- a/doc/examples/at_json_pointer.link
+++ b/doc/examples/at_json_pointer.link
@@ -1 +1 @@
-<a target="_blank" href="https://wandbox.org/permlink/mlj2WqOtwBidvuJx"><b>online</b></a>
\ No newline at end of file
+<a target="_blank" href="https://wandbox.org/permlink/3RO0naQeY3cWXNAz"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/at_json_pointer.output b/doc/examples/at_json_pointer.output
index 505792f..1d29893 100644
--- a/doc/examples/at_json_pointer.output
+++ b/doc/examples/at_json_pointer.output
@@ -8,4 +8,5 @@
 [json.exception.parse_error.109] parse error: array index 'one' is not a number
 [json.exception.out_of_range.401] array index 4 is out of range
 [json.exception.out_of_range.402] array index '-' (2) is out of range
+[json.exception.out_of_range.403] key 'foo' not found
 [json.exception.out_of_range.404] unresolved reference token 'foo'
diff --git a/doc/examples/at_json_pointer_const.cpp b/doc/examples/at_json_pointer_const.cpp
index 1496aa5..8009e95 100644
--- a/doc/examples/at_json_pointer_const.cpp
+++ b/doc/examples/at_json_pointer_const.cpp
@@ -55,6 +55,17 @@
         std::cout << e.what() << '\n';
     }
 
+    // out_of_range.403
+    try
+    {
+        // try to use a JSON pointer to an nonexistent object key
+        json::const_reference ref = j.at("/foo"_json_pointer);
+    }
+    catch (json::out_of_range& e)
+    {
+        std::cout << e.what() << '\n';
+    }
+
     // out_of_range.404
     try
     {
diff --git a/doc/examples/at_json_pointer_const.link b/doc/examples/at_json_pointer_const.link
index 31e0bb0..9011b99 100644
--- a/doc/examples/at_json_pointer_const.link
+++ b/doc/examples/at_json_pointer_const.link
@@ -1 +1 @@
-<a target="_blank" href="https://wandbox.org/permlink/vHKlyYl9DwaUO9UN"><b>online</b></a>
\ No newline at end of file
+<a target="_blank" href="https://wandbox.org/permlink/LwtGNqrGgjcWey3P"><b>online</b></a>
\ No newline at end of file
diff --git a/doc/examples/at_json_pointer_const.output b/doc/examples/at_json_pointer_const.output
index b3361f0..aaf8f18 100644
--- a/doc/examples/at_json_pointer_const.output
+++ b/doc/examples/at_json_pointer_const.output
@@ -5,4 +5,5 @@
 [json.exception.parse_error.109] parse error: array index 'one' is not a number
 [json.exception.out_of_range.401] array index 4 is out of range
 [json.exception.out_of_range.402] array index '-' (2) is out of range
+[json.exception.out_of_range.403] key 'foo' not found
 [json.exception.out_of_range.404] unresolved reference token 'foo'
diff --git a/doc/examples/meta.output b/doc/examples/meta.output
index 287d438..1b3e2aa 100644
--- a/doc/examples/meta.output
+++ b/doc/examples/meta.output
@@ -11,7 +11,7 @@
     "version": {
         "major": 3,
         "minor": 0,
-        "patch": 0,
-        "string": "3.0.0"
+        "patch": 1,
+        "string": "3.0.1"
     }
 }
diff --git a/doc/index.md b/doc/index.md
index 36bde60..a72d965 100644
--- a/doc/index.md
+++ b/doc/index.md
@@ -28,6 +28,12 @@
     - @link nlohmann::basic_json::get_ref get_ref @endlink -- get a value reference
     - @link nlohmann::basic_json::operator ValueType() const operator ValueType @endlink -- get a value (implicit conversion)
     - @link nlohmann::basic_json::value value @endlink -- get a value from an object and return default value if key is not present
+  - exceptions
+    - @link nlohmann::basic_json::parse_error parse_error @endlink for exceptions indicating a parse error
+    - @link nlohmann::basic_json::invalid_iterator invalid_iterator @endlink for exceptions indicating errors with iterators
+    - @link nlohmann::basic_json::type_error type_error @endlink for exceptions indicating executing a member function with a wrong type
+    - @link nlohmann::basic_json::out_of_range out_of_range @endlink for exceptions indicating access out of the defined range
+    - @link nlohmann::basic_json::other_error other_error @endlink for exceptions indicating other library errors
   - lexicographical comparison operators
   - serialization
   - deserialization
@@ -45,6 +51,8 @@
 
 The container functions known from STL have been extended to support the different value types from JSON. However, not all functions can be applied to all value types. Note that the signature of some functions differ between the types; for instance, `at` may be called with either a string to address a key in an object or with an integer to address a value in an array.
 
+Note that this table only lists those exceptions thrown due to the type. For instance, the @link nlohmann::basic_json::at(const typename object_t::key_type & key) `at` @endlink function will always throw a @link nlohmann::basic_json::type_error `json::type_error` @endlink exception when called for a string type. When called for an array, it *may* throw an @link nlohmann::basic_json::out_of_range `json::out_of_range` @endlink exception if the passed index is invalid.
+
 <table>
   <tr>
     <th rowspan="2">group</td>
@@ -137,18 +145,18 @@
     <td>`at`</td>
     <td class="ok_green">@link nlohmann::basic_json::at(const typename object_t::key_type & key) `at` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::at(size_type) `at` @endlink</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (304)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (304)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (304)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (304)</td>
   </tr>
   <tr>
     <td>`operator[]`</td>
     <td class="ok_green">@link nlohmann::basic_json::operator[](const typename object_t::key_type &key) `operator[]` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::operator[](size_type) `operator[]` @endlink</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (305)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (305)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (305)</td>
     <td class="ok_green">@link nlohmann::basic_json::operator[](const typename object_t::key_type & key) `operator[]` @endlink (creates object)<br>@link nlohmann::basic_json::operator[](size_type) `operator[]` @endlink (creates array)</td>
   </tr>
   <tr>
@@ -158,7 +166,7 @@
     <td class="ok_green">@link nlohmann::basic_json::front `front` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::front `front` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::front `front` @endlink</td>
-    <td class="nok_throws">throws `std::out_of_range`</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::invalid_iterator `json::invalid_iterator` @endlink (214)</td>
   </tr>
   <tr>
     <td>`back`</td>
@@ -167,7 +175,7 @@
     <td class="ok_green">@link nlohmann::basic_json::back `back` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::back `back` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::back `back` @endlink</td>
-    <td class="nok_throws">throws `std::out_of_range`</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::invalid_iterator `json::invalid_iterator` @endlink (214)</td>
   </tr>
   <tr>
     <td rowspan="3">capacity</td>
@@ -198,7 +206,7 @@
     <td class="ok_green">@link nlohmann::basic_json::max_size `max_size` @endlink (returns `0`)</td>
   </tr>
   <tr>
-    <td rowspan="6">modifiers</td>
+    <td rowspan="7">modifiers</td>
     <td>`clear`</td>
     <td class="ok_green">@link nlohmann::basic_json::clear `clear` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::clear `clear` @endlink</td>
@@ -209,12 +217,12 @@
   </tr>
   <tr>
     <td>`insert`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>
     <td class="ok_green">@link nlohmann::basic_json::insert `insert` @endlink</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (309)</td>
   </tr>
   <tr>
     <td>`erase`</td>
@@ -223,27 +231,36 @@
     <td class="ok_green">@link nlohmann::basic_json::erase `erase` @endlink (converts to null)</td>
     <td class="ok_green">@link nlohmann::basic_json::erase `erase` @endlink (converts to null)</td>
     <td class="ok_green">@link nlohmann::basic_json::erase `erase` @endlink (converts to null)</td>
-    <td class="nok_throws">throws</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (307)</td>
   </tr>
   <tr>
     <td>`push_back`</td>
     <td class="ok_green">@link nlohmann::basic_json::push_back(const typename object_t::value_type & val) `push_back` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::push_back(const nlohmann::basic_json &) `push_back` @endlink</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (308)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (308)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (308)</td>
     <td class="ok_green">@link nlohmann::basic_json::push_back(const typename object_t::value_type & val) `push_back` @endlink (creates object)<br>@link nlohmann::basic_json::push_back(const nlohmann::basic_json &) `push_back` @endlink (creates array)</td>
   </tr>
   <tr>
     <td>`emplace` / `emplace_back`</td>
     <td class="ok_green">@link nlohmann::basic_json::emplace() `emplace` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::emplace_back() `emplace_back` @endlink</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
-    <td class="nok_throws">throws `std::domain_error`</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (311)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (311)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (311)</td>
     <td class="ok_green">@link nlohmann::basic_json::emplace() `emplace` @endlink (creates object)<br>@link nlohmann::basic_json::emplace_back() `emplace_back` @endlink (creates array)</td>
   </tr>
   <tr>
+    <td>`update`</td>
+    <td class="ok_green">@link nlohmann::basic_json::update() `update` @endlink</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>
+    <td class="nok_throws">throws @link nlohmann::basic_json::type_error `json::type_error` @endlink (312)</td>
+  </tr>
+  <tr>
     <td>`swap`</td>
     <td class="ok_green">@link nlohmann::basic_json::swap `swap` @endlink</td>
     <td class="ok_green">@link nlohmann::basic_json::swap `swap` @endlink</td>
@@ -278,4 +295,4 @@
 @author [Niels Lohmann](http://nlohmann.me)
 @see https://github.com/nlohmann/json to download the source code
 
-@version 3.0.0
+@version 3.0.1
diff --git a/doc/json.gif b/doc/json.gif
index dea0438..2b5b588 100644
--- a/doc/json.gif
+++ b/doc/json.gif
Binary files differ
diff --git a/src/json.hpp b/src/json.hpp
index 91cd2a2..5b0b0ea 100644
--- a/src/json.hpp
+++ b/src/json.hpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@@ -456,7 +456,6 @@
 name / id                      | example message | description
 ------------------------------ | --------------- | -------------------------
 json.exception.other_error.501 | unsuccessful: {"op":"test","path":"/baz", "value":"bar"} | A JSON Patch operation 'test' failed. The unsuccessful operation is also printed.
-json.exception.other_error.502 | invalid object size for conversion | Some conversions to user-defined types impose constraints on the object size (e.g. std::pair)
 
 @sa @ref exception for the base class of the library exceptions
 @sa @ref parse_error for exceptions indicating a parse error
@@ -733,7 +732,7 @@
         j.m_type = value_t::array;
         j.m_value = value_t::array;
         j.m_value.array->reserve(arr.size());
-        for (bool x : arr)
+        for (const bool x : arr)
         {
             j.m_value.array->push_back(x);
         }
@@ -2760,7 +2759,7 @@
     {
         // escape control characters
         std::string result;
-        for (auto c : token_string)
+        for (const auto c : token_string)
         {
             if ('\x00' <= c and c <= '\x1F')
             {
@@ -3527,7 +3526,7 @@
         return *this;
     }
 
-    primitive_iterator_t operator++(int)
+    primitive_iterator_t const operator++(int)
     {
         auto result = *this;
         m_it++;
@@ -3540,7 +3539,7 @@
         return *this;
     }
 
-    primitive_iterator_t operator--(int)
+    primitive_iterator_t const operator--(int)
     {
         auto result = *this;
         m_it--;
@@ -3851,7 +3850,7 @@
     @brief post-increment (it++)
     @pre The iterator is initialized; i.e. `m_object != nullptr`.
     */
-    iter_impl operator++(int)
+    iter_impl const operator++(int)
     {
         auto result = *this;
         ++(*this);
@@ -3894,7 +3893,7 @@
     @brief post-decrement (it--)
     @pre The iterator is initialized; i.e. `m_object != nullptr`.
     */
-    iter_impl operator--(int)
+    iter_impl const operator--(int)
     {
         auto result = *this;
         --(*this);
@@ -4300,7 +4299,7 @@
     json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
 
     /// post-increment (it++)
-    json_reverse_iterator operator++(int)
+    json_reverse_iterator const operator++(int)
     {
         return static_cast<json_reverse_iterator>(base_iterator::operator++(1));
     }
@@ -4312,7 +4311,7 @@
     }
 
     /// post-decrement (it--)
-    json_reverse_iterator operator--(int)
+    json_reverse_iterator const operator--(int)
     {
         return static_cast<json_reverse_iterator>(base_iterator::operator--(1));
     }
@@ -6564,11 +6563,12 @@
                         // check that the additional bytes are present
                         assert(i + bytes < s.size());
 
-                        // to use \uxxxx escaping, we first need to caluclate
+                        // to use \uxxxx escaping, we first need to calculate
                         // the codepoint from the UTF-8 bytes
                         int codepoint = 0;
 
-                        assert(0 <= bytes and bytes <= 3);
+                        // bytes is unsigned type:
+                        assert(bytes <= 3);
                         switch (bytes)
                         {
                             case 0:
@@ -7012,6 +7012,27 @@
         return to_string();
     }
 
+    /*!
+    @param[in] s  reference token to be converted into an array index
+
+    @return integer representation of @a s
+
+    @throw out_of_range.404 if string @a s could not be converted to an integer
+    */
+    static int array_index(const std::string& s)
+    {
+        size_t processed_chars = 0;
+        const int res = std::stoi(s, &processed_chars);
+
+        // check if the string was completely read
+        if (JSON_UNLIKELY(processed_chars != s.size()))
+        {
+            JSON_THROW(detail::out_of_range::create(404, "unresolved reference token '" + s + "'"));
+        }
+
+        return res;
+    }
+
   private:
     /*!
     @brief remove and return last reference pointer
@@ -7047,7 +7068,6 @@
         return result;
     }
 
-
     /*!
     @brief create and return a reference to the pointed to value
 
@@ -7499,7 +7519,7 @@
         result["url"] = "https://github.com/nlohmann/json";
         result["version"] =
         {
-            {"string", "3.0.0"}, {"major", 3}, {"minor", 0}, {"patch", 0}
+            {"string", "3.0.1"}, {"major", 3}, {"minor", 0}, {"patch", 1}
         };
 
 #ifdef _WIN32
@@ -8119,7 +8139,7 @@
                     object = nullptr;  // silence warning, see #821
                     if (JSON_UNLIKELY(t == value_t::null))
                     {
-                        JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.0.0")); // LCOV_EXCL_LINE
+                        JSON_THROW(other_error::create(500, "961c151d2e87f2686a955a9be24d316f1362bf21 3.0.1")); // LCOV_EXCL_LINE
                     }
                     break;
                 }
@@ -12237,7 +12257,7 @@
             JSON_THROW(type_error::create(312, "cannot use update() with " + std::string(j.type_name())));
         }
 
-        for (auto it = j.begin(); it != j.end(); ++it)
+        for (auto it = j.cbegin(); it != j.cend(); ++it)
         {
             m_value.object->operator[](it.key()) = it.value();
         }
@@ -13721,6 +13741,9 @@
     pointer @a ptr. As `at` provides checked access (and no elements are
     implicitly inserted), the index '-' is always invalid. See example below.
 
+    @throw out_of_range.403 if the JSON pointer describes a key of an object
+    which cannot be found. See example below.
+
     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
     See example below.
 
@@ -13761,6 +13784,9 @@
     pointer @a ptr. As `at` provides checked access (and no elements are
     implicitly inserted), the index '-' is always invalid. See example below.
 
+    @throw out_of_range.403 if the JSON pointer describes a key of an object
+    which cannot be found. See example below.
+
     @throw out_of_range.404 if the JSON pointer @a ptr can not be resolved.
     See example below.
 
@@ -13976,7 +14002,7 @@
                         }
                         else
                         {
-                            const auto idx = std::stoi(last_path);
+                            const auto idx = json_pointer::array_index(last_path);
                             if (JSON_UNLIKELY(static_cast<size_type>(idx) > parent.size()))
                             {
                                 // avoid undefined behavior
@@ -14024,7 +14050,7 @@
             else if (parent.is_array())
             {
                 // note erase performs range check
-                parent.erase(static_cast<size_type>(std::stoi(last_path)));
+                parent.erase(static_cast<size_type>(json_pointer::array_index(last_path)));
             }
         };
 
@@ -14119,7 +14145,12 @@
                     const json_pointer from_ptr(from_path);
 
                     // the "from" location must exist - use at()
-                    result[ptr] = result.at(from_ptr);
+                    basic_json v = result.at(from_ptr);
+
+                    // The copy is functionally identical to an "add"
+                    // operation at the target location using the value
+                    // specified in the "from" member.
+                    operation_add(ptr, v);
                     break;
                 }
 
@@ -14261,7 +14292,7 @@
                 case value_t::object:
                 {
                     // first pass: traverse this object's elements
-                    for (auto it = source.begin(); it != source.end(); ++it)
+                    for (auto it = source.cbegin(); it != source.cend(); ++it)
                     {
                         // escape the key name to be used in a JSON patch
                         const auto key = json_pointer::escape(it.key());
@@ -14283,7 +14314,7 @@
                     }
 
                     // second pass: traverse other object's elements
-                    for (auto it = target.begin(); it != target.end(); ++it)
+                    for (auto it = target.cbegin(); it != target.cend(); ++it)
                     {
                         if (source.find(it.key()) == source.end())
                         {
@@ -14376,7 +14407,7 @@
                 // create an entry in the array
                 JSON_TRY
                 {
-                    result = &result->operator[](static_cast<size_type>(std::stoi(reference_token)));
+                    result = &result->operator[](static_cast<size_type>(array_index(reference_token)));
                 }
                 JSON_CATCH(std::invalid_argument&)
                 {
@@ -14453,7 +14484,7 @@
                     JSON_TRY
                     {
                         ptr = &ptr->operator[](
-                            static_cast<size_type>(std::stoi(reference_token)));
+                            static_cast<size_type>(array_index(reference_token)));
                     }
                     JSON_CATCH(std::invalid_argument&)
                     {
@@ -14508,7 +14539,7 @@
                 // note: at performs range check
                 JSON_TRY
                 {
-                    ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
+                    ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
                 }
                 JSON_CATCH(std::invalid_argument&)
                 {
@@ -14563,7 +14594,7 @@
                 JSON_TRY
                 {
                     ptr = &ptr->operator[](
-                        static_cast<size_type>(std::stoi(reference_token)));
+                        static_cast<size_type>(array_index(reference_token)));
                 }
                 JSON_CATCH(std::invalid_argument&)
                 {
@@ -14617,7 +14648,7 @@
                 // note: at performs range check
                 JSON_TRY
                 {
-                    ptr = &ptr->at(static_cast<size_type>(std::stoi(reference_token)));
+                    ptr = &ptr->at(static_cast<size_type>(array_index(reference_token)));
                 }
                 JSON_CATCH(std::invalid_argument&)
                 {
diff --git a/test/data/json-patch-tests/README.md b/test/data/json-patch-tests/README.md
new file mode 100755
index 0000000..fb9e447
--- /dev/null
+++ b/test/data/json-patch-tests/README.md
@@ -0,0 +1,75 @@
+JSON Patch Tests
+================
+
+These are test cases for implementations of [IETF JSON Patch (RFC6902)](http://tools.ietf.org/html/rfc6902).
+
+Some implementations can be found at [jsonpatch.com](http://jsonpatch.com).
+
+
+Test Format
+-----------
+
+Each test file is a JSON document that contains an array of test records. A
+test record is an object with the following members:
+
+- doc: The JSON document to test against
+- patch: The patch(es) to apply
+- expected: The expected resulting document, OR
+- error: A string describing an expected error
+- comment: A string describing the test
+- disabled: True if the test should be skipped
+
+All fields except 'doc' and 'patch' are optional. Test records consisting only
+of a comment are also OK.
+
+
+Files
+-----
+
+- tests.json: the main test file
+- spec_tests.json: tests from the RFC6902 spec
+
+
+Writing Tests
+-------------
+
+All tests should have a descriptive comment.  Tests should be as
+simple as possible - just what's required to test a specific piece of
+behavior.  If you want to test interacting behaviors, create tests for
+each behavior as well as the interaction.
+
+If an 'error' member is specified, the error text should describe the
+error the implementation should raise - *not* what's being tested.
+Implementation error strings will vary, but the suggested error should
+be easily matched to the implementation error string.  Try to avoid
+creating error tests that might pass because an incorrect error was
+reported.
+
+Please feel free to contribute!
+
+
+Credits
+-------
+
+The seed test set was adapted from Byron Ruth's
+[jsonpatch-js](https://github.com/bruth/jsonpatch-js/blob/master/test.js) and
+extended by [Mike McCabe](https://github.com/mikemccabe).
+
+
+License
+-------
+
+   Copyright 2014 The Authors
+
+   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.
+
diff --git a/test/data/json-patch-tests/spec_tests.json b/test/data/json-patch-tests/spec_tests.json
new file mode 100755
index 0000000..c160535
--- /dev/null
+++ b/test/data/json-patch-tests/spec_tests.json
@@ -0,0 +1,233 @@
+[
+  {
+    "comment": "4.1. add with missing object",
+    "doc": { "q": { "bar": 2 } },
+    "patch": [ {"op": "add", "path": "/a/b", "value": 1} ],
+    "error":
+       "path /a does not exist -- missing objects are not created recursively"
+  },
+
+  {
+    "comment": "A.1.  Adding an Object Member",
+    "doc": {
+  "foo": "bar"
+},
+    "patch": [
+  { "op": "add", "path": "/baz", "value": "qux" }
+],
+    "expected": {
+  "baz": "qux",
+  "foo": "bar"
+}
+  },
+
+  {
+    "comment": "A.2.  Adding an Array Element",
+    "doc": {
+  "foo": [ "bar", "baz" ]
+},
+    "patch": [
+  { "op": "add", "path": "/foo/1", "value": "qux" }
+],
+    "expected": {
+  "foo": [ "bar", "qux", "baz" ]
+}
+  },
+
+  {
+    "comment": "A.3.  Removing an Object Member",
+    "doc": {
+  "baz": "qux",
+  "foo": "bar"
+},
+    "patch": [
+  { "op": "remove", "path": "/baz" }
+],
+    "expected": {
+  "foo": "bar"
+}
+  },
+
+  {
+    "comment": "A.4.  Removing an Array Element",
+    "doc": {
+  "foo": [ "bar", "qux", "baz" ]
+},
+    "patch": [
+  { "op": "remove", "path": "/foo/1" }
+],
+    "expected": {
+  "foo": [ "bar", "baz" ]
+}
+  },
+
+  {
+    "comment": "A.5.  Replacing a Value",
+    "doc": {
+  "baz": "qux",
+  "foo": "bar"
+},
+    "patch": [
+  { "op": "replace", "path": "/baz", "value": "boo" }
+],
+    "expected": {
+  "baz": "boo",
+  "foo": "bar"
+}
+  },
+
+  {
+    "comment": "A.6.  Moving a Value",
+    "doc": {
+  "foo": {
+    "bar": "baz",
+    "waldo": "fred"
+  },
+  "qux": {
+    "corge": "grault"
+  }
+},
+    "patch": [
+  { "op": "move", "from": "/foo/waldo", "path": "/qux/thud" }
+],
+    "expected": {
+  "foo": {
+    "bar": "baz"
+  },
+  "qux": {
+    "corge": "grault",
+    "thud": "fred"
+  }
+}
+  },
+
+  {
+    "comment": "A.7.  Moving an Array Element",
+    "doc": {
+  "foo": [ "all", "grass", "cows", "eat" ]
+},
+    "patch": [
+  { "op": "move", "from": "/foo/1", "path": "/foo/3" }
+],
+    "expected": {
+  "foo": [ "all", "cows", "eat", "grass" ]
+}
+
+  },
+
+  {
+    "comment": "A.8.  Testing a Value: Success",
+    "doc": {
+  "baz": "qux",
+  "foo": [ "a", 2, "c" ]
+},
+    "patch": [
+  { "op": "test", "path": "/baz", "value": "qux" },
+  { "op": "test", "path": "/foo/1", "value": 2 }
+],
+    "expected": {
+     "baz": "qux",
+     "foo": [ "a", 2, "c" ]
+    }
+  },
+
+  {
+    "comment": "A.9.  Testing a Value: Error",
+    "doc": {
+  "baz": "qux"
+},
+    "patch": [
+  { "op": "test", "path": "/baz", "value": "bar" }
+],
+    "error": "string not equivalent"
+  },
+
+  {
+    "comment": "A.10.  Adding a nested Member Object",
+    "doc": {
+  "foo": "bar"
+},
+    "patch": [
+  { "op": "add", "path": "/child", "value": { "grandchild": { } } }
+],
+    "expected": {
+  "foo": "bar",
+  "child": {
+    "grandchild": {
+    }
+  }
+}
+  },
+
+  {
+    "comment": "A.11.  Ignoring Unrecognized Elements",
+    "doc": {
+  "foo":"bar"
+},
+    "patch": [
+  { "op": "add", "path": "/baz", "value": "qux", "xyz": 123 }
+],
+    "expected": {
+  "foo":"bar",
+  "baz":"qux"
+}
+  },
+
+ {
+    "comment": "A.12.  Adding to a Non-existent Target",
+    "doc": {
+  "foo": "bar"
+},
+    "patch": [
+  { "op": "add", "path": "/baz/bat", "value": "qux" }
+],
+    "error": "add to a non-existent target"
+  },
+
+ {
+    "comment": "A.13 Invalid JSON Patch Document",
+    "doc": {
+     "foo": "bar"
+    },
+    "patch": [
+  { "op": "add", "path": "/baz", "value": "qux", "op": "remove" }
+],
+    "error": "operation has two 'op' members",
+    "disabled": true
+  },
+
+  {
+    "comment": "A.14. ~ Escape Ordering",
+    "doc": {
+       "/": 9,
+       "~1": 10
+    },
+    "patch": [{"op": "test", "path": "/~01", "value": 10}],
+    "expected": {
+       "/": 9,
+       "~1": 10
+    }
+  },
+
+  {
+    "comment": "A.15. Comparing Strings and Numbers",
+    "doc": {
+       "/": 9,
+       "~1": 10
+    },
+    "patch": [{"op": "test", "path": "/~01", "value": "10"}],
+    "error": "number is not equal to string"
+  },
+
+  {
+    "comment": "A.16. Adding an Array Value",
+    "doc": {
+       "foo": ["bar"]
+    },
+    "patch": [{ "op": "add", "path": "/foo/-", "value": ["abc", "def"] }],
+    "expected": {
+      "foo": ["bar", ["abc", "def"]]
+    }
+  }
+
+]
diff --git a/test/data/json-patch-tests/tests.json b/test/data/json-patch-tests/tests.json
new file mode 100755
index 0000000..86305c1
--- /dev/null
+++ b/test/data/json-patch-tests/tests.json
@@ -0,0 +1,434 @@
+[
+    { "comment": "empty list, empty docs",
+      "doc": {},
+      "patch": [],
+      "expected": {} },
+
+    { "comment": "empty patch list",
+      "doc": {"foo": 1},
+      "patch": [],
+      "expected": {"foo": 1} },
+
+    { "comment": "rearrangements OK?",
+      "doc": {"foo": 1, "bar": 2},
+      "patch": [],
+      "expected": {"bar":2, "foo": 1} },
+
+    { "comment": "rearrangements OK?  How about one level down ... array",
+      "doc": [{"foo": 1, "bar": 2}],
+      "patch": [],
+      "expected": [{"bar":2, "foo": 1}] },
+
+    { "comment": "rearrangements OK?  How about one level down...",
+      "doc": {"foo":{"foo": 1, "bar": 2}},
+      "patch": [],
+      "expected": {"foo":{"bar":2, "foo": 1}} },
+
+    { "comment": "add replaces any existing field",
+      "doc": {"foo": null},
+      "patch": [{"op": "add", "path": "/foo", "value":1}],
+      "expected": {"foo": 1} },
+
+    { "comment": "toplevel array",
+      "doc": [],
+      "patch": [{"op": "add", "path": "/0", "value": "foo"}],
+      "expected": ["foo"] },
+
+    { "comment": "toplevel array, no change",
+      "doc": ["foo"],
+      "patch": [],
+      "expected": ["foo"] },
+
+    { "comment": "toplevel object, numeric string",
+      "doc": {},
+      "patch": [{"op": "add", "path": "/foo", "value": "1"}],
+      "expected": {"foo":"1"} },
+
+    { "comment": "toplevel object, integer",
+      "doc": {},
+      "patch": [{"op": "add", "path": "/foo", "value": 1}],
+      "expected": {"foo":1} },
+
+    { "comment": "Toplevel scalar values OK?",
+      "doc": "foo",
+      "patch": [{"op": "replace", "path": "", "value": "bar"}],
+      "expected": "bar",
+      "disabled": true },
+
+    { "comment": "replace object document with array document?",
+      "doc": {},
+      "patch": [{"op": "add", "path": "", "value": []}],
+      "expected": [] },
+
+    { "comment": "replace array document with object document?",
+      "doc": [],
+      "patch": [{"op": "add", "path": "", "value": {}}],
+      "expected": {} },
+
+    { "comment": "append to root array document?",
+      "doc": [],
+      "patch": [{"op": "add", "path": "/-", "value": "hi"}],
+      "expected": ["hi"] },
+
+    { "comment": "Add, / target",
+      "doc": {},
+      "patch": [ {"op": "add", "path": "/", "value":1 } ],
+      "expected": {"":1} },
+
+    { "comment": "Add, /foo/ deep target (trailing slash)",
+      "doc": {"foo": {}},
+      "patch": [ {"op": "add", "path": "/foo/", "value":1 } ],
+      "expected": {"foo":{"": 1}} },
+
+    { "comment": "Add composite value at top level",
+      "doc": {"foo": 1},
+      "patch": [{"op": "add", "path": "/bar", "value": [1, 2]}],
+      "expected": {"foo": 1, "bar": [1, 2]} },
+
+    { "comment": "Add into composite value",
+      "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
+      "patch": [{"op": "add", "path": "/baz/0/foo", "value": "world"}],
+      "expected": {"foo": 1, "baz": [{"qux": "hello", "foo": "world"}]} },
+
+    { "doc": {"bar": [1, 2]},
+      "patch": [{"op": "add", "path": "/bar/8", "value": "5"}],
+      "error": "Out of bounds (upper)" },
+
+    { "doc": {"bar": [1, 2]},
+      "patch": [{"op": "add", "path": "/bar/-1", "value": "5"}],
+      "error": "Out of bounds (lower)" },
+
+    { "doc": {"foo": 1},
+      "patch": [{"op": "add", "path": "/bar", "value": true}],
+      "expected": {"foo": 1, "bar": true} },
+
+    { "doc": {"foo": 1},
+      "patch": [{"op": "add", "path": "/bar", "value": false}],
+      "expected": {"foo": 1, "bar": false} },
+
+    { "doc": {"foo": 1},
+      "patch": [{"op": "add", "path": "/bar", "value": null}],
+      "expected": {"foo": 1, "bar": null} },
+
+    { "comment": "0 can be an array index or object element name",
+      "doc": {"foo": 1},
+      "patch": [{"op": "add", "path": "/0", "value": "bar"}],
+      "expected": {"foo": 1, "0": "bar" } },
+
+    { "doc": ["foo"],
+      "patch": [{"op": "add", "path": "/1", "value": "bar"}],
+      "expected": ["foo", "bar"] },
+
+    { "doc": ["foo", "sil"],
+      "patch": [{"op": "add", "path": "/1", "value": "bar"}],
+      "expected": ["foo", "bar", "sil"] },
+
+    { "doc": ["foo", "sil"],
+      "patch": [{"op": "add", "path": "/0", "value": "bar"}],
+      "expected": ["bar", "foo", "sil"] },
+
+    { "comment": "push item to array via last index + 1",
+      "doc": ["foo", "sil"],
+      "patch": [{"op":"add", "path": "/2", "value": "bar"}],
+      "expected": ["foo", "sil", "bar"] },
+
+    { "comment": "add item to array at index > length should fail",
+      "doc": ["foo", "sil"],
+      "patch": [{"op":"add", "path": "/3", "value": "bar"}],
+      "error": "index is greater than number of items in array" },
+      
+    { "comment": "test against implementation-specific numeric parsing",
+      "doc": {"1e0": "foo"},
+      "patch": [{"op": "test", "path": "/1e0", "value": "foo"}],
+      "expected": {"1e0": "foo"} },
+
+    { "comment": "test with bad number should fail",
+      "doc": ["foo", "bar"],
+      "patch": [{"op": "test", "path": "/1e0", "value": "bar"}],
+      "error": "test op shouldn't get array element 1" },
+
+    { "doc": ["foo", "sil"],
+      "patch": [{"op": "add", "path": "/bar", "value": 42}],
+      "error": "Object operation on array target" },
+
+    { "doc": ["foo", "sil"],
+      "patch": [{"op": "add", "path": "/1", "value": ["bar", "baz"]}],
+      "expected": ["foo", ["bar", "baz"], "sil"],
+      "comment": "value in array add not flattened" },
+
+    { "doc": {"foo": 1, "bar": [1, 2, 3, 4]},
+      "patch": [{"op": "remove", "path": "/bar"}],
+      "expected": {"foo": 1} },
+
+    { "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
+      "patch": [{"op": "remove", "path": "/baz/0/qux"}],
+      "expected": {"foo": 1, "baz": [{}]} },
+
+    { "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
+      "patch": [{"op": "replace", "path": "/foo", "value": [1, 2, 3, 4]}],
+      "expected": {"foo": [1, 2, 3, 4], "baz": [{"qux": "hello"}]} },
+
+    { "doc": {"foo": [1, 2, 3, 4], "baz": [{"qux": "hello"}]},
+      "patch": [{"op": "replace", "path": "/baz/0/qux", "value": "world"}],
+      "expected": {"foo": [1, 2, 3, 4], "baz": [{"qux": "world"}]} },
+
+    { "doc": ["foo"],
+      "patch": [{"op": "replace", "path": "/0", "value": "bar"}],
+      "expected": ["bar"] },
+
+    { "doc": [""],
+      "patch": [{"op": "replace", "path": "/0", "value": 0}],
+      "expected": [0] },
+
+    { "doc": [""],
+      "patch": [{"op": "replace", "path": "/0", "value": true}],
+      "expected": [true] },
+
+    { "doc": [""],
+      "patch": [{"op": "replace", "path": "/0", "value": false}],
+      "expected": [false] },
+
+    { "doc": [""],
+      "patch": [{"op": "replace", "path": "/0", "value": null}],
+      "expected": [null] },
+
+    { "doc": ["foo", "sil"],
+      "patch": [{"op": "replace", "path": "/1", "value": ["bar", "baz"]}],
+      "expected": ["foo", ["bar", "baz"]],
+      "comment": "value in array replace not flattened" },
+
+    { "comment": "replace whole document",
+      "doc": {"foo": "bar"},
+      "patch": [{"op": "replace", "path": "", "value": {"baz": "qux"}}],
+      "expected": {"baz": "qux"} },
+
+    { "comment": "test replace with missing parent key should fail",
+      "doc": {"bar": "baz"},
+      "patch": [{"op": "replace", "path": "/foo/bar", "value": false}],
+      "error": "replace op should fail with missing parent key" },
+
+    { "comment": "spurious patch properties",
+      "doc": {"foo": 1},
+      "patch": [{"op": "test", "path": "/foo", "value": 1, "spurious": 1}],
+      "expected": {"foo": 1} },
+
+    { "doc": {"foo": null},
+      "patch": [{"op": "test", "path": "/foo", "value": null}],
+      "comment": "null value should be valid obj property" },
+
+    { "doc": {"foo": null},
+      "patch": [{"op": "replace", "path": "/foo", "value": "truthy"}],
+      "expected": {"foo": "truthy"},
+      "comment": "null value should be valid obj property to be replaced with something truthy" },
+
+    { "doc": {"foo": null},
+      "patch": [{"op": "move", "from": "/foo", "path": "/bar"}],
+      "expected": {"bar": null},
+      "comment": "null value should be valid obj property to be moved" },
+
+    { "doc": {"foo": null},
+      "patch": [{"op": "copy", "from": "/foo", "path": "/bar"}],
+      "expected": {"foo": null, "bar": null},
+      "comment": "null value should be valid obj property to be copied" },
+
+    { "doc": {"foo": null},
+      "patch": [{"op": "remove", "path": "/foo"}],
+      "expected": {},
+      "comment": "null value should be valid obj property to be removed" },
+
+    { "doc": {"foo": "bar"},
+      "patch": [{"op": "replace", "path": "/foo", "value": null}],
+      "expected": {"foo": null},
+      "comment": "null value should still be valid obj property replace other value" },
+
+    { "doc": {"foo": {"foo": 1, "bar": 2}},
+      "patch": [{"op": "test", "path": "/foo", "value": {"bar": 2, "foo": 1}}],
+      "comment": "test should pass despite rearrangement" },
+
+    { "doc": {"foo": [{"foo": 1, "bar": 2}]},
+      "patch": [{"op": "test", "path": "/foo", "value": [{"bar": 2, "foo": 1}]}],
+      "comment": "test should pass despite (nested) rearrangement" },
+
+    { "doc": {"foo": {"bar": [1, 2, 5, 4]}},
+      "patch": [{"op": "test", "path": "/foo", "value": {"bar": [1, 2, 5, 4]}}],
+      "comment": "test should pass - no error" },
+
+    { "doc": {"foo": {"bar": [1, 2, 5, 4]}},
+      "patch": [{"op": "test", "path": "/foo", "value": [1, 2]}],
+      "error": "test op should fail" },
+
+    { "comment": "Whole document",
+      "doc": { "foo": 1 },
+      "patch": [{"op": "test", "path": "", "value": {"foo": 1}}],
+      "disabled": true },
+
+    { "comment": "Empty-string element",
+      "doc": { "": 1 },
+      "patch": [{"op": "test", "path": "/", "value": 1}] },
+
+    { "doc": {
+            "foo": ["bar", "baz"],
+            "": 0,
+            "a/b": 1,
+            "c%d": 2,
+            "e^f": 3,
+            "g|h": 4,
+            "i\\j": 5,
+            "k\"l": 6,
+            " ": 7,
+            "m~n": 8
+            },
+      "patch": [{"op": "test", "path": "/foo", "value": ["bar", "baz"]},
+                {"op": "test", "path": "/foo/0", "value": "bar"},
+                {"op": "test", "path": "/", "value": 0},
+                {"op": "test", "path": "/a~1b", "value": 1},
+                {"op": "test", "path": "/c%d", "value": 2},
+                {"op": "test", "path": "/e^f", "value": 3},
+                {"op": "test", "path": "/g|h", "value": 4},
+                {"op": "test", "path":  "/i\\j", "value": 5},
+                {"op": "test", "path": "/k\"l", "value": 6},
+                {"op": "test", "path": "/ ", "value": 7},
+                {"op": "test", "path": "/m~0n", "value": 8}] },
+
+    { "comment": "Move to same location has no effect",
+      "doc": {"foo": 1},
+      "patch": [{"op": "move", "from": "/foo", "path": "/foo"}],
+      "expected": {"foo": 1} },
+
+    { "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
+      "patch": [{"op": "move", "from": "/foo", "path": "/bar"}],
+      "expected": {"baz": [{"qux": "hello"}], "bar": 1} },
+
+    { "doc": {"baz": [{"qux": "hello"}], "bar": 1},
+      "patch": [{"op": "move", "from": "/baz/0/qux", "path": "/baz/1"}],
+      "expected": {"baz": [{}, "hello"], "bar": 1} },
+
+    { "doc": {"baz": [{"qux": "hello"}], "bar": 1},
+      "patch": [{"op": "copy", "from": "/baz/0", "path": "/boo"}],
+      "expected": {"baz":[{"qux":"hello"}],"bar":1,"boo":{"qux":"hello"}} },
+
+    { "comment": "replacing the root of the document is possible with add",
+      "doc": {"foo": "bar"},
+      "patch": [{"op": "add", "path": "", "value": {"baz": "qux"}}],
+      "expected": {"baz":"qux"}},
+
+    { "comment": "Adding to \"/-\" adds to the end of the array",
+      "doc": [ 1, 2 ],
+      "patch": [ { "op": "add", "path": "/-", "value": { "foo": [ "bar", "baz" ] } } ],
+      "expected": [ 1, 2, { "foo": [ "bar", "baz" ] } ]},
+
+    { "comment": "Adding to \"/-\" adds to the end of the array, even n levels down",
+      "doc": [ 1, 2, [ 3, [ 4, 5 ] ] ],
+      "patch": [ { "op": "add", "path": "/2/1/-", "value": { "foo": [ "bar", "baz" ] } } ],
+      "expected": [ 1, 2, [ 3, [ 4, 5, { "foo": [ "bar", "baz" ] } ] ] ]},
+
+    { "comment": "test remove with bad number should fail",
+      "doc": {"foo": 1, "baz": [{"qux": "hello"}]},
+      "patch": [{"op": "remove", "path": "/baz/1e0/qux"}],
+      "error": "remove op shouldn't remove from array with bad number" },
+
+    { "comment": "test remove on array",
+      "doc": [1, 2, 3, 4],
+      "patch": [{"op": "remove", "path": "/0"}],
+      "expected": [2, 3, 4] },
+
+    { "comment": "test repeated removes",
+      "doc": [1, 2, 3, 4],
+      "patch": [{ "op": "remove", "path": "/1" },
+                { "op": "remove", "path": "/2" }],
+      "expected": [1, 3] },
+
+    { "comment": "test remove with bad index should fail",
+      "doc": [1, 2, 3, 4],
+      "patch": [{"op": "remove", "path": "/1e0"}],
+      "error": "remove op shouldn't remove from array with bad number" },
+
+    { "comment": "test replace with bad number should fail",
+      "doc": [""],
+      "patch": [{"op": "replace", "path": "/1e0", "value": false}],
+      "error": "replace op shouldn't replace in array with bad number" },
+
+    { "comment": "test copy with bad number should fail",
+      "doc": {"baz": [1,2,3], "bar": 1},
+      "patch": [{"op": "copy", "from": "/baz/1e0", "path": "/boo"}],
+      "error": "copy op shouldn't work with bad number" },
+
+    { "comment": "test move with bad number should fail",
+      "doc": {"foo": 1, "baz": [1,2,3,4]},
+      "patch": [{"op": "move", "from": "/baz/1e0", "path": "/foo"}],
+      "error": "move op shouldn't work with bad number" },
+
+    { "comment": "test add with bad number should fail",
+      "doc": ["foo", "sil"],
+      "patch": [{"op": "add", "path": "/1e0", "value": "bar"}],
+      "error": "add op shouldn't add to array with bad number" },
+
+    { "comment": "missing 'value' parameter to add",
+      "doc": [ 1 ],
+      "patch": [ { "op": "add", "path": "/-" } ],
+      "error": "missing 'value' parameter" },
+
+    { "comment": "missing 'value' parameter to replace",
+      "doc": [ 1 ],
+      "patch": [ { "op": "replace", "path": "/0" } ],
+      "error": "missing 'value' parameter" },
+
+    { "comment": "missing 'value' parameter to test",
+      "doc": [ null ],
+      "patch": [ { "op": "test", "path": "/0" } ],
+      "error": "missing 'value' parameter" },
+
+    { "comment": "missing value parameter to test - where undef is falsy",
+      "doc": [ false ],
+      "patch": [ { "op": "test", "path": "/0" } ],
+      "error": "missing 'value' parameter" },
+
+    { "comment": "missing from parameter to copy",
+      "doc": [ 1 ],
+      "patch": [ { "op": "copy", "path": "/-" } ],
+      "error": "missing 'from' parameter" },
+
+    { "comment": "missing from parameter to move",
+      "doc": { "foo": 1 },
+      "patch": [ { "op": "move", "path": "" } ],
+      "error": "missing 'from' parameter" },
+
+    { "comment": "duplicate ops",
+      "doc": { "foo": "bar" },
+      "patch": [ { "op": "add", "path": "/baz", "value": "qux",
+                   "op": "move", "from":"/foo" } ],
+      "error": "patch has two 'op' members",
+      "disabled": true },
+
+    { "comment": "unrecognized op should fail",
+      "doc": {"foo": 1},
+      "patch": [{"op": "spam", "path": "/foo", "value": 1}],
+      "error": "Unrecognized op 'spam'" },
+
+    { "comment": "test with bad array number that has leading zeros",
+      "doc": ["foo", "bar"],
+      "patch": [{"op": "test", "path": "/00", "value": "foo"}],
+      "error": "test op should reject the array value, it has leading zeros" },
+
+    { "comment": "test with bad array number that has leading zeros",
+      "doc": ["foo", "bar"],
+      "patch": [{"op": "test", "path": "/01", "value": "bar"}],
+      "error": "test op should reject the array value, it has leading zeros" },
+
+    { "comment": "Removing nonexistent field",
+      "doc": {"foo" : "bar"},
+      "patch": [{"op": "remove", "path": "/baz"}],
+      "error": "removing a nonexistent field should fail" },
+
+    { "comment": "Removing nonexistent index",
+      "doc": ["foo", "bar"],
+      "patch": [{"op": "remove", "path": "/2"}],
+      "error": "removing a nonexistent index should fail" },
+
+    { "comment": "Patch with different capitalisation than doc",
+       "doc": {"foo":"bar"},
+       "patch": [{"op": "add", "path": "/FOO", "value": "BAR"}],
+       "expected": {"foo": "bar", "FOO": "BAR"}
+    }
+
+]
diff --git a/test/src/fuzzer-driver_afl.cpp b/test/src/fuzzer-driver_afl.cpp
index e4eb4a1..69fcec7 100644
--- a/test/src/fuzzer-driver_afl.cpp
+++ b/test/src/fuzzer-driver_afl.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 This file implements a driver for American Fuzzy Lop (afl-fuzz). It relies on
diff --git a/test/src/fuzzer-parse_cbor.cpp b/test/src/fuzzer-parse_cbor.cpp
index cf2ce82..576407b 100644
--- a/test/src/fuzzer-parse_cbor.cpp
+++ b/test/src/fuzzer-parse_cbor.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 This file implements a parser test suitable for fuzz testing. Given a byte
diff --git a/test/src/fuzzer-parse_json.cpp b/test/src/fuzzer-parse_json.cpp
index bacf628..6b2b115 100644
--- a/test/src/fuzzer-parse_json.cpp
+++ b/test/src/fuzzer-parse_json.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 This file implements a parser test suitable for fuzz testing. Given a byte
diff --git a/test/src/fuzzer-parse_msgpack.cpp b/test/src/fuzzer-parse_msgpack.cpp
index ae9534f..c3f9eb5 100644
--- a/test/src/fuzzer-parse_msgpack.cpp
+++ b/test/src/fuzzer-parse_msgpack.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (fuzz test support)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 This file implements a parser test suitable for fuzz testing. Given a byte
diff --git a/test/src/unit-algorithms.cpp b/test/src/unit-algorithms.cpp
index b3f534d..f74ca72 100644
--- a/test/src/unit-algorithms.cpp
+++ b/test/src/unit-algorithms.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-allocator.cpp b/test/src/unit-allocator.cpp
index 183336e..a182d98 100644
--- a/test/src/unit-allocator.cpp
+++ b/test/src/unit-allocator.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-capacity.cpp b/test/src/unit-capacity.cpp
index 971068e..4df512a 100644
--- a/test/src/unit-capacity.cpp
+++ b/test/src/unit-capacity.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-cbor.cpp b/test/src/unit-cbor.cpp
index 638ccef..1e37a98 100644
--- a/test/src/unit-cbor.cpp
+++ b/test/src/unit-cbor.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-class_const_iterator.cpp b/test/src/unit-class_const_iterator.cpp
index 631656d..5ecc9d6 100644
--- a/test/src/unit-class_const_iterator.cpp
+++ b/test/src/unit-class_const_iterator.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-class_iterator.cpp b/test/src/unit-class_iterator.cpp
index 875f309..45f28ef 100644
--- a/test/src/unit-class_iterator.cpp
+++ b/test/src/unit-class_iterator.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-class_lexer.cpp b/test/src/unit-class_lexer.cpp
index 3f2d77c..45355cd 100644
--- a/test/src/unit-class_lexer.cpp
+++ b/test/src/unit-class_lexer.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-class_parser.cpp b/test/src/unit-class_parser.cpp
index 008ef43..91fd181 100644
--- a/test/src/unit-class_parser.cpp
+++ b/test/src/unit-class_parser.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-comparison.cpp b/test/src/unit-comparison.cpp
index 7b1aa6e..dbd7788 100644
--- a/test/src/unit-comparison.cpp
+++ b/test/src/unit-comparison.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-concepts.cpp b/test/src/unit-concepts.cpp
index 981c89e..dea1238 100644
--- a/test/src/unit-concepts.cpp
+++ b/test/src/unit-concepts.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-constructor1.cpp b/test/src/unit-constructor1.cpp
index b216540..9d93f6f 100644
--- a/test/src/unit-constructor1.cpp
+++ b/test/src/unit-constructor1.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-constructor2.cpp b/test/src/unit-constructor2.cpp
index cf5e39f..58545ad 100644
--- a/test/src/unit-constructor2.cpp
+++ b/test/src/unit-constructor2.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-convenience.cpp b/test/src/unit-convenience.cpp
index fc9f299..2bfef0f 100644
--- a/test/src/unit-convenience.cpp
+++ b/test/src/unit-convenience.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-conversions.cpp b/test/src/unit-conversions.cpp
index 8197849..fb0ab4e 100644
--- a/test/src/unit-conversions.cpp
+++ b/test/src/unit-conversions.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-deserialization.cpp b/test/src/unit-deserialization.cpp
index 2181bc4..1da791a 100644
--- a/test/src/unit-deserialization.cpp
+++ b/test/src/unit-deserialization.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-element_access1.cpp b/test/src/unit-element_access1.cpp
index 0a7f964..e288cb5 100644
--- a/test/src/unit-element_access1.cpp
+++ b/test/src/unit-element_access1.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-element_access2.cpp b/test/src/unit-element_access2.cpp
index 40cd811..8f628f6 100644
--- a/test/src/unit-element_access2.cpp
+++ b/test/src/unit-element_access2.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-inspection.cpp b/test/src/unit-inspection.cpp
index 82fbf72..0043a9e 100644
--- a/test/src/unit-inspection.cpp
+++ b/test/src/unit-inspection.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-iterator_wrapper.cpp b/test/src/unit-iterator_wrapper.cpp
index 137aca8..e16ce16 100644
--- a/test/src/unit-iterator_wrapper.cpp
+++ b/test/src/unit-iterator_wrapper.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-iterators1.cpp b/test/src/unit-iterators1.cpp
index d5d6193..8c5eddb 100644
--- a/test/src/unit-iterators1.cpp
+++ b/test/src/unit-iterators1.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-iterators2.cpp b/test/src/unit-iterators2.cpp
index 2ef5c0a..d872890 100644
--- a/test/src/unit-iterators2.cpp
+++ b/test/src/unit-iterators2.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-json_patch.cpp b/test/src/unit-json_patch.cpp
index 15f3d01..3490f70 100644
--- a/test/src/unit-json_patch.cpp
+++ b/test/src/unit-json_patch.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@@ -31,6 +31,8 @@
 #include "json.hpp"
 using nlohmann::json;
 
+#include <fstream>
+
 TEST_CASE("JSON patch")
 {
     SECTION("examples from RFC 6902")
@@ -1250,4 +1252,42 @@
                               R"( [{"op": "test", "path": "/foo", "value": "bar"}] )"_json));
         }
     }
+
+    SECTION("Tests from github.com/json-patch/json-patch-tests")
+    {
+        for (auto filename :
+                {"test/data/json-patch-tests/spec_tests.json",
+                 "test/data/json-patch-tests/tests.json"
+                })
+        {
+            CAPTURE(filename);
+            std::ifstream f(filename);
+            json suite = json::parse(f);
+
+            for (const auto& test : suite)
+            {
+                CAPTURE(test.value("comment", ""))
+
+                // skip tests marked as disabled
+                if (test.value("disabled", false))
+                {
+                    continue;
+                }
+
+                const auto& doc = test["doc"];
+                const auto& patch = test["patch"];
+
+                if (test.count("error") == 0)
+                {
+                    // if an expected value is given, use it; use doc otherwise
+                    const auto& expected = test.value("expected", doc);
+                    CHECK(doc.patch(patch) == expected);
+                }
+                else
+                {
+                    CHECK_THROWS(doc.patch(patch));
+                }
+            }
+        }
+    }
 }
diff --git a/test/src/unit-json_pointer.cpp b/test/src/unit-json_pointer.cpp
index 4af379c..b6b8376 100644
--- a/test/src/unit-json_pointer.cpp
+++ b/test/src/unit-json_pointer.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@@ -55,6 +55,15 @@
         CHECK_THROWS_AS(p.pop_back(), json::out_of_range&);
         CHECK_THROWS_WITH(p.pop_back(),
                           "[json.exception.out_of_range.405] JSON pointer has no parent");
+
+        SECTION("array index error")
+        {
+            json v = {1, 2, 3, 4};
+            json::json_pointer ptr("/10e");
+            CHECK_THROWS_AS(v[ptr], json::out_of_range);
+            CHECK_THROWS_WITH(v[ptr],
+                              "[json.exception.out_of_range.404] unresolved reference token '10e'");
+        }
     }
 
     SECTION("examples from RFC 6901")
diff --git a/test/src/unit-meta.cpp b/test/src/unit-meta.cpp
index 015e84b..f6e9d6f 100644
--- a/test/src/unit-meta.cpp
+++ b/test/src/unit-meta.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@@ -42,10 +42,10 @@
         CHECK(j["url"] == "https://github.com/nlohmann/json");
         CHECK(j["version"] == json(
         {
-            {"string", "3.0.0"},
+            {"string", "3.0.1"},
             {"major", 3},
             {"minor", 0},
-            {"patch", 0}
+            {"patch", 1}
         }));
 
         CHECK(j.find("platform") != j.end());
diff --git a/test/src/unit-modifiers.cpp b/test/src/unit-modifiers.cpp
index e439c2f..44b9cf2 100644
--- a/test/src/unit-modifiers.cpp
+++ b/test/src/unit-modifiers.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-msgpack.cpp b/test/src/unit-msgpack.cpp
index 18bdbfe..531012b 100644
--- a/test/src/unit-msgpack.cpp
+++ b/test/src/unit-msgpack.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-noexcept.cpp b/test/src/unit-noexcept.cpp
index ed29425..56ca4a4 100644
--- a/test/src/unit-noexcept.cpp
+++ b/test/src/unit-noexcept.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-pointer_access.cpp b/test/src/unit-pointer_access.cpp
index 068330c..1925490 100644
--- a/test/src/unit-pointer_access.cpp
+++ b/test/src/unit-pointer_access.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-readme.cpp b/test/src/unit-readme.cpp
index 8f9f7e0..ebf1058 100644
--- a/test/src/unit-readme.cpp
+++ b/test/src/unit-readme.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-reference_access.cpp b/test/src/unit-reference_access.cpp
index fd02022..ea84c9e 100644
--- a/test/src/unit-reference_access.cpp
+++ b/test/src/unit-reference_access.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-regression.cpp b/test/src/unit-regression.cpp
index a24ff53..a119ed7 100644
--- a/test/src/unit-regression.cpp
+++ b/test/src/unit-regression.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
@@ -1322,4 +1322,32 @@
         j = ar;
         ar = j;
     }
+
+    SECTION("issue #894 - invalid RFC6902 copy operation succeeds")
+    {
+        auto model = R"({
+            "one": {
+                "two": {
+                    "three": "hello",
+                    "four": 42
+                }
+            }
+        })"_json;
+
+        CHECK_THROWS_AS(model.patch(R"([{"op": "move",
+                         "from": "/one/two/three",
+                         "path": "/a/b/c"}])"_json), json::out_of_range);
+        CHECK_THROWS_WITH(model.patch(R"([{"op": "move",
+                         "from": "/one/two/three",
+                         "path": "/a/b/c"}])"_json),
+                          "[json.exception.out_of_range.403] key 'a' not found");
+
+        CHECK_THROWS_AS(model.patch(R"([{"op": "copy",
+                                 "from": "/one/two/three",
+                                 "path": "/a/b/c"}])"_json), json::out_of_range);
+        CHECK_THROWS_WITH(model.patch(R"([{"op": "copy",
+                                 "from": "/one/two/three",
+                                 "path": "/a/b/c"}])"_json),
+                          "[json.exception.out_of_range.403] key 'a' not found");
+    }
 }
diff --git a/test/src/unit-serialization.cpp b/test/src/unit-serialization.cpp
index ce48b55..5668b7b 100644
--- a/test/src/unit-serialization.cpp
+++ b/test/src/unit-serialization.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-testsuites.cpp b/test/src/unit-testsuites.cpp
index 861419b..aad2b1d 100644
--- a/test/src/unit-testsuites.cpp
+++ b/test/src/unit-testsuites.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-udt.cpp b/test/src/unit-udt.cpp
index f32acbb..4fd6f7e 100644
--- a/test/src/unit-udt.cpp
+++ b/test/src/unit-udt.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit-unicode.cpp b/test/src/unit-unicode.cpp
index 24b13f9..3b2a239 100644
--- a/test/src/unit-unicode.cpp
+++ b/test/src/unit-unicode.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.
diff --git a/test/src/unit.cpp b/test/src/unit.cpp
index b08408d..1ad77ce 100644
--- a/test/src/unit.cpp
+++ b/test/src/unit.cpp
@@ -1,7 +1,7 @@
 /*
     __ _____ _____ _____
  __|  |   __|     |   | |  JSON for Modern C++ (test suite)
-|  |  |__   |  |  | | | |  version 3.0.0
+|  |  |__   |  |  | | | |  version 3.0.1
 |_____|_____|_____|_|___|  https://github.com/nlohmann/json
 
 Licensed under the MIT License <http://opensource.org/licenses/MIT>.