[libmongodb-perl] 01/07: Imported Upstream version 0.708.4.0

Harlan Lieberman-Berg H.LiebermanBerg at gmail.com
Sun Aug 30 02:46:42 UTC 2015


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

hlieberman-guest pushed a commit to branch master
in repository libmongodb-perl.

commit 2a3a23d25904f17b8fd0b10ffdb6154dce12d4db
Author: Harlan Lieberman-Berg <hlieberman at setec.io>
Date:   Sat Aug 22 20:46:09 2015 +0200

    Imported Upstream version 0.708.4.0
---
 Changes                               |  150 +++++
 INSTALL.md                            |   49 +-
 MANIFEST                              |    8 +-
 META.json                             |   72 +--
 META.yml                              |   66 +--
 Makefile.PL                           |    3 +-
 README                                |    6 +-
 bson/bcon.c                           | 1024 ---------------------------------
 bson/bcon.h                           |  280 ---------
 bson/bson-compat.h                    |    4 +
 bson/bson.c                           |    1 -
 inc/Module/Install/PRIVATE/Mongo.pm   |   58 +-
 lib/MongoDB.pm                        |   12 +-
 lib/MongoDB/BSON.pm                   |   58 +-
 lib/MongoDB/BSON/Binary.pm            |   12 +-
 lib/MongoDB/BSON/Regexp.pm            |   12 +-
 lib/MongoDB/BulkWrite.pm              |   12 +-
 lib/MongoDB/BulkWriteView.pm          |   12 +-
 lib/MongoDB/Code.pm                   |   12 +-
 lib/MongoDB/Collection.pm             |  121 ++--
 lib/MongoDB/CommandResult.pm          |   12 +-
 lib/MongoDB/Connection.pm             |   12 +-
 lib/MongoDB/Cursor.pm                 |   32 +-
 lib/MongoDB/DBRef.pm                  |   12 +-
 lib/MongoDB/DataTypes.pod             |   27 +-
 lib/MongoDB/Database.pm               |   59 +-
 lib/MongoDB/Error.pm                  |   12 +-
 lib/MongoDB/Examples.pod              |   10 +-
 lib/MongoDB/GridFS.pm                 |   43 +-
 lib/MongoDB/GridFS/File.pm            |   31 +-
 lib/MongoDB/Indexing.pod              |   16 +-
 lib/MongoDB/MongoClient.pm            |  129 ++++-
 lib/MongoDB/OID.pm                    |   36 +-
 lib/MongoDB/Role/_LastError.pm        |    2 +-
 lib/MongoDB/Role/_Remover.pm          |    2 +-
 lib/MongoDB/Role/_Updater.pm          |    2 +-
 lib/MongoDB/Role/_View.pm             |    2 +-
 lib/MongoDB/Role/_WriteQueue.pm       |    2 +-
 lib/MongoDB/Role/_Writeable.pm        |    2 +-
 lib/MongoDB/Timestamp.pm              |   12 +-
 lib/MongoDB/Tutorial.pod              |   10 +-
 lib/MongoDB/WriteResult.pm            |   12 +-
 lib/MongoDB/_Types.pm                 |    2 +-
 mongo_link.c                          |   14 +-
 perl_mongo.c                          |  116 ++--
 t/00-report-prereqs.dd                |   10 +-
 t/00-report-prereqs.t                 |   28 +-
 t/bson.t                              |   38 +-
 t/bulk.t                              |   15 -
 t/collection.t                        |  214 ++-----
 t/connection.t                        |    3 +-
 t/cursor.t                            |   28 +-
 t/database.t                          |   24 +-
 t/gridfs.t                            |   54 +-
 t/indexes.t                           |  195 +++++++
 t/lib/MongoDBTest.pm                  |    8 +-
 t/threads/basic.t                     |    4 +-
 t/threads/bson.t                      |   89 +++
 t/threads/cursor.t                    |    5 +-
 t/threads/oid.t                       |    6 +-
 t/types.t                             |   21 +-
 xs/Cursor.xs                          |   20 +-
 xs/Mongo.xs                           |    1 -
 xs/MongoClient.xs                     |    2 +-
 xt/{release => author}/test-version.t |   12 +-
 xt/release/check-jira-in-changes.t    |    4 +-
 66 files changed, 1339 insertions(+), 2023 deletions(-)

diff --git a/Changes b/Changes
index 54b370f..5225e19 100644
--- a/Changes
+++ b/Changes
@@ -1,5 +1,155 @@
 # Change history for the MongoDB Perl driver:
 
+v0.708.4.0 2015-08-11 16:06:55-04:00 America/New_York
+
+  [Bug fixes]
+
+  - Fixes handling of 'safe' option for 'remove'
+
+  - PERL-555 Fixes serialization of thread-shared scalars (and likely
+    other tied/magic-using scalars) on Perls before 5.18
+
+v0.708.3.0 2015-07-14 15:42:16-04:00 America/New_York
+
+  [Bug fixes]
+
+  - PERL-543 fix serialization of undef in tied hashes
+
+  - PERL-553 fix duplicate _id bug with Tie::IxHash and array reference
+    documents with an existing _id
+
+  - Fix BSON tests on Perl with long doubled enabled
+
+v0.708.2.0 2015-06-05 16:39:00-04:00 America/New_York
+
+  [Bug fixes]
+
+  - PERL-536 fix GridFS to stop throwing an error when a known empty file has
+    no chunks; errors will still be thrown if a non-empty file has no chunks.
+
+  - PERL-541 fixed remove() to respect MongoClient write concern
+
+  [Documentation]
+
+  - PERL-525 updated legacy author emails in docs and metadata
+
+v0.708.1.0 2015-04-29 16:51:52-04:00 America/New_York
+
+  [Bug fixes]
+
+  - PERL-479 retrieving a GridFS file now throws an error if no chunks exist
+    instead of returning an empty string
+
+  [Removals]
+
+  - PERL-496 The $MongoDB::BSON::use_boolean never worked; BSON boolean values
+    were always deserialized as boolean.pm objects.  Rather than
+    "fix" this and break people's code, the option has been removed
+    and documented as such.
+
+v0.708.0.0 2015-01-20 16:57:11-05:00 America/New_York
+
+  [Additions]
+
+  - Added 'get_namespace' method (and 'ns' alias) to MongoDB::MongoClient
+    for getting a collection directly without an intermediate database object.
+
+  - Added 'db' and 'coll' aliases for 'get_database' and 'get_collection'
+
+  [Bug fixes]
+
+  - PERL-489 references to scalars with both number and string slots internally
+    would crash on BSON encoding, rather than encode the string part as a
+    binary.
+
+  [Diagnostics]
+
+  - Added parenthetical note to "can't get db response" errors to disambiguate
+    where they occur.
+
+v0.707.2.0 2014-12-22 05:35:31-05:00 America/New_York
+
+  [Bug fixes]
+
+  - PERL-476 fixed getting lists of collections and indices for changes in
+    MongoDB 2.8-rc3 and later.
+
+v0.707.1.0 2014-12-10 12:50:45-05:00 America/New_York
+
+  [Bug fixes]
+
+  - PERL-465 allowed arbitrary options on index creation
+
+  - Fixed t/database.t for change in error message for missing commands
+
+  - Fixed undef warning from get_indexes on older MongoDB versions
+
+  [Prerequisites]
+
+  - Removed Data::Types as a test dependency as it was barely used
+    and not necessary
+
+v0.707.0.0 2014-11-12 15:04:46-05:00 America/New_York
+
+  [Additions]
+
+  - Supports MongoDB 2.8-RC0; in addition to prior feature support, this release
+    fixes tests that were broken against non-default storage engines
+
+  [Bug fixes]
+
+  - PERL-454 suppress warnings storing datetimes at the epoch
+
+v0.706.0.0 2014-10-28 11:30:42-04:00 America/New_York
+
+  [*** Deprecations ***]
+
+  - PERL-425 the 'drop_dups' indexing option is deprecated because it is
+    ignored as of server version 2.7.5
+
+  [Additions]
+
+  - PERL-408 added support for SCRAM-SHA-1 (for MongoDB 2.7.8+)
+
+  [Bug fixes]
+
+  - PERL-409 fixed compilation on MSWin32 using the MinGW compiler
+
+  - Fixed compilation errors on MSWin32 using the MSVC compiler
+
+  - Fixed construction of Makefile LIBS argument for some platforms
+
+  - Fixed parallel scan and explain tests for changes in the MongoDB 2.7.x
+    development series
+
+  [Diagnostics]
+
+  - Passing the "ssl" parameter to MongoDB::MongoClient will now warn if SSL
+    support is not available.
+
+  [Documentation]
+
+  - Revised "run_command" documentation to explain that array references or
+    Tie::IxHash should be used.
+
+  [Prerequisites]
+
+  - Added dependency on Authen::SCRAM::Client 0.003
+
+  - Removed (test) dependency on File::Slurp
+
+  - Minimum required versions of configuration dependencies Path::Tiny and
+    Config::AutoConf are now enforced in the code, not just specified in
+    META.json
+
+  [~ Internal changes ~]
+
+  - PERL-433 uses the listCollections command if available (MongoDB 2.7.8+)
+
+  - PERL-434 uses the listIndexes command if available (MongoDB 2.7.8+)
+
+  - PERL-436 bumped supported maxWireProtocolVersion to 3 (MongoDB 2.7.8+)
+
 v0.705.0.0 2014-09-09 10:04:59-04:00 America/New_York
 
   [Additions]
diff --git a/INSTALL.md b/INSTALL.md
index bfa62aa..c3fe925 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -29,8 +29,8 @@ Linux, Fedora, etc.) should issue the following command:
 
 Configuration requires the following Perl modules:
 
-* Config::AutoConf
-* Path::Tiny
+* Config::AutoConf (0.22 or later)
+* Path::Tiny (0.052 or later)
 
 If you are using a modern CPAN client (anything since Perl v5.12), these will
 be installed automatically as needed.  If you have an older CPAN client or are
@@ -120,21 +120,44 @@ If your libssl or libgsasl libraries are in a non-standard location, you
 will need to pass custom arguments to the `Makefile.PL` using the `LIBS`
 parameter.
 
-Due to a quirk in ExtUtils::MakeMaker, this will override any
-libraries set by Makefile.PL and you will need to specify them all on the
-command line.  You should first run `Makefile.PL` without any arguments and
-look in the generated `Makefile` for the `LIBS` parameter in the commented
-section at the top.
+Due to a quirk in ExtUtils::MakeMaker, this will override any libraries set
+by Makefile.PL and you will need to specify them all on the command line.
+The list will differ by platform so you need to figure out what would have
+been in `LIBS` and then add your custom information to it..
 
-Then, add your library path and library flags to that and pass it on the
-command line.  Be sure your include path is available to your compiler.
+You should first run `Makefile.PL` with your desired flags and look in the
+generated `Makefile` for the `LIBS` parameter in the commented section at
+the top.
 
-For example, assuming libgsasl is installed in /opt/local:
+For example (on a Linux machine):
 
-    $ export C_INCLUDE_PATH=/opt/local/include
-    $ perl Makefile.PL --sasl LIBS="-L/opt/local/lib -lgsasl -lrt"
+    $ perl Makefile.PL --ssl --sasl
+    $ grep "LIBS =>" Makefile
+    #     LIBS => [q[-lssl -lcrypto -lgsasl -lrt]]
+
+Or, on Mac OSX:
+
+    $ perl Makefile.PL --ssl --sasl
+    $ grep "LIBS =>" Makefile
+    #     LIBS => [q[-lssl -lcrypto -lgsasl]]
+
+Then, prepend your library path to the `q[]` quoted part of the Makefile
+line and pass it as the `LIBS` argument on the command line.  Be sure your
+include path is available to your compiler, possibly with the
+`C_INCLUDE_PATH` environment variable.
 
-The specific list of libraries may be different by platform.
+For example, assuming we use the Linux example above with libssl-dev
+installed normally in `/usr/local` but libgsasl installed in `/opt/local`,
+we need to configure the include and lib paths so that libgsasl can be
+found.
+
+The `LIBS` line in the Makefile had `q[-lssl -lcrypto -lgsasl -lrt]` so
+we prepend `-L/opt/local/lib` and use that for the `LIBS` parameter on
+the command line:
+
+    $ export C_INCLUDE_PATH=/opt/local/include
+    $ perl Makefile.PL --ssl --sasl \
+        LIBS="-L/opt/local/lib -lssl -lcrypto -lgsasl -lrt"
 
 Note: even though you specify the libraries and paths with `LIBS` you will
 still need to pass "--ssl" or "--sasl" (or set the corresponding
diff --git a/MANIFEST b/MANIFEST
index d4f6b43..111c6cf 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,4 +1,4 @@
-# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.020.
+# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.039.
 CONTRIBUTING.md
 Changes
 INSTALL.md
@@ -11,8 +11,6 @@ README
 README.md
 bson/b64_ntop.h
 bson/b64_pton.h
-bson/bcon.c
-bson/bcon.h
 bson/bson-atomic.h
 bson/bson-clock.c
 bson/bson-clock.h
@@ -120,6 +118,7 @@ t/errors.t
 t/fsync.t
 t/gridfs.t
 t/img.png
+t/indexes.t
 t/input.txt
 t/lib/MongoDBTest.pm
 t/max_time_ms.t
@@ -127,6 +126,7 @@ t/readpref.t
 t/regex.t
 t/regexp_obj.t
 t/threads/basic.t
+t/threads/bson.t
 t/threads/cursor.t
 t/threads/oid.t
 t/types.t
@@ -137,10 +137,10 @@ xs/Cursor.xs
 xs/Mongo.xs
 xs/MongoClient.xs
 xs/OID.xs
+xt/author/test-version.t
 xt/release/check-jira-in-changes.t
 xt/release/minimum-version.t
 xt/release/pod-syntax.t
-xt/release/test-version.t
 yajl/LICENSE
 yajl/yajl.c
 yajl/yajl_alloc.c
diff --git a/META.json b/META.json
index 38b35c2..68575e3 100644
--- a/META.json
+++ b/META.json
@@ -1,19 +1,19 @@
 {
    "abstract" : "Official MongoDB Driver for Perl",
    "author" : [
-      "David Golden <david.golden at mongodb.org>",
-      "Mike Friedman <friedo at mongodb.com>",
-      "Kristina Chodorow <kristina at mongodb.org>",
+      "David Golden <david at mongodb.com>",
+      "Mike Friedman <friedo at friedo.com>",
+      "Kristina Chodorow <k.chodorow at gmail.com>",
       "Florian Ragwitz <rafl at debian.org>"
    ],
    "dynamic_config" : 0,
-   "generated_by" : "Dist::Zilla version 5.020, CPAN::Meta::Converter version 2.142060",
+   "generated_by" : "Dist::Zilla version 5.039, CPAN::Meta::Converter version 2.150005",
    "license" : [
       "apache_2_0"
    ],
    "meta-spec" : {
       "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
-      "version" : "2"
+      "version" : 2
    },
    "name" : "MongoDB",
    "no_index" : {
@@ -34,11 +34,14 @@
       },
       "develop" : {
          "requires" : {
-            "Test::Pod" : "1.41"
+            "Test::More" : "0",
+            "Test::Pod" : "1.41",
+            "Test::Version" : "1"
          }
       },
       "runtime" : {
          "requires" : {
+            "Authen::SCRAM::Client" : "0.003",
             "Carp" : "0",
             "Class::MOP::Class" : "0",
             "DateTime" : "0.78",
@@ -46,6 +49,7 @@
             "Encode" : "0",
             "Exporter" : "5.57",
             "IO::File" : "0",
+            "MIME::Base64" : "0",
             "Moose" : "0",
             "Moose::Meta::Class" : "0",
             "Moose::Role" : "0",
@@ -75,10 +79,8 @@
          },
          "requires" : {
             "Data::Dumper" : "0",
-            "Data::Types" : "0",
             "DateTime::Tiny" : "0",
             "ExtUtils::MakeMaker" : "0",
-            "File::Slurp" : "0",
             "File::Spec" : "0",
             "File::Temp" : "0",
             "FileHandle" : "0",
@@ -89,7 +91,7 @@
             "Test::Warn" : "0",
             "bigint" : "0",
             "lib" : "0",
-            "threads" : "0",
+            "threads::shared" : "0",
             "utf8" : "0"
          }
       }
@@ -97,103 +99,103 @@
    "provides" : {
       "MongoDB" : {
          "file" : "lib/MongoDB.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::BSON" : {
          "file" : "lib/MongoDB/BSON.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::BSON::Binary" : {
          "file" : "lib/MongoDB/BSON/Binary.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::BSON::Regexp" : {
          "file" : "lib/MongoDB/BSON/Regexp.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::BulkWrite" : {
          "file" : "lib/MongoDB/BulkWrite.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::BulkWriteView" : {
          "file" : "lib/MongoDB/BulkWriteView.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::Code" : {
          "file" : "lib/MongoDB/Code.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::Collection" : {
          "file" : "lib/MongoDB/Collection.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::CommandResult" : {
          "file" : "lib/MongoDB/CommandResult.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::Connection" : {
          "file" : "lib/MongoDB/Connection.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::ConnectionError" : {
          "file" : "lib/MongoDB/Error.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::Cursor" : {
          "file" : "lib/MongoDB/Cursor.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::DBRef" : {
          "file" : "lib/MongoDB/DBRef.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::Database" : {
          "file" : "lib/MongoDB/Database.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::DatabaseError" : {
          "file" : "lib/MongoDB/Error.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::DocumentSizeError" : {
          "file" : "lib/MongoDB/Error.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::Error" : {
          "file" : "lib/MongoDB/Error.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::GridFS" : {
          "file" : "lib/MongoDB/GridFS.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::GridFS::File" : {
          "file" : "lib/MongoDB/GridFS/File.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::MongoClient" : {
          "file" : "lib/MongoDB/MongoClient.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::OID" : {
          "file" : "lib/MongoDB/OID.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::Timestamp" : {
          "file" : "lib/MongoDB/Timestamp.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::WriteConcernError" : {
          "file" : "lib/MongoDB/Error.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::WriteError" : {
          "file" : "lib/MongoDB/Error.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       },
       "MongoDB::WriteResult" : {
          "file" : "lib/MongoDB/WriteResult.pm",
-         "version" : "v0.705.0.0"
+         "version" : "v0.708.4.0"
       }
    },
    "release_status" : "stable",
@@ -208,6 +210,6 @@
          "web" : "https://github.com/mongodb/mongo-perl-driver"
       }
    },
-   "version" : "v0.705.0.0"
+   "version" : "v0.708.4.0"
 }
 
diff --git a/META.yml b/META.yml
index 9550498..7d3438c 100644
--- a/META.yml
+++ b/META.yml
@@ -1,16 +1,14 @@
 ---
 abstract: 'Official MongoDB Driver for Perl'
 author:
-  - 'David Golden <david.golden at mongodb.org>'
-  - 'Mike Friedman <friedo at mongodb.com>'
-  - 'Kristina Chodorow <kristina at mongodb.org>'
+  - 'David Golden <david at mongodb.com>'
+  - 'Mike Friedman <friedo at friedo.com>'
+  - 'Kristina Chodorow <k.chodorow at gmail.com>'
   - 'Florian Ragwitz <rafl at debian.org>'
 build_requires:
   Data::Dumper: '0'
-  Data::Types: '0'
   DateTime::Tiny: '0'
   ExtUtils::MakeMaker: '0'
-  File::Slurp: '0'
   File::Spec: '0'
   File::Temp: '0'
   FileHandle: '0'
@@ -21,14 +19,14 @@ build_requires:
   Test::Warn: '0'
   bigint: '0'
   lib: '0'
-  threads: '0'
+  threads::shared: '0'
   utf8: '0'
 configure_requires:
   Config::AutoConf: '0.22'
   ExtUtils::MakeMaker: '0'
   Path::Tiny: '0.052'
 dynamic_config: 0
-generated_by: 'Dist::Zilla version 5.020, CPAN::Meta::Converter version 2.142060'
+generated_by: 'Dist::Zilla version 5.039, CPAN::Meta::Converter version 2.150005'
 license: apache
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -43,80 +41,81 @@ no_index:
 provides:
   MongoDB:
     file: lib/MongoDB.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::BSON:
     file: lib/MongoDB/BSON.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::BSON::Binary:
     file: lib/MongoDB/BSON/Binary.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::BSON::Regexp:
     file: lib/MongoDB/BSON/Regexp.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::BulkWrite:
     file: lib/MongoDB/BulkWrite.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::BulkWriteView:
     file: lib/MongoDB/BulkWriteView.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::Code:
     file: lib/MongoDB/Code.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::Collection:
     file: lib/MongoDB/Collection.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::CommandResult:
     file: lib/MongoDB/CommandResult.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::Connection:
     file: lib/MongoDB/Connection.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::ConnectionError:
     file: lib/MongoDB/Error.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::Cursor:
     file: lib/MongoDB/Cursor.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::DBRef:
     file: lib/MongoDB/DBRef.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::Database:
     file: lib/MongoDB/Database.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::DatabaseError:
     file: lib/MongoDB/Error.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::DocumentSizeError:
     file: lib/MongoDB/Error.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::Error:
     file: lib/MongoDB/Error.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::GridFS:
     file: lib/MongoDB/GridFS.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::GridFS::File:
     file: lib/MongoDB/GridFS/File.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::MongoClient:
     file: lib/MongoDB/MongoClient.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::OID:
     file: lib/MongoDB/OID.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::Timestamp:
     file: lib/MongoDB/Timestamp.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::WriteConcernError:
     file: lib/MongoDB/Error.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::WriteError:
     file: lib/MongoDB/Error.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
   MongoDB::WriteResult:
     file: lib/MongoDB/WriteResult.pm
-    version: v0.705.0.0
+    version: v0.708.4.0
 requires:
+  Authen::SCRAM::Client: '0.003'
   Carp: '0'
   Class::MOP::Class: '0'
   DateTime: '0.78'
@@ -124,6 +123,7 @@ requires:
   Encode: '0'
   Exporter: '5.57'
   IO::File: '0'
+  MIME::Base64: '0'
   Moose: '0'
   Moose::Meta::Class: '0'
   Moose::Role: '0'
@@ -149,4 +149,4 @@ resources:
   bugtracker: https://jira.mongodb.org/browse/PERL
   homepage: https://github.com/mongodb/mongo-perl-driver
   repository: https://github.com/mongodb/mongo-perl-driver.git
-version: v0.705.0.0
+version: v0.708.4.0
diff --git a/Makefile.PL b/Makefile.PL
index 4f0564a..63b4137 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -27,6 +27,7 @@ if ( $ENV{PERL_MONGODB_WITH_SASL} || grep { $_ eq '--sasl' } @ARGV ) {
 cc_lib_links( @cc_lib_links ) if @cc_lib_links;
 cc_optimize_flags( @cc_optimize_flags ) if @cc_optimize_flags;
 
+requires 'Authen::SCRAM::Client' => '0.003';
 requires 'Carp';
 requires 'Class::MOP::Class';
 requires 'DateTime' => '0.78';
@@ -48,12 +49,10 @@ requires 'version';
 
 test_requires 'Data::Dump';
 test_requires 'Data::Dumper';
-test_requires 'Data::Types';
 test_requires 'DateTime::Tiny';
 test_requires 'Devel::Peek';
 test_requires 'File::Copy';
 test_requires 'File::Path';
-test_requires 'File::Slurp';
 test_requires 'File::Spec';
 test_requires 'File::Temp' => '0.17';
 test_requires 'FileHandle';
diff --git a/README b/README
index d143b6f..f189a46 100644
--- a/README
+++ b/README
@@ -1,16 +1,16 @@
 
 
 This archive contains the distribution MongoDB,
-version v0.705.0.0:
+version v0.708.4.0:
 
   Official MongoDB Driver for Perl
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
   The Apache License, Version 2.0, January 2004
 
 
-This README file was generated by Dist::Zilla::Plugin::Readme v5.020.
+This README file was generated by Dist::Zilla::Plugin::Readme v5.039.
 
diff --git a/bson/bcon.c b/bson/bcon.c
deleted file mode 100644
index a926026..0000000
--- a/bson/bcon.c
+++ /dev/null
@@ -1,1024 +0,0 @@
-/*
- * @file bcon.c
- * @brief BCON (BSON C Object Notation) Implementation
- */
-
-/*    Copyright 2009-2013 MongoDB, Inc.
- *
- *    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.
- */
-
-#include "bcon.h"
-
-/* These stack manipulation macros are used to manage append recursion in
- * bcon_append_ctx_va().  They take care of some awkward dereference rules (the
- * real bson object isn't in the stack, but accessed by pointer) and add in run
- * time asserts to make sure we don't blow the stack in either direction */
-
-#define STACK_ELE(_delta, _name) (ctx->stack[(_delta) + ctx->n]._name)
-
-#define STACK_BSON(_delta) ( \
-      ((_delta) + ctx->n) == 0 \
-      ? bson \
-      : &STACK_ELE (_delta, bson) \
-      )
-
-#define STACK_ITER(_delta) ( \
-      ((_delta) + ctx->n) == 0 \
-      ? &root_iter \
-      : &STACK_ELE (_delta, iter) \
-      )
-
-#define STACK_BSON_PARENT STACK_BSON (-1)
-#define STACK_BSON_CHILD STACK_BSON (0)
-
-#define STACK_ITER_PARENT STACK_ITER (-1)
-#define STACK_ITER_CHILD STACK_ITER (0)
-
-#define STACK_I STACK_ELE (0, i)
-#define STACK_IS_ARRAY STACK_ELE (0, is_array)
-
-#define STACK_PUSH_ARRAY(statement) \
-   do { \
-      assert (ctx->n < (BCON_STACK_MAX - 1)); \
-      ctx->n++; \
-      STACK_I = 0; \
-      STACK_IS_ARRAY = 1; \
-      statement; \
-   } while (0)
-
-#define STACK_PUSH_DOC(statement) \
-   do { \
-      assert (ctx->n < (BCON_STACK_MAX - 1)); \
-      ctx->n++; \
-      STACK_IS_ARRAY = 0; \
-      statement; \
-   } while (0)
-
-#define STACK_POP_ARRAY(statement) \
-   do { \
-      assert (STACK_IS_ARRAY); \
-      assert (ctx->n != 0); \
-      statement; \
-      ctx->n--; \
-   } while (0)
-
-#define STACK_POP_DOC(statement) \
-   do { \
-      assert (!STACK_IS_ARRAY); \
-      assert (ctx->n != 0); \
-      statement; \
-      ctx->n--; \
-   } while (0)
-
-/* This is a landing pad union for all of the types we can process with bcon.
- * We need actual storage for this to capture the return value of va_arg, which
- * takes multiple calls to get everything we need for some complex types */
-typedef union bcon_append {
-   char   *UTF8;
-   double  DOUBLE;
-   bson_t *DOCUMENT;
-   bson_t *ARRAY;
-   bson_t *BCON;
-
-   struct
-   {
-      bson_subtype_t subtype;
-      uint8_t  *binary;
-      uint32_t  length;
-   } BIN;
-
-   bson_oid_t    *OID;
-   bool BOOL;
-   int64_t   DATE_TIME;
-
-   struct
-   {
-      char *regex;
-      char *flags;
-   } REGEX;
-
-   struct
-   {
-      char       *collection;
-      bson_oid_t *oid;
-   } DBPOINTER;
-
-   const char *CODE;
-
-   char *SYMBOL;
-
-   struct
-   {
-      const char *js;
-      bson_t     *scope;
-   } CODEWSCOPE;
-
-   int32_t INT32;
-
-   struct
-   {
-      uint32_t timestamp;
-      uint32_t increment;
-   } TIMESTAMP;
-
-   int64_t       INT64;
-   const bson_iter_t *ITER;
-} bcon_append_t;
-
-/* same as bcon_append_t.  Some extra symbols and varying types that handle the
- * differences between bson_append and bson_iter */
-typedef union bcon_extract {
-   bson_type_t  TYPE;
-   bson_iter_t *ITER;
-   const char  *key;
-   const char **UTF8;
-   double      *DOUBLE;
-   bson_t      *DOCUMENT;
-   bson_t      *ARRAY;
-
-   struct
-   {
-      bson_subtype_t      *subtype;
-      const uint8_t **binary;
-      uint32_t       *length;
-   } BIN;
-
-   const bson_oid_t **OID;
-   bool *BOOL;
-   int64_t      *DATE_TIME;
-
-   struct
-   {
-      const char **regex;
-      const char **flags;
-   } REGEX;
-
-   struct
-   {
-      const char       **collection;
-      const bson_oid_t **oid;
-   } DBPOINTER;
-
-   const char **CODE;
-
-   const char **SYMBOL;
-
-   struct
-   {
-      const char **js;
-      bson_t      *scope;
-   } CODEWSCOPE;
-
-   int32_t *INT32;
-
-   struct
-   {
-      uint32_t *timestamp;
-      uint32_t *increment;
-   } TIMESTAMP;
-
-   int64_t *INT64;
-} bcon_extract_t;
-
-static const char *gBconMagic = "BCON_MAGIC";
-static const char *gBconeMagic = "BCONE_MAGIC";
-
-const char *
-bson_bcon_magic (void)
-{
-   return gBconMagic;
-}
-
-
-const char *
-bson_bcone_magic (void)
-{
-   return gBconeMagic;
-}
-
-static void
-_noop (void)
-{
-}
-
-/* appends val to the passed bson object.  Meant to be a super simple dispatch
- * table */
-static void
-_bcon_append_single (bson_t        *bson,
-                     bcon_type_t    type,
-                     const char    *key,
-                     bcon_append_t *val)
-{
-   switch ((int)type) {
-   case BCON_TYPE_UTF8:
-      bson_append_utf8 (bson, key, -1, val->UTF8, -1);
-      break;
-   case BCON_TYPE_DOUBLE:
-      bson_append_double (bson, key, -1, val->DOUBLE);
-      break;
-   case BCON_TYPE_BIN: {
-         bson_append_binary (bson, key, -1, val->BIN.subtype, val->BIN.binary,
-                             val->BIN.length);
-         break;
-      }
-   case BCON_TYPE_UNDEFINED:
-      bson_append_undefined (bson, key, -1);
-      break;
-   case BCON_TYPE_OID:
-      bson_append_oid (bson, key, -1, val->OID);
-      break;
-   case BCON_TYPE_BOOL:
-      bson_append_bool (bson, key, -1, (bool)val->BOOL);
-      break;
-   case BCON_TYPE_DATE_TIME:
-      bson_append_date_time (bson, key, -1, val->DATE_TIME);
-      break;
-   case BCON_TYPE_NULL:
-      bson_append_null (bson, key, -1);
-      break;
-   case BCON_TYPE_REGEX: {
-         bson_append_regex (bson, key, -1, val->REGEX.regex, val->REGEX.flags);
-         break;
-      }
-   case BCON_TYPE_DBPOINTER: {
-         bson_append_dbpointer (bson, key, -1, val->DBPOINTER.collection,
-                                val->DBPOINTER.oid);
-         break;
-      }
-   case BCON_TYPE_CODE:
-      bson_append_code (bson, key, -1, val->CODE);
-      break;
-   case BCON_TYPE_SYMBOL:
-      bson_append_symbol (bson, key, -1, val->SYMBOL, -1);
-      break;
-   case BCON_TYPE_CODEWSCOPE:
-      bson_append_code_with_scope (bson, key, -1, val->CODEWSCOPE.js,
-                                   val->CODEWSCOPE.scope);
-      break;
-   case BCON_TYPE_INT32:
-      bson_append_int32 (bson, key, -1, val->INT32);
-      break;
-   case BCON_TYPE_TIMESTAMP: {
-         bson_append_timestamp (bson, key, -1, val->TIMESTAMP.timestamp,
-                                val->TIMESTAMP.increment);
-         break;
-      }
-   case BCON_TYPE_INT64:
-      bson_append_int64 (bson, key, -1, val->INT64);
-      break;
-   case BCON_TYPE_MAXKEY:
-      bson_append_maxkey (bson, key, -1);
-      break;
-   case BCON_TYPE_MINKEY:
-      bson_append_minkey (bson, key, -1);
-      break;
-   case BCON_TYPE_ARRAY: {
-         bson_append_array (bson, key, -1, val->ARRAY);
-         break;
-      }
-   case BCON_TYPE_DOCUMENT: {
-         bson_append_document (bson, key, -1, val->DOCUMENT);
-         break;
-      }
-   case BCON_TYPE_ITER:
-      bson_append_iter (bson, key, -1, val->ITER);
-      break;
-   default:
-      assert (0);
-      break;
-   }
-}
-
-#define CHECK_TYPE(_type) \
-   do { \
-      if (bson_iter_type (iter) != (_type)) { return false; } \
-   } while (0)
-
-/* extracts the value under the iterator and writes it to val.  returns false
- * if the iterator type doesn't match the token type.
- *
- * There are two magic tokens:
- *
- * BCONE_SKIP -
- *    Let's us verify that a key has a type, without caring about its value.
- *    This allows for wider declarative BSON verification
- *
- * BCONE_ITER -
- *    Returns the underlying iterator.  This could allow for more complicated,
- *    procedural verification (if a parameter could have multiple types).
- * */
-static bool
-_bcon_extract_single (const bson_iter_t *iter,
-                      bcon_type_t        type,
-                      bcon_extract_t    *val)
-{
-   switch ((int)type) {
-   case BCON_TYPE_UTF8:
-      CHECK_TYPE (BSON_TYPE_UTF8);
-      *val->UTF8 = bson_iter_utf8 (iter, NULL);
-      break;
-   case BCON_TYPE_DOUBLE:
-      CHECK_TYPE (BSON_TYPE_DOUBLE);
-      *val->DOUBLE = bson_iter_double (iter);
-      break;
-   case BCON_TYPE_BIN:
-      CHECK_TYPE (BSON_TYPE_BINARY);
-      bson_iter_binary (iter, val->BIN.subtype, val->BIN.length,
-                        val->BIN.binary);
-      break;
-   case BCON_TYPE_UNDEFINED:
-      CHECK_TYPE (BSON_TYPE_UNDEFINED);
-      break;
-   case BCON_TYPE_OID:
-      CHECK_TYPE (BSON_TYPE_OID);
-      *val->OID = bson_iter_oid (iter);
-      break;
-   case BCON_TYPE_BOOL:
-      CHECK_TYPE (BSON_TYPE_BOOL);
-      *val->BOOL = bson_iter_bool (iter);
-      break;
-   case BCON_TYPE_DATE_TIME:
-      CHECK_TYPE (BSON_TYPE_DATE_TIME);
-      *val->DATE_TIME = bson_iter_date_time (iter);
-      break;
-   case BCON_TYPE_NULL:
-      CHECK_TYPE (BSON_TYPE_NULL);
-      break;
-   case BCON_TYPE_REGEX:
-      CHECK_TYPE (BSON_TYPE_REGEX);
-      *val->REGEX.regex = bson_iter_regex (iter, val->REGEX.flags);
-
-      break;
-   case BCON_TYPE_DBPOINTER:
-      CHECK_TYPE (BSON_TYPE_DBPOINTER);
-      bson_iter_dbpointer (iter, NULL, val->DBPOINTER.collection,
-                           val->DBPOINTER.oid);
-      break;
-   case BCON_TYPE_CODE:
-      CHECK_TYPE (BSON_TYPE_CODE);
-      *val->CODE = bson_iter_code (iter, NULL);
-      break;
-   case BCON_TYPE_SYMBOL:
-      CHECK_TYPE (BSON_TYPE_SYMBOL);
-      *val->SYMBOL = bson_iter_symbol (iter, NULL);
-      break;
-   case BCON_TYPE_CODEWSCOPE: {
-         const uint8_t *buf;
-         uint32_t len;
-
-         CHECK_TYPE (BSON_TYPE_CODEWSCOPE);
-
-         *val->CODEWSCOPE.js = bson_iter_codewscope (iter, NULL, &len, &buf);
-
-         bson_init_static (val->CODEWSCOPE.scope, buf, len);
-         break;
-      }
-   case BCON_TYPE_INT32:
-      CHECK_TYPE (BSON_TYPE_INT32);
-      *val->INT32 = bson_iter_int32 (iter);
-      break;
-   case BCON_TYPE_TIMESTAMP:
-      CHECK_TYPE (BSON_TYPE_TIMESTAMP);
-      bson_iter_timestamp (iter, val->TIMESTAMP.timestamp,
-                           val->TIMESTAMP.increment);
-      break;
-   case BCON_TYPE_INT64:
-      CHECK_TYPE (BSON_TYPE_INT64);
-      *val->INT64 = bson_iter_int64 (iter);
-      break;
-   case BCON_TYPE_MAXKEY:
-      CHECK_TYPE (BSON_TYPE_MAXKEY);
-      break;
-   case BCON_TYPE_MINKEY:
-      CHECK_TYPE (BSON_TYPE_MINKEY);
-      break;
-   case BCON_TYPE_ARRAY: {
-         const uint8_t *buf;
-         uint32_t len;
-
-         CHECK_TYPE (BSON_TYPE_ARRAY);
-
-         bson_iter_array (iter, &len, &buf);
-
-         bson_init_static (val->ARRAY, buf, len);
-         break;
-      }
-   case BCON_TYPE_DOCUMENT: {
-         const uint8_t *buf;
-         uint32_t len;
-
-         CHECK_TYPE (BSON_TYPE_DOCUMENT);
-
-         bson_iter_document (iter, &len, &buf);
-
-         bson_init_static (val->DOCUMENT, buf, len);
-         break;
-      }
-   case BCON_TYPE_SKIP:
-      CHECK_TYPE (val->TYPE);
-      break;
-   case BCON_TYPE_ITER:
-      memcpy (val->ITER, iter, sizeof *iter);
-      break;
-   default:
-      assert (0);
-      break;
-   }
-
-   return true;
-}
-
-/* Consumes ap, storing output values into u and returning the type of the
- * captured token.
- *
- * The basic workflow goes like this:
- *
- * 1. Look at the current arg.  It will be a char *
- *    a. If it's a NULL, we're done processing.
- *    b. If it's BCON_MAGIC (a symbol with storage in this module)
- *       I. The next token is the type
- *       II. The type specifies how many args to eat and their types
- *    c. Otherwise it's either recursion related or a raw string
- *       I. If the first byte is '{', '}', '[', or ']' pass back an
- *          appropriate recursion token
- *       II. If not, just call it a UTF8 token and pass that back
- */
-bcon_type_t
-_bcon_append_tokenize (va_list       *ap,
-                       bcon_append_t *u)
-{
-   char *mark;
-   bcon_type_t type;
-
-   mark = va_arg (*ap, char *);
-
-   assert (mark != BCONE_MAGIC);
-
-   if (mark == NULL) {
-      type = BCON_TYPE_END;
-   } else if (mark == BCON_MAGIC) {
-      type = va_arg (*ap, bcon_type_t);
-
-      switch ((int)type) {
-      case BCON_TYPE_UTF8:
-         u->UTF8 = va_arg (*ap, char *);
-         break;
-      case BCON_TYPE_DOUBLE:
-         u->DOUBLE = va_arg (*ap, double);
-         break;
-      case BCON_TYPE_DOCUMENT:
-         u->DOCUMENT = va_arg (*ap, bson_t *);
-         break;
-      case BCON_TYPE_ARRAY:
-         u->ARRAY = va_arg (*ap, bson_t *);
-         break;
-      case BCON_TYPE_BIN:
-         u->BIN.subtype = va_arg (*ap, bson_subtype_t);
-         u->BIN.binary = va_arg (*ap, uint8_t *);
-         u->BIN.length = va_arg (*ap, uint32_t);
-         break;
-      case BCON_TYPE_UNDEFINED:
-         break;
-      case BCON_TYPE_OID:
-         u->OID = va_arg (*ap, bson_oid_t *);
-         break;
-      case BCON_TYPE_BOOL:
-         u->BOOL = va_arg (*ap, int);
-         break;
-      case BCON_TYPE_DATE_TIME:
-         u->DATE_TIME = va_arg (*ap, int64_t);
-         break;
-      case BCON_TYPE_NULL:
-         break;
-      case BCON_TYPE_REGEX:
-         u->REGEX.regex = va_arg (*ap, char *);
-         u->REGEX.flags = va_arg (*ap, char *);
-         break;
-      case BCON_TYPE_DBPOINTER:
-         u->DBPOINTER.collection = va_arg (*ap, char *);
-         u->DBPOINTER.oid = va_arg (*ap, bson_oid_t *);
-         break;
-      case BCON_TYPE_CODE:
-         u->CODE = va_arg (*ap, char *);
-         break;
-      case BCON_TYPE_SYMBOL:
-         u->SYMBOL = va_arg (*ap, char *);
-         break;
-      case BCON_TYPE_CODEWSCOPE:
-         u->CODEWSCOPE.js = va_arg (*ap, char *);
-         u->CODEWSCOPE.scope = va_arg (*ap, bson_t *);
-         break;
-      case BCON_TYPE_INT32:
-         u->INT32 = va_arg (*ap, int32_t);
-         break;
-      case BCON_TYPE_TIMESTAMP:
-         u->TIMESTAMP.timestamp = va_arg (*ap, uint32_t);
-         u->TIMESTAMP.increment = va_arg (*ap, uint32_t);
-         break;
-      case BCON_TYPE_INT64:
-         u->INT64 = va_arg (*ap, int64_t);
-         break;
-      case BCON_TYPE_MAXKEY:
-         break;
-      case BCON_TYPE_MINKEY:
-         break;
-      case BCON_TYPE_BCON:
-         u->BCON = va_arg (*ap, bson_t *);
-         break;
-      case BCON_TYPE_ITER:
-         u->ITER = va_arg (*ap, const bson_iter_t *);
-         break;
-      default:
-         assert (0);
-         break;
-      }
-   } else {
-      switch (mark[0]) {
-      case '{':
-         type = BCON_TYPE_DOC_START;
-         break;
-      case '}':
-         type = BCON_TYPE_DOC_END;
-         break;
-      case '[':
-         type = BCON_TYPE_ARRAY_START;
-         break;
-      case ']':
-         type = BCON_TYPE_ARRAY_END;
-         break;
-
-      default:
-         type = BCON_TYPE_UTF8;
-         u->UTF8 = mark;
-         break;
-      }
-   }
-
-   return type;
-}
-
-
-/* Consumes ap, storing output values into u and returning the type of the
- * captured token.
- *
- * The basic workflow goes like this:
- *
- * 1. Look at the current arg.  It will be a char *
- *    a. If it's a NULL, we're done processing.
- *    b. If it's BCONE_MAGIC (a symbol with storage in this module)
- *       I. The next token is the type
- *       II. The type specifies how many args to eat and their types
- *    c. Otherwise it's either recursion related or a raw string
- *       I. If the first byte is '{', '}', '[', or ']' pass back an
- *          appropriate recursion token
- *       II. If not, just call it a UTF8 token and pass that back
- */
-bcon_type_t
-_bcon_extract_tokenize (va_list        *ap,
-                        bcon_extract_t *u)
-{
-   char *mark;
-   bcon_type_t type;
-
-   mark = va_arg (*ap, char *);
-
-   assert (mark != BCON_MAGIC);
-
-   if (mark == NULL) {
-      type = BCON_TYPE_END;
-   } else if (mark == BCONE_MAGIC) {
-      type = va_arg (*ap, bcon_type_t);
-
-      switch ((int)type) {
-      case BCON_TYPE_UTF8:
-         u->UTF8 = va_arg (*ap, const char **);
-         break;
-      case BCON_TYPE_DOUBLE:
-         u->DOUBLE = va_arg (*ap, double *);
-         break;
-      case BCON_TYPE_DOCUMENT:
-         u->DOCUMENT = va_arg (*ap, bson_t *);
-         break;
-      case BCON_TYPE_ARRAY:
-         u->ARRAY = va_arg (*ap, bson_t *);
-         break;
-      case BCON_TYPE_BIN:
-         u->BIN.subtype = va_arg (*ap, bson_subtype_t *);
-         u->BIN.binary = va_arg (*ap, const uint8_t * *);
-         u->BIN.length = va_arg (*ap, uint32_t *);
-         break;
-      case BCON_TYPE_UNDEFINED:
-         break;
-      case BCON_TYPE_OID:
-         u->OID = va_arg (*ap, const bson_oid_t * *);
-         break;
-      case BCON_TYPE_BOOL:
-         u->BOOL = va_arg (*ap, bool *);
-         break;
-      case BCON_TYPE_DATE_TIME:
-         u->DATE_TIME = va_arg (*ap, int64_t *);
-         break;
-      case BCON_TYPE_NULL:
-         break;
-      case BCON_TYPE_REGEX:
-         u->REGEX.regex = va_arg (*ap, const char **);
-         u->REGEX.flags = va_arg (*ap, const char **);
-         break;
-      case BCON_TYPE_DBPOINTER:
-         u->DBPOINTER.collection = va_arg (*ap, const char **);
-         u->DBPOINTER.oid = va_arg (*ap, const bson_oid_t * *);
-         break;
-      case BCON_TYPE_CODE:
-         u->CODE = va_arg (*ap, const char **);
-         break;
-      case BCON_TYPE_SYMBOL:
-         u->SYMBOL = va_arg (*ap, const char **);
-         break;
-      case BCON_TYPE_CODEWSCOPE:
-         u->CODEWSCOPE.js = va_arg (*ap, const char **);
-         u->CODEWSCOPE.scope = va_arg (*ap, bson_t *);
-         break;
-      case BCON_TYPE_INT32:
-         u->INT32 = va_arg (*ap, int32_t *);
-         break;
-      case BCON_TYPE_TIMESTAMP:
-         u->TIMESTAMP.timestamp = va_arg (*ap, uint32_t *);
-         u->TIMESTAMP.increment = va_arg (*ap, uint32_t *);
-         break;
-      case BCON_TYPE_INT64:
-         u->INT64 = va_arg (*ap, int64_t *);
-         break;
-      case BCON_TYPE_MAXKEY:
-         break;
-      case BCON_TYPE_MINKEY:
-         break;
-      case BCON_TYPE_SKIP:
-         u->TYPE = va_arg (*ap, bson_type_t);
-         break;
-      case BCON_TYPE_ITER:
-         u->ITER = va_arg (*ap, bson_iter_t *);
-         break;
-      default:
-         assert (0);
-         break;
-      }
-   } else {
-      switch (mark[0]) {
-      case '{':
-         type = BCON_TYPE_DOC_START;
-         break;
-      case '}':
-         type = BCON_TYPE_DOC_END;
-         break;
-      case '[':
-         type = BCON_TYPE_ARRAY_START;
-         break;
-      case ']':
-         type = BCON_TYPE_ARRAY_END;
-         break;
-
-      default:
-         type = BCON_TYPE_RAW;
-         u->key = mark;
-         break;
-      }
-   }
-
-   return type;
-}
-
-
-/* This trivial utility function is useful for concatenating a bson object onto
- * the end of another, ignoring the keys from the source bson object and
- * continuing to use and increment the keys from the source.  It's only useful
- * when called from bcon_append_ctx_va */
-static void
-_bson_concat_array (bson_t            *dest,
-                    const bson_t      *src,
-                    bcon_append_ctx_t *ctx)
-{
-   const char *key;
-   char i_str[11];
-   bson_iter_t iter;
-
-   bson_iter_init (&iter, src);
-
-   STACK_I--;
-
-   while (bson_iter_next (&iter)) {
-      bson_uint32_to_string (STACK_I, &key, i_str, 11);
-      STACK_I++;
-
-      bson_append_iter (dest, key, -1, &iter);
-   }
-}
-
-
-/* Append_ctx_va consumes the va_list until NULL is found, appending into bson
- * as tokens are found.  It can receive or return an in-progress bson object
- * via the ctx param.  It can also operate on the middle of a va_list, and so
- * can be wrapped inside of another varargs function.
- *
- * Note that passing in a va_list that isn't perferectly formatted for BCON
- * ingestion will almost certainly result in undefined behavior
- *
- * The workflow relies on the passed ctx object, which holds a stack of bson
- * objects, along with metadata (if the emedded layer is an array, and which
- * element it is on if so).  We iterate, generating tokens from the va_list,
- * until we reach an END token.  If any errors occur, we just blow up (the
- * var_args stuff is already incredibly fragile to mistakes, and we have no way
- * of introspecting, so just don't screw it up).
- *
- * There are also a few STACK_* macros in here which manimpulate ctx that are
- * defined up top.
- * */
-void
-bcon_append_ctx_va (bson_t            *bson,
-                    bcon_append_ctx_t *ctx,
-                    va_list           *ap)
-{
-   bcon_type_t type;
-   const char *key;
-
-   char i_str[11];
-
-   bcon_append_t u = { 0 };
-
-   while (1) {
-      if (STACK_IS_ARRAY) {
-         bson_uint32_to_string (STACK_I, &key, i_str, 11);
-         STACK_I++;
-      } else {
-         type = _bcon_append_tokenize (ap, &u);
-
-         if (type == BCON_TYPE_END) {
-            return;
-         }
-
-         if (type == BCON_TYPE_DOC_END) {
-            STACK_POP_DOC (bson_append_document_end (STACK_BSON_PARENT,
-                                                     STACK_BSON_CHILD));
-            continue;
-         }
-
-         if (type == BCON_TYPE_BCON) {
-            bson_concat (STACK_BSON_CHILD, u.BCON);
-            continue;
-         }
-
-         assert (type == BCON_TYPE_UTF8);
-
-         key = u.UTF8;
-      }
-
-      type = _bcon_append_tokenize (ap, &u);
-      assert (type != BCON_TYPE_END);
-
-      switch ((int)type) {
-      case BCON_TYPE_BCON:
-         assert (STACK_IS_ARRAY);
-         _bson_concat_array (STACK_BSON_CHILD, u.BCON, ctx);
-
-         break;
-      case BCON_TYPE_DOC_START:
-         STACK_PUSH_DOC (bson_append_document_begin (STACK_BSON_PARENT, key, -1,
-                                                     STACK_BSON_CHILD));
-         break;
-      case BCON_TYPE_DOC_END:
-         STACK_POP_DOC (bson_append_document_end (STACK_BSON_PARENT,
-                                                  STACK_BSON_CHILD));
-         break;
-      case BCON_TYPE_ARRAY_START:
-         STACK_PUSH_ARRAY (bson_append_array_begin (STACK_BSON_PARENT, key, -1,
-                                                    STACK_BSON_CHILD));
-         break;
-      case BCON_TYPE_ARRAY_END:
-         STACK_POP_ARRAY (bson_append_array_end (STACK_BSON_PARENT,
-                                                 STACK_BSON_CHILD));
-         break;
-      default:
-         _bcon_append_single (STACK_BSON_CHILD, type, key, &u);
-
-         break;
-      }
-   }
-}
-
-
-/* extract_ctx_va consumes the va_list until NULL is found, extracting values
- * as tokens are found.  It can receive or return an in-progress bson object
- * via the ctx param.  It can also operate on the middle of a va_list, and so
- * can be wrapped inside of another varargs function.
- *
- * Note that passing in a va_list that isn't perferectly formatted for BCON
- * ingestion will almost certainly result in undefined behavior
- *
- * The workflow relies on the passed ctx object, which holds a stack of iterator
- * objects, along with metadata (if the emedded layer is an array, and which
- * element it is on if so).  We iterate, generating tokens from the va_list,
- * until we reach an END token.  If any errors occur, we just blow up (the
- * var_args stuff is already incredibly fragile to mistakes, and we have no way
- * of introspecting, so just don't screw it up).
- *
- * There are also a few STACK_* macros in here which manimpulate ctx that are
- * defined up top.
- *
- * The function returns true if all tokens could be successfully matched, false
- * otherwise.
- * */
-bool
-bcon_extract_ctx_va (bson_t             *bson,
-                     bcon_extract_ctx_t *ctx,
-                     va_list            *ap)
-{
-   bcon_type_t type;
-   const char *key;
-   bson_iter_t root_iter;
-   bson_iter_t current_iter;
-
-   char i_str[11];
-
-   bcon_extract_t u = { 0 };
-
-   bson_iter_init (&root_iter, bson);
-
-   while (1) {
-      if (STACK_IS_ARRAY) {
-         bson_uint32_to_string (STACK_I, &key, i_str, 11);
-         STACK_I++;
-      } else {
-         type = _bcon_extract_tokenize (ap, &u);
-
-         if (type == BCON_TYPE_END) {
-            return true;
-         }
-
-         if (type == BCON_TYPE_DOC_END) {
-            STACK_POP_DOC (_noop ());
-            continue;
-         }
-
-         assert (type == BCON_TYPE_RAW);
-
-         key = u.key;
-      }
-
-      type = _bcon_extract_tokenize (ap, &u);
-      assert (type != BCON_TYPE_END);
-
-      if (type == BCON_TYPE_DOC_END) {
-         STACK_POP_DOC (_noop ());
-      } else if (type == BCON_TYPE_ARRAY_END) {
-         STACK_POP_ARRAY (_noop ());
-      } else {
-         memcpy (&current_iter, STACK_ITER_CHILD, sizeof current_iter);
-
-         if (!bson_iter_find (&current_iter, key)) { return false; }
-
-         switch ((int)type) {
-         case BCON_TYPE_DOC_START:
-
-            if (bson_iter_type (&current_iter) !=
-                BSON_TYPE_DOCUMENT) { return false; }
-
-            STACK_PUSH_DOC (bson_iter_recurse (&current_iter,
-                                               STACK_ITER_CHILD));
-            break;
-         case BCON_TYPE_DOC_END:
-            STACK_POP_DOC (_noop ());
-            break;
-         case BCON_TYPE_ARRAY_START:
-
-            if (bson_iter_type (&current_iter) !=
-                BSON_TYPE_ARRAY) { return false; }
-
-            STACK_PUSH_ARRAY (bson_iter_recurse (&current_iter,
-                                                 STACK_ITER_CHILD));
-            break;
-         case BCON_TYPE_ARRAY_END:
-            STACK_POP_ARRAY (_noop ());
-            break;
-         default:
-
-            if (!_bcon_extract_single (&current_iter, type, &u)) {
-               return false;
-            }
-
-            break;
-         }
-      }
-   }
-}
-
-void
-bcon_extract_ctx_init (bcon_extract_ctx_t *ctx)
-{
-   ctx->n = 0;
-   ctx->stack[0].is_array = false;
-}
-
-bool
-bcon_extract (bson_t *bson,
-              ...)
-{
-   va_list ap;
-   bcon_extract_ctx_t ctx;
-   bool r;
-
-   bcon_extract_ctx_init (&ctx);
-
-   va_start (ap, bson);
-
-   r = bcon_extract_ctx_va (bson, &ctx, &ap);
-
-   va_end (ap);
-
-   return r;
-}
-
-
-void
-bcon_append (bson_t *bson,
-             ...)
-{
-   va_list ap;
-   bcon_append_ctx_t ctx;
-
-   bcon_append_ctx_init (&ctx);
-
-   va_start (ap, bson);
-
-   bcon_append_ctx_va (bson, &ctx, &ap);
-
-   va_end (ap);
-}
-
-
-void
-bcon_append_ctx (bson_t            *bson,
-                 bcon_append_ctx_t *ctx,
-                 ...)
-{
-   va_list ap;
-
-   va_start (ap, ctx);
-
-   bcon_append_ctx_va (bson, ctx, &ap);
-
-   va_end (ap);
-}
-
-
-void
-bcon_extract_ctx (bson_t             *bson,
-                  bcon_extract_ctx_t *ctx,
-                  ...)
-{
-   va_list ap;
-
-   va_start (ap, ctx);
-
-   bcon_extract_ctx_va (bson, ctx, &ap);
-
-   va_end (ap);
-}
-
-void
-bcon_append_ctx_init (bcon_append_ctx_t *ctx)
-{
-   ctx->n = 0;
-   ctx->stack[0].is_array = 0;
-}
-
-
-bson_t *
-bcon_new (void *unused,
-          ...)
-{
-   va_list ap;
-   bcon_append_ctx_t ctx;
-   bson_t *bson;
-
-   bcon_append_ctx_init (&ctx);
-
-   bson = bson_new ();
-
-   va_start (ap, unused);
-
-   bcon_append_ctx_va (bson, &ctx, &ap);
-
-   va_end (ap);
-
-   return bson;
-}
diff --git a/bson/bcon.h b/bson/bcon.h
deleted file mode 100644
index 1b71d70..0000000
--- a/bson/bcon.h
+++ /dev/null
@@ -1,280 +0,0 @@
-/*
- * @file bcon.h
- * @brief BCON (BSON C Object Notation) Declarations
- */
-
-/*    Copyright 2009-2013 MongoDB, Inc.
- *
- *    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.
- */
-
-#ifndef BCON_H_
-#define BCON_H_
-
-#include <bson.h>
-
-#define BCON_STACK_MAX 100
-
-#define BCON_ENSURE_DECLARE(fun, type) \
-   static BSON_INLINE type bcon_ensure_##fun (type _t) { return _t; }
-
-#define BCON_ENSURE(fun, val) \
-   bcon_ensure_##fun (val)
-
-#define BCON_ENSURE_STORAGE(fun, val) \
-   bcon_ensure_##fun (&(val))
-
-BCON_ENSURE_DECLARE (const_char_ptr, const char *)
-BCON_ENSURE_DECLARE (const_char_ptr_ptr, const char **)
-BCON_ENSURE_DECLARE (double, double)
-BCON_ENSURE_DECLARE (double_ptr, double *)
-BCON_ENSURE_DECLARE (const_bson_ptr, const bson_t *)
-BCON_ENSURE_DECLARE (bson_ptr, bson_t *)
-BCON_ENSURE_DECLARE (subtype, bson_subtype_t)
-BCON_ENSURE_DECLARE (subtype_ptr, bson_subtype_t *)
-BCON_ENSURE_DECLARE (const_uint8_ptr, const uint8_t *)
-BCON_ENSURE_DECLARE (const_uint8_ptr_ptr, const uint8_t **)
-BCON_ENSURE_DECLARE (uint32, uint32_t)
-BCON_ENSURE_DECLARE (uint32_ptr, uint32_t *)
-BCON_ENSURE_DECLARE (const_oid_ptr, const bson_oid_t *)
-BCON_ENSURE_DECLARE (const_oid_ptr_ptr, const bson_oid_t **)
-BCON_ENSURE_DECLARE (int32, int32_t)
-BCON_ENSURE_DECLARE (int32_ptr, int32_t *)
-BCON_ENSURE_DECLARE (int64, int64_t)
-BCON_ENSURE_DECLARE (int64_ptr, int64_t *)
-BCON_ENSURE_DECLARE (bool, bool)
-BCON_ENSURE_DECLARE (bool_ptr, bool *)
-BCON_ENSURE_DECLARE (bson_type, bson_type_t)
-BCON_ENSURE_DECLARE (bson_iter_ptr, bson_iter_t *)
-BCON_ENSURE_DECLARE (const_bson_iter_ptr, const bson_iter_t *)
-
-#define BCON_UTF8(_val) \
-   BCON_MAGIC, BCON_TYPE_UTF8, BCON_ENSURE (const_char_ptr, (_val))
-#define BCON_DOUBLE(_val) \
-   BCON_MAGIC, BCON_TYPE_DOUBLE, BCON_ENSURE (double, (_val))
-#define BCON_DOCUMENT(_val) \
-   BCON_MAGIC, BCON_TYPE_DOCUMENT, BCON_ENSURE (const_bson_ptr, (_val))
-#define BCON_ARRAY(_val) \
-   BCON_MAGIC, BCON_TYPE_ARRAY, BCON_ENSURE (const_bson_ptr, (_val))
-#define BCON_BIN(_subtype, _binary, _length) \
-   BCON_MAGIC, BCON_TYPE_BIN, \
-   BCON_ENSURE (subtype, (_subtype)), \
-   BCON_ENSURE (const_uint8_ptr, (_binary)), \
-   BCON_ENSURE (uint32, (_length))
-#define BCON_UNDEFINED BCON_MAGIC, BCON_TYPE_UNDEFINED
-#define BCON_OID(_val) \
-   BCON_MAGIC, BCON_TYPE_OID, BCON_ENSURE (const_oid_ptr, (_val))
-#define BCON_BOOL(_val) \
-   BCON_MAGIC, BCON_TYPE_BOOL, BCON_ENSURE (bool, (_val))
-#define BCON_DATE_TIME(_val) \
-   BCON_MAGIC, BCON_TYPE_DATE_TIME, BCON_ENSURE (int64, (_val))
-#define BCON_NULL BCON_MAGIC, BCON_TYPE_NULL
-#define BCON_REGEX(_regex, _flags) \
-   BCON_MAGIC, BCON_TYPE_REGEX, \
-   BCON_ENSURE (const_char_ptr, (_regex)), \
-   BCON_ENSURE (const_char_ptr, (_flags))
-#define BCON_DBPOINTER(_collection, _oid) \
-   BCON_MAGIC, BCON_TYPE_DBPOINTER, \
-   BCON_ENSURE (const_char_ptr, (_collection)), \
-   BCON_ENSURE (const_oid_ptr, (_oid))
-#define BCON_CODE(_val) \
-   BCON_MAGIC, BCON_TYPE_CODE, BCON_ENSURE (const_char_ptr, (_val))
-#define BCON_SYMBOL(_val) \
-   BCON_MAGIC, BCON_TYPE_SYMBOL, BCON_ENSURE (const_char_ptr, (_val))
-#define BCON_CODEWSCOPE(_js, _scope) \
-   BCON_MAGIC, BCON_TYPE_CODEWSCOPE, \
-   BCON_ENSURE (const_char_ptr, (_js)), \
-   BCON_ENSURE (const_bson_ptr, (_scope))
-#define BCON_INT32(_val) \
-   BCON_MAGIC, BCON_TYPE_INT32, BCON_ENSURE (int32, (_val))
-#define BCON_TIMESTAMP(_timestamp, _increment) \
-   BCON_MAGIC, BCON_TYPE_TIMESTAMP, \
-   BCON_ENSURE (int32, (_timestamp)), \
-   BCON_ENSURE (int32, (_increment))
-#define BCON_INT64(_val) \
-   BCON_MAGIC, BCON_TYPE_INT64, BCON_ENSURE (int64, (_val))
-#define BCON_MAXKEY BCON_MAGIC, BCON_TYPE_MAXKEY
-#define BCON_MINKEY BCON_MAGIC, BCON_TYPE_MINKEY
-#define BCON(_val) \
-   BCON_MAGIC, BCON_TYPE_BCON, BCON_ENSURE (const_bson_ptr, (_val))
-#define BCON_ITER(_val) \
-   BCON_MAGIC, BCON_TYPE_ITER, BCON_ENSURE (const_bson_iter_ptr, (_val))
-
-#define BCONE_UTF8(_val) BCONE_MAGIC, BCON_TYPE_UTF8, \
-   BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val))
-#define BCONE_DOUBLE(_val) BCONE_MAGIC, BCON_TYPE_DOUBLE, \
-   BCON_ENSURE_STORAGE (double_ptr, (_val))
-#define BCONE_DOCUMENT(_val) BCONE_MAGIC, BCON_TYPE_DOCUMENT, \
-   BCON_ENSURE_STORAGE (bson_ptr, (_val))
-#define BCONE_ARRAY(_val) BCONE_MAGIC, BCON_TYPE_ARRAY, \
-   BCON_ENSURE_STORAGE (bson_ptr, (_val))
-#define BCONE_BIN(subtype, binary, length) \
-   BCONE_MAGIC, BCON_TYPE_BIN, \
-   BCON_ENSURE_STORAGE (subtype_ptr, (subtype)), \
-   BCON_ENSURE_STORAGE (const_uint8_ptr_ptr, (binary)), \
-   BCON_ENSURE_STORAGE (uint32_ptr, (length))
-#define BCONE_UNDEFINED BCONE_MAGIC, BCON_TYPE_UNDEFINED
-#define BCONE_OID(_val) BCONE_MAGIC, BCON_TYPE_OID, \
-   BCON_ENSURE_STORAGE (const_oid_ptr_ptr, (_val))
-#define BCONE_BOOL(_val) BCONE_MAGIC, BCON_TYPE_BOOL, \
-   BCON_ENSURE_STORAGE (bool_ptr, (_val))
-#define BCONE_DATE_TIME(_val) BCONE_MAGIC, BCON_TYPE_DATE_TIME, \
-   BCON_ENSURE_STORAGE (int64_ptr, (_val))
-#define BCONE_NULL BCONE_MAGIC, BCON_TYPE_NULL
-#define BCONE_REGEX(_regex, _flags) \
-   BCONE_MAGIC, BCON_TYPE_REGEX, \
-   BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_regex)), \
-   BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_flags))
-#define BCONE_DBPOINTER(_collection, _oid) \
-   BCONE_MAGIC, BCON_TYPE_DBPOINTER, \
-   BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_collection)), \
-   BCON_ENSURE_STORAGE (const_oid_ptr_ptr, (_oid))
-#define BCONE_CODE(_val) BCONE_MAGIC, BCON_TYPE_CODE, \
-   BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val))
-#define BCONE_SYMBOL(_val) BCONE_MAGIC, BCON_TYPE_SYMBOL, \
-   BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_val))
-#define BCONE_CODEWSCOPE(_js, _scope) \
-   BCONE_MAGIC, BCON_TYPE_CODEWSCOPE, \
-   BCON_ENSURE_STORAGE (const_char_ptr_ptr, (_js)), \
-   BCON_ENSURE_STORAGE (bson_ptr, (_scope))
-#define BCONE_INT32(_val) BCONE_MAGIC, BCON_TYPE_INT32, \
-   BCON_ENSURE_STORAGE (int32_ptr, (_val))
-#define BCONE_TIMESTAMP(_timestamp, _increment) \
-   BCONE_MAGIC, BCON_TYPE_TIMESTAMP, \
-   BCON_ENSURE_STORAGE (int32_ptr, (_timestamp)), \
-   BCON_ENSURE_STORAGE (int32_ptr, (_increment))
-#define BCONE_INT64(_val) BCONE_MAGIC, BCON_TYPE_INT64, \
-   BCON_ENSURE_STORAGE (int64_ptr, (_val))
-#define BCONE_MAXKEY BCONE_MAGIC, BCON_TYPE_MAXKEY
-#define BCONE_MINKEY BCONE_MAGIC, BCON_TYPE_MINKEY
-#define BCONE_SKIP(_val) BCONE_MAGIC, BCON_TYPE_SKIP, \
-   BCON_ENSURE (bson_type, (_val))
-#define BCONE_ITER(_val) BCONE_MAGIC, BCON_TYPE_ITER, \
-   BCON_ENSURE_STORAGE (bson_iter_ptr, (_val))
-
-#define BCON_MAGIC  bson_bcon_magic()
-#define BCONE_MAGIC bson_bcone_magic()
-
-typedef enum
-{
-   BCON_TYPE_UTF8,
-   BCON_TYPE_DOUBLE,
-   BCON_TYPE_DOCUMENT,
-   BCON_TYPE_ARRAY,
-   BCON_TYPE_BIN,
-   BCON_TYPE_UNDEFINED,
-   BCON_TYPE_OID,
-   BCON_TYPE_BOOL,
-   BCON_TYPE_DATE_TIME,
-   BCON_TYPE_NULL,
-   BCON_TYPE_REGEX,
-   BCON_TYPE_DBPOINTER,
-   BCON_TYPE_CODE,
-   BCON_TYPE_SYMBOL,
-   BCON_TYPE_CODEWSCOPE,
-   BCON_TYPE_INT32,
-   BCON_TYPE_TIMESTAMP,
-   BCON_TYPE_INT64,
-   BCON_TYPE_MAXKEY,
-   BCON_TYPE_MINKEY,
-   BCON_TYPE_BCON,
-   BCON_TYPE_ARRAY_START,
-   BCON_TYPE_ARRAY_END,
-   BCON_TYPE_DOC_START,
-   BCON_TYPE_DOC_END,
-   BCON_TYPE_END,
-   BCON_TYPE_RAW,
-   BCON_TYPE_SKIP,
-   BCON_TYPE_ITER,
-   BCON_TYPE_ERROR,
-} bcon_type_t;
-
-typedef struct bcon_append_ctx_frame
-{
-   int         i;
-   bool is_array;
-   bson_t      bson;
-} bcon_append_ctx_frame_t;
-
-typedef struct bcon_extract_ctx_frame
-{
-   int         i;
-   bool is_array;
-   bson_iter_t iter;
-} bcon_extract_ctx_frame_t;
-
-typedef struct bcon_append_ctx
-{
-   bcon_append_ctx_frame_t stack[BCON_STACK_MAX];
-   int                     n;
-} bcon_append_ctx_t;
-
-typedef struct bcon_extract_ctx
-{
-   bcon_extract_ctx_frame_t stack[BCON_STACK_MAX];
-   int                      n;
-} bcon_extract_ctx_t;
-
-void
-bcon_append (bson_t *bson,
-             ...) BSON_GNUC_NULL_TERMINATED;
-void
-bcon_append_ctx (bson_t            *bson,
-                 bcon_append_ctx_t *ctx,
-                 ...) BSON_GNUC_NULL_TERMINATED;
-void
-bcon_append_ctx_va (bson_t            *bson,
-                    bcon_append_ctx_t *ctx,
-                    va_list           *va);
-void
-bcon_append_ctx_init (bcon_append_ctx_t *ctx);
-
-void
-bcon_extract_ctx_init (bcon_extract_ctx_t *ctx);
-
-bool
-bcon_extract_ctx_va (bson_t             *bson,
-                     bcon_extract_ctx_t *ctx,
-                     va_list            *ap);
-
-bool
-bcon_extract (bson_t *bson,
-              ...) BSON_GNUC_NULL_TERMINATED;
-
-bool
-bcon_extract_va (bson_t             *bson,
-                 bcon_extract_ctx_t *ctx,
-                 ...) BSON_GNUC_NULL_TERMINATED;
-
-bson_t *
-bcon_new (void *unused,
-          ...) BSON_GNUC_NULL_TERMINATED;
-
-#define BCON_APPEND(_bson, ...) \
-   bcon_append ((_bson), __VA_ARGS__, NULL)
-#define BCON_APPEND_CTX(_bson, _ctx, ...) \
-   bcon_append_ctx ((_bson), (_ctx), __VA_ARGS__, NULL)
-
-#define BCON_EXTRACT(_bson, ...) \
-   bcon_extract ((_bson), __VA_ARGS__, NULL)
-
-#define BCON_EXTRACT_CTX(_bson, _ctx, ...) \
-   bcon_extract ((_bson), (_ctx), __VA_ARGS__, NULL)
-
-#define BCON_NEW(...) \
-   bcon_new (NULL, __VA_ARGS__, NULL)
-
-const char *bson_bcon_magic  (void) BSON_GNUC_CONST;
-const char *bson_bcone_magic (void) BSON_GNUC_CONST;
-
-#endif
diff --git a/bson/bson-compat.h b/bson/bson-compat.h
index 1ccd198..02e024e 100644
--- a/bson/bson-compat.h
+++ b/bson/bson-compat.h
@@ -91,6 +91,10 @@ BSON_BEGIN_DECLS
 # include <inttypes.h>
 #endif
 
+#if defined(__MINGW32__) && ! defined(INIT_ONCE_STATIC_INIT)
+# define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
+  typedef RTL_RUN_ONCE INIT_ONCE;
+#endif
 
 #ifdef BSON_HAVE_STDBOOL_H
 # include <stdbool.h>
diff --git a/bson/bson.c b/bson/bson.c
index 6b09806..31f3035 100644
--- a/bson/bson.c
+++ b/bson/bson.c
@@ -1582,7 +1582,6 @@ bson_append_date_time (bson_t      *bson,
 
    bson_return_val_if_fail (bson, false);
    bson_return_val_if_fail (key, false);
-   bson_return_val_if_fail (value, false);
 
    if (key_length < 0) {
       key_length =(int)strlen (key);
diff --git a/inc/Module/Install/PRIVATE/Mongo.pm b/inc/Module/Install/PRIVATE/Mongo.pm
index 17cc3d0..51d34e3 100644
--- a/inc/Module/Install/PRIVATE/Mongo.pm
+++ b/inc/Module/Install/PRIVATE/Mongo.pm
@@ -5,18 +5,65 @@ package Module::Install::PRIVATE::Mongo;
 
 use Module::Install::Base;
 use Config;
-use Config::AutoConf;
-use Path::Tiny;
+use Config::AutoConf 0.22;
+use Path::Tiny 0.052;
 use File::Spec::Functions qw/catdir/;
 use Cwd; 
 
 our @ISA = qw{Module::Install::Base};
 
+sub check_for_outdated_win_gcc {
+	return if $ENV{MONGODB_NO_WIN32_GCC_CHECK};
+	return if $Config{cc} !~ /gcc/;
+
+	local $@;
+	my $gcc_ver = eval {
+		my ( $v ) = split / /, $Config{gccversion};
+		"$v";
+	};
+	die "Could not identify gcc version in '$Config{gccversion}' due to:\n$@" if !$gcc_ver or $@;
+        my $gcc_vstring = eval "v$gcc_ver";
+	die "Could not parse gcc version '$gcc_ver':\n$@" if !$gcc_vstring or $@;
+	my $min_work_ver = "4.6.3";
+	my $min_work_vstring = eval "v$min_work_ver";
+	return if $gcc_vstring ge $min_work_vstring;
+
+	die <<"END";
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+Your gcc is version '$gcc_ver'.
+The highest known incompatible version of gcc is '4.4.7'.
+The lowest  known   compatible version of gcc is '$min_work_ver'.
+
+Your gcc version is highly unlikely to be able to compile BSON, since the
+libraries/headers that come with it is incompatible with our version of libbson.
+
+We're aborting here forcibly so you will see this message. You have the
+following options at this point:
+
+1. set MONGODB_NO_WIN32_GCC_CHECK to any value to ignore this message and retry
+
+2. if you know C, try and help us by upgrading our libbson, patches welcome!
+
+3. install a newer gcc, '$min_work_ver' or higher
+
+4. install Strawberry 5.16.3 or higher, their gcc versions are compatible
+
+!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+END
+}
+
 sub mongo {
     my ($self, @mongo_vars) = @_;
+
     my $ccflags = $self->makemaker_args->{CCFLAGS} || $Config{ccflags};
     $ccflags = "" unless defined $ccflags;
 
+    # MSWin32 requires newer gcc (if using gcc)
+    if ( $^O eq 'MSWin32' ) {
+        check_for_outdated_win_gcc;
+    }
+
     # openbsd needs threaded perl *or* single-threaded but with libpthread, so
     # we check specifically for that
     if ($^O eq 'openbsd') {
@@ -51,8 +98,11 @@ sub mongo {
 
     if ( $conf->{BSON_HAVE_CLOCK_GETTIME} ) {
         my $libs = $self->makemaker_args->{LIBS};
-        $libs = "" unless defined $libs;
-        $self->makemaker_args( LIBS => "$libs -lrt" );
+        $libs = [""] unless defined $libs;
+        for my $part ( @$libs) {
+          $part .= (length($part)  ? " " : "") . "-lrt";
+        }
+        $self->makemaker_args->{LIBS} = $libs;;
     }
 
     $self->makemaker_args( CCFLAGS => $ccflags );
diff --git a/lib/MongoDB.pm b/lib/MongoDB.pm
index 3730455..bd53e76 100644
--- a/lib/MongoDB.pm
+++ b/lib/MongoDB.pm
@@ -22,7 +22,7 @@ package MongoDB;
 # ABSTRACT: Official MongoDB Driver for Perl
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 # regexp_pattern was unavailable before 5.10, had to be exported to load the
 # function implementation on 5.10, and was automatically available in 5.10.1
@@ -58,7 +58,7 @@ MongoDB - Official MongoDB Driver for Perl
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -210,15 +210,15 @@ the nature of changes involved.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -228,7 +228,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/BSON.pm b/lib/MongoDB/BSON.pm
index 9d1c869..141d78a 100644
--- a/lib/MongoDB/BSON.pm
+++ b/lib/MongoDB/BSON.pm
@@ -20,7 +20,7 @@ package MongoDB::BSON;
 # ABSTRACT: Tools for serializing and deserializing data in BSON form
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use MongoDB;
@@ -84,18 +84,6 @@ $MongoDB::BSON::char = '$';
 
 $MongoDB::BSON::utf8_flag_on = 1;
 
-#pod =head2 Return boolean values as booleans instead of integers
-#pod
-#pod     $MongoDB::BSON::use_boolean = 1
-#pod
-#pod By default, booleans are deserialized as integers.  If you would like them to be
-#pod deserialized as L<boolean/true> and L<boolean/false>, set
-#pod C<$MongoDB::BSON::use_boolean> to 1.
-#pod
-#pod =cut
-
-$MongoDB::BSON::use_boolean = 0;
-
 #pod =head2 Return binary data as instances of L<MongoDB::BSON::Binary> instead of
 #pod string refs.
 #pod
@@ -109,6 +97,20 @@ $MongoDB::BSON::use_boolean = 0;
 
 $MongoDB::BSON::use_binary = 0;
 
+#pod =head1 UNSUPPORTED
+#pod
+#pod =head2 Return boolean values as integers
+#pod
+#pod Previously, the MongoDB driver documented the C<$MongoDB::BSON::use_boolean>
+#pod global for toggling whether boolean BSON values were deserialized as integers
+#pod or L<boolean> objects.  However, this value was actually never used and the
+#pod driver always deserialized objects as L<boolean> values.  Rather than fix this
+#pod and break people's code, instead this option is no longer supported.  A future
+#pod driver (v1.0.0 or later) will provide a means for customizing the
+#pod deserialization of boolean BSON values without the use of a global variable.
+#pod
+#pod =cut
+
 __PACKAGE__->meta->make_immutable;
 
 1;
@@ -125,7 +127,7 @@ MongoDB::BSON - Tools for serializing and deserializing data in BSON form
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 NAME
 
@@ -173,14 +175,6 @@ NOTE:
 
 If you turn off utf8 flag, the string  length will compute as bytes, and is_utf8 will return false.
 
-=head2 Return boolean values as booleans instead of integers
-
-    $MongoDB::BSON::use_boolean = 1
-
-By default, booleans are deserialized as integers.  If you would like them to be
-deserialized as L<boolean/true> and L<boolean/false>, set
-C<$MongoDB::BSON::use_boolean> to 1.
-
 =head2 Return binary data as instances of L<MongoDB::BSON::Binary> instead of
 string refs.
 
@@ -190,21 +184,33 @@ For backwards compatibility, binary data is deserialized as a string ref.  If
 you would like to have it deserialized as instances of L<MongoDB::BSON::Binary>
 (to, say, preserve the subtype), set C<$MongoDB::BSON::use_binary> to 1.
 
+=head1 UNSUPPORTED
+
+=head2 Return boolean values as integers
+
+Previously, the MongoDB driver documented the C<$MongoDB::BSON::use_boolean>
+global for toggling whether boolean BSON values were deserialized as integers
+or L<boolean> objects.  However, this value was actually never used and the
+driver always deserialized objects as L<boolean> values.  Rather than fix this
+and break people's code, instead this option is no longer supported.  A future
+driver (v1.0.0 or later) will provide a means for customizing the
+deserialization of boolean BSON values without the use of a global variable.
+
 =head1 AUTHORS
 
 =over 4
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -214,7 +220,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/BSON/Binary.pm b/lib/MongoDB/BSON/Binary.pm
index eb00f62..b1824db 100644
--- a/lib/MongoDB/BSON/Binary.pm
+++ b/lib/MongoDB/BSON/Binary.pm
@@ -20,7 +20,7 @@ package MongoDB::BSON::Binary;
 # ABSTRACT: Binary type
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use namespace::clean -except => 'meta';
@@ -155,7 +155,7 @@ MongoDB::BSON::Binary - Binary type
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -246,15 +246,15 @@ any native UUID type.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -264,7 +264,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/BSON/Regexp.pm b/lib/MongoDB/BSON/Regexp.pm
index 02201ea..d5e7992 100644
--- a/lib/MongoDB/BSON/Regexp.pm
+++ b/lib/MongoDB/BSON/Regexp.pm
@@ -2,7 +2,7 @@ package MongoDB::BSON::Regexp;
 # ABSTRACT: Regular expression type
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use namespace::clean -except => 'meta';
@@ -60,7 +60,7 @@ MongoDB::BSON::Regexp - Regular expression type
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 AUTHORS
 
@@ -68,15 +68,15 @@ version v0.705.0.0
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -86,7 +86,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/BulkWrite.pm b/lib/MongoDB/BulkWrite.pm
index a8eaed2..3dbaf89 100644
--- a/lib/MongoDB/BulkWrite.pm
+++ b/lib/MongoDB/BulkWrite.pm
@@ -19,7 +19,7 @@ package MongoDB::BulkWrite;
 # ABSTRACT: MongoDB bulk write interface
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use MongoDB::Error;
 use MongoDB::OID;
@@ -697,7 +697,7 @@ MongoDB::BulkWrite - MongoDB bulk write interface
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -849,15 +849,15 @@ to call C<execute> more than once on the same bulk object.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -867,7 +867,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/BulkWriteView.pm b/lib/MongoDB/BulkWriteView.pm
index 61eec06..d68aea9 100644
--- a/lib/MongoDB/BulkWriteView.pm
+++ b/lib/MongoDB/BulkWriteView.pm
@@ -19,7 +19,7 @@ package MongoDB::BulkWriteView;
 # ABSTRACT: Bulk write operations against a query document
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use namespace::clean -except => 'meta';
@@ -51,7 +51,7 @@ MongoDB::BulkWriteView - Bulk write operations against a query document
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -146,15 +146,15 @@ update, update_one or replace_one operation as an upsert operation.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -164,7 +164,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Code.pm b/lib/MongoDB/Code.pm
index 2906973..564588d 100644
--- a/lib/MongoDB/Code.pm
+++ b/lib/MongoDB/Code.pm
@@ -20,7 +20,7 @@ package MongoDB::Code;
 # ABSTRACT: JavaScript Code
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 #pod =head1 NAME
 #pod
@@ -73,7 +73,7 @@ MongoDB::Code - JavaScript Code
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 NAME
 
@@ -95,15 +95,15 @@ An optional hash of variables to pass as the scope.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -113,7 +113,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Collection.pm b/lib/MongoDB/Collection.pm
index 5c20a03..75bca41 100644
--- a/lib/MongoDB/Collection.pm
+++ b/lib/MongoDB/Collection.pm
@@ -20,11 +20,12 @@ package MongoDB::Collection;
 # ABSTRACT: A MongoDB Collection
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Tie::IxHash;
 use Carp 'carp';
 use boolean;
+use Safe::Isa;
 use Scalar::Util qw/blessed/;
 use Try::Tiny;
 use Moose;
@@ -290,8 +291,7 @@ sub legacy_update {
     }
 
     if ($conn->send($update) == -1) {
-        $conn->connect;
-        die("can't get db response, not connected");
+        die("can't get db response, not connected (sending update)");
     }
 
     return 1;
@@ -433,10 +433,11 @@ sub legacy_remove {
     my ($just_one, $safe);
     if (defined $options && ref $options eq 'HASH') {
         $just_one = exists $options->{just_one} ? $options->{just_one} : 0;
-        $safe = $options->{safe} or $conn->_w_want_safe;
+        $safe = $options->{safe} || $conn->_w_want_safe;
     }
     else {
         $just_one = $options || 0;
+        $safe = $conn->_w_want_safe;
     }
 
     my $ns = $self->full_name;
@@ -448,14 +449,12 @@ sub legacy_remove {
     }
 
     if ($conn->send($remove) == -1) {
-        $conn->connect;
-        die("can't get db response, not connected");
+        die("can't get db response, not connected (sending delete)");
     }
 
     return 1;
 }
 
-
 sub ensure_index {
     my ($self, $keys, $options, $garbage) = @_;
     my $ns = $self->full_name;
@@ -474,53 +473,57 @@ sub ensure_index {
     }
 
     $keys = Tie::IxHash->new(@$keys) if ref $keys eq 'ARRAY';
-    my $obj = Tie::IxHash->new("ns" => $ns, "key" => $keys);
+    my $obj = Tie::IxHash->new("key" => $keys);
 
     if (exists $options->{name}) {
-        $obj->Push("name" => $options->{name});
+        $obj->Push("name" => delete $options->{name});
     }
     else {
         $obj->Push("name" => MongoDB::Collection::to_index_string($keys));
     }
 
-    foreach ("unique", "background", "sparse") {
-        if (exists $options->{$_}) {
-            $obj->Push("$_" => ($options->{$_} ? boolean::true : boolean::false));
-        }
-    }
+    # extract legacy insertion options
+    my $insert_opts = { no_ids => 1 };
+    $insert_opts->{safe} = delete $options->{safe} if exists $options->{safe};
+
+    # convert historical snake-case options to required camelCase
     if (exists $options->{drop_dups}) {
-        $obj->Push("dropDups" => ($options->{drop_dups} ? boolean::true : boolean::false));
+        $options->{dropDups} = delete $options->{drop_dups};
     }
-    $options->{'no_ids'} = 1;
 
-    foreach ("weights", "default_language", "language_override") {
-        if (exists $options->{$_}) {
-            $obj->Push("$_" => $options->{$_});
-        }
+    if (exists $options->{expire_after_seconds}) {
+        $options->{expireAfterSeconds} = int(delete $options->{expire_after_seconds});
     }
 
-    if (exists $options->{expire_after_seconds}) {
-        $obj->Push("expireAfterSeconds" => int($options->{expire_after_seconds}));
+    # some options *must* be sent as booleans
+    for my $k ( qw/unique background sparse dropDups/ ) {
+        next unless exists $options->{$k};
+        $options->{$k} = boolean($options->{$k});
+    }
+
+    # pass through all options after conversion
+    while ( my ($k,$v) = each %$options ) {
+        $obj->Push($k, $v);
     }
 
     my ($db, $coll) = $ns =~ m/^([^\.]+)\.(.*)/;
 
     # try the new createIndexes command (mongodb 2.6), falling back to the old insert
     # method if createIndexes is not available.
-    my $tmp_ns = $obj->DELETE( 'ns' );     # ci command takes ns outside of index spec
 
     my $res = $self->_database->get_collection( '$cmd' )->find_one( Tie::IxHash->new( createIndexes => $self->name, indexes => [ $obj ] ) );
 
-    return $res if $res->{ok};    
+    return $res if $res->{ok};
 
     # if not ok, no code or code 59 or code 13390 mean "command not available",
-    # per DRIVERS-103 and DRIVERS-132
-    if ( ( not $res->{ok} )  && 
+    # per DRIVERS-103 and DRIVERS-132; 13390 is old mongos per DRIVERS-149
+    if ( ( not $res->{ok} )  &&
          ( not exists $res->{code} or $res->{code} == 59 or $res->{code} == 13390) ) { 
-        $obj->Unshift( ns => $tmp_ns );     # restore ns to spec
+        # add ns to object to insert
+        $obj->Unshift( ns => $ns );
         my $indexes = $self->_database->get_collection("system.indexes");
-        return $indexes->insert($obj, $options);
-    } else { 
+        return $indexes->insert($obj, $insert_opts);
+    } else {
         die "error creating index: " . $res->{errmsg};
     }
 } 
@@ -627,6 +630,51 @@ sub drop_index {
 
 sub get_indexes {
     my ($self) = @_;
+
+    # try command style for 2.8+
+    my ( $ok, @indexes ) = try {
+        my $command = Tie::IxHash->new( listIndexes => $self->name, cursor => {} );
+        my $res     = $self->_database->_try_run_command($command);
+        my @list;
+        # XXX RC0 - RC2 give collections result; RC3+ give cursor result
+        if ( $res->{indexes} ) {
+            @list = @{$res->{indexes}};
+        }
+        else {
+            my $cursor  = MongoDB::Cursor->new(
+                started_iterating => 1,                 # we have the first batch
+                _client           => $self->_database->_client,
+                _master           => $self->_database->_client,    # fake this because we're already iterating
+                _ns               => $res->{cursor}{ns},
+                _agg_first_batch => $res->{cursor}{firstBatch},
+                _agg_batch_size  => scalar @{ $res->{cursor}{firstBatch} }, # for has_next
+                _query           => $command,
+            );
+            $cursor->_init( $res->{cursor}{id} );
+            @list = $cursor->all;
+        }
+        return 1, @list;
+    }
+    catch {
+        if ( $_->$_isa('MongoDB::DatabaseError') ) {
+            my $cmd_result = $_->result->result;
+            my $code = $cmd_result->{code} || 0;
+            if ( $code == 26 ) {
+                return 1, (); # empty
+            }
+            elsif ($code == 59 || $code == 13390 ) {
+                return 0;
+            }
+            elsif ( ($cmd_result->{errmsg} || '') =~ m{^no such cmd} ) {
+                return 0;
+            }
+        }
+        die $_;
+    };
+
+    return @indexes if $ok;
+
+    # fallback to earlier style
     return $self->_database->get_collection('system.indexes')->query({
         ns => $self->full_name,
     })->all;
@@ -669,7 +717,7 @@ MongoDB::Collection - A MongoDB Collection
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -807,14 +855,17 @@ are:
 =over
 
 =item C<upsert>
+
 If no object matching C<$criteria> is found, C<$object> will be inserted.
 
 =item C<multiple>
+
 All of the documents that match C<$criteria> will be updated, not just
 the first document found. (Only available with database version 1.1.3 and
 newer.)
 
 =item C<safe>
+
 If the update fails and safe is set, the update will croak.
 
 =back
@@ -987,6 +1038,8 @@ option is set and the index creation fails, it will also croak. You can also
 check if the indexing succeeded by doing an unsafe index creation, then calling
 L<MongoDB::Database/"last_error($options?)">.
 
+Boolean options should be passed as objects of type L<booelan>.
+
 See the L<MongoDB::Indexing> pod for more information on indexing.
 
 =head2 count($query?)
@@ -1059,15 +1112,15 @@ Deletes a collection as well as all of its indexes.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -1077,7 +1130,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/CommandResult.pm b/lib/MongoDB/CommandResult.pm
index 2f51150..5fa12f5 100644
--- a/lib/MongoDB/CommandResult.pm
+++ b/lib/MongoDB/CommandResult.pm
@@ -19,7 +19,7 @@ package MongoDB::CommandResult;
 # ABSTRACT: MongoDB generic command result document
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use namespace::clean -except => 'meta';
@@ -68,7 +68,7 @@ MongoDB::CommandResult - MongoDB generic command result document
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 DESCRIPTION
 
@@ -93,15 +93,15 @@ Error string (if any) or the empty string if there was no error.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -111,7 +111,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Connection.pm b/lib/MongoDB/Connection.pm
index 8750b96..327195b 100644
--- a/lib/MongoDB/Connection.pm
+++ b/lib/MongoDB/Connection.pm
@@ -19,7 +19,7 @@ package MongoDB::Connection;
 # ABSTRACT: A connection to a MongoDB server (DEPRECATED)
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use MongoDB;
@@ -63,7 +63,7 @@ MongoDB::Connection - A connection to a MongoDB server (DEPRECATED)
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 DEPRECATED
 
@@ -374,15 +374,15 @@ Unlocks a database server to allow writes and reverses the operation of a $conn-
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -392,7 +392,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Cursor.pm b/lib/MongoDB/Cursor.pm
index b80f4d5..534ca8c 100644
--- a/lib/MongoDB/Cursor.pm
+++ b/lib/MongoDB/Cursor.pm
@@ -20,7 +20,7 @@ package MongoDB::Cursor;
 # ABSTRACT: A cursor/iterator for Mongo query results
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use MongoDB;
@@ -30,10 +30,6 @@ use Tie::IxHash;
 use Try::Tiny;
 use namespace::clean -except => 'meta';
 
-#pod =head1 NAME
-#pod
-#pod MongoDB::Cursor - A cursor/iterator for Mongo query results
-#pod
 #pod =head1 SYNOPSIS
 #pod
 #pod     while (my $object = $cursor->next) {
@@ -48,10 +44,6 @@ use namespace::clean -except => 'meta';
 #pod multiple threads will give unpredictable results.  Only iterate from a single
 #pod thread.
 #pod
-#pod =head1 SEE ALSO
-#pod
-#pod Core documentation on cursors: L<http://dochub.mongodb.org/core/cursors>.
-#pod
 #pod =cut
 
 $MongoDB::Cursor::_request_id = int(rand(1000000));
@@ -750,7 +742,7 @@ MongoDB::Cursor - A cursor/iterator for Mongo query results
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -766,14 +758,6 @@ Cursors are cloned in threads, but not reset.  Iterating the same cursor from
 multiple threads will give unpredictable results.  Only iterate from a single
 thread.
 
-=head1 NAME
-
-MongoDB::Cursor - A cursor/iterator for Mongo query results
-
-=head1 SEE ALSO
-
-Core documentation on cursors: L<http://dochub.mongodb.org/core/cursors>.
-
 =head1 STATIC ATTRIBUTES
 
 =head2 slave_okay
@@ -1018,9 +1002,9 @@ For core documentation on read preference see L<http://docs.mongodb.org/manual/c
 
 Returns $self so that this method can be chained.
 
-=head1 AUTHOR
+=head1 SEE ALSO
 
-  Kristina Chodorow <kristina at mongodb.org>
+Core documentation on cursors: L<http://dochub.mongodb.org/core/cursors>.
 
 =head1 AUTHORS
 
@@ -1028,15 +1012,15 @@ Returns $self so that this method can be chained.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -1046,7 +1030,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/DBRef.pm b/lib/MongoDB/DBRef.pm
index f0e0f03..f49cbc4 100644
--- a/lib/MongoDB/DBRef.pm
+++ b/lib/MongoDB/DBRef.pm
@@ -19,7 +19,7 @@ package MongoDB::DBRef;
 # ABSTRACT: Native DBRef support
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Carp 'croak';
 use Tie::IxHash;
@@ -117,7 +117,7 @@ MongoDB::DBRef - Native DBRef support
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -193,15 +193,15 @@ database or collection concerned does not exist.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -211,7 +211,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/DataTypes.pod b/lib/MongoDB/DataTypes.pod
index 18984a1..06b4645 100644
--- a/lib/MongoDB/DataTypes.pod
+++ b/lib/MongoDB/DataTypes.pod
@@ -30,7 +30,7 @@ MongoDB::DataTypes - The data types used with MongoDB
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 DESCRIPTION
 
@@ -302,8 +302,11 @@ from the database (this does not affect queries or Perl 5.10+).
 
 =head2 Booleans
 
-Use the L<boolean> package to get boolean values.  C<boolean::true> and
-C<boolean::false> are the only parts of the package used, currently.
+Boolean values are emulated using the L<boolean> package via the
+C<boolean::true> and C<boolean::false> functions.  Using L<boolean> objects
+in documents will ensure the documents have the BSON boolean type in the
+database.  Likewise, BSON boolean types in the database will be returned
+as L<boolean> objects.
 
 An example of inserting boolean values:
 
@@ -316,12 +319,10 @@ where the name field exists):
 
     my $cursor = $collection->query({"name" => {'$exists' => boolean::true}});
 
-Most of the time, you can just use 1 or 0 instead of C<true> and C<false>, such
-as for specifying fields to return.  L<boolean> is the only way to save
-booleans to the database, though.
-
-By default, booleans are returned from the database as integers.  To return
-booleans as L<boolean>s, set C<$MongoDB::BSON::use_boolean> to 1.
+Most of the time, you can just use 1 or 0 in query operations instead of
+C<true> and C<false>, such as for specifying fields to return, but some
+commands require L<boolean> objects and the database will return an error
+if integers 1 or 0 are used.
 
 =head2 MongoDB::OID
 
@@ -444,15 +445,15 @@ L<DateTime> object, or L<DateTime::Tiny> object.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -462,7 +463,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Database.pm b/lib/MongoDB/Database.pm
index 507ab22..86bb9a0 100644
--- a/lib/MongoDB/Database.pm
+++ b/lib/MongoDB/Database.pm
@@ -20,7 +20,7 @@ package MongoDB::Database;
 # ABSTRACT: A MongoDB Database
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use MongoDB::CommandResult;
 use MongoDB::Error;
@@ -28,6 +28,7 @@ use MongoDB::GridFS;
 use Carp 'carp';
 use boolean;
 use Moose;
+use Try::Tiny;
 use namespace::clean -except => 'meta';
 
 has _client => ( 
@@ -45,6 +46,34 @@ has name => (
 
 sub collection_names {
     my ($self) = @_;
+
+    # try command style for 2.8+
+    my ( $ok, @names ) = try {
+        my $command = Tie::IxHash->new( listCollections => 1, cursor => {} );
+        my $res     = $self->_try_run_command($command);
+        my @list;
+        # XXX RC0 - RC2 give collections result; RC3+ give cursor result
+        if ( $res->{collections} ) {
+            @list = map { $_->{name} } @{$res->{collections}};
+        }
+        else {
+            my $cursor  = MongoDB::Cursor->new(
+                started_iterating => 1,                 # we have the first batch
+                _client           => $self->_client,
+                _master           => $self->_client,    # fake this because we're already iterating
+                _ns               => $res->{cursor}{ns},
+                _agg_first_batch => $res->{cursor}{firstBatch},
+                _agg_batch_size  => scalar @{ $res->{cursor}{firstBatch} }, # for has_next
+                _query           => $command,
+            );
+            $cursor->_init( $res->{cursor}{id} );
+            @list = map { $_->{name} } $cursor->all;
+        }
+        return 1, @list;
+    };
+    return @names if $ok;
+
+    # fallback to earlier style
     my $it = $self->get_collection('system.namespaces')->query({});
     return grep { 
         not ( index( $_, '$' ) >= 0 && index( $_, '.oplog.$' ) < 0 ) 
@@ -62,6 +91,7 @@ sub get_collection {
     );
 }
 
+{ no warnings 'once'; *coll = \&get_collection }
 
 sub get_gridfs {
     my ($self, $prefix) = @_;
@@ -149,7 +179,7 @@ MongoDB::Database - A MongoDB Database
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -190,6 +220,8 @@ Returns the list of collections in this database.
 Returns a L<MongoDB::Collection> for the collection called C<$name> within this
 database.
 
+The C<coll> method is an alias for C<get_collection>.
+
 =head2 get_gridfs ($prefix?)
 
     my $grid = $database->get_gridfs;
@@ -324,13 +356,18 @@ See L<MongoDB::Connection/w> for more information.
 
 =head2 run_command ($command)
 
-    my $result = $database->run_command({ some_command => 1 });
+    my $result = $database->run_command([ some_command => 1 ]);
+
+Runs a database command.  The input should be an array reference of key-value
+pairs or a L<Tie::IxHash> object with the command name as the first key.  The
+use of a hash reference will only reliably work for commands without additional
+parameters.
 
-Runs a database command. Returns a string with the error message if the
-command fails. Returns the result of the command (a hash reference) on success.
-For a list of possible database commands, run:
+It returns a string with the error message if the command fails.  It returns
+the result of the command (a hash reference) on success.  For a list of
+possible database commands, run:
 
-    my $commands = $db->run_command({listCommands => 1});
+    my $commands = $db->run_command([listCommands => 1]);
 
 There are a few examples of database commands in the
 L<MongoDB::Examples/"DATABASE COMMANDS"> section.
@@ -361,15 +398,15 @@ L<http://www.mongodb.org/display/DOCS/Server-side+Code+Execution#Server-sideCode
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -379,7 +416,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Error.pm b/lib/MongoDB/Error.pm
index cfc856c..6859748 100644
--- a/lib/MongoDB/Error.pm
+++ b/lib/MongoDB/Error.pm
@@ -22,7 +22,7 @@ package MongoDB::Error;
 # ABSTRACT: MongoDB Driver Error classes
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use Moose::Meta::Class ();
@@ -146,7 +146,7 @@ MongoDB::Error - MongoDB Driver Error classes
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -236,15 +236,15 @@ document — the document that caused the error
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -254,7 +254,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Examples.pod b/lib/MongoDB/Examples.pod
index 03c308f..8efa145 100644
--- a/lib/MongoDB/Examples.pod
+++ b/lib/MongoDB/Examples.pod
@@ -30,7 +30,7 @@ MongoDB::Examples - Some examples of MongoDB syntax
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 MAPPING SQL TO MONGODB
 
@@ -534,15 +534,15 @@ now has C<"name" =E<gt> "george">.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -552,7 +552,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/GridFS.pm b/lib/MongoDB/GridFS.pm
index 21f737e..43a6930 100644
--- a/lib/MongoDB/GridFS.pm
+++ b/lib/MongoDB/GridFS.pm
@@ -20,7 +20,7 @@ package MongoDB::GridFS;
 # ABSTRACT: A file storage utility
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use MongoDB::GridFS::File;
 use DateTime 0.78; # drops dependency on bug-prone Math::Round
@@ -28,10 +28,6 @@ use Digest::MD5;
 use Moose;
 use namespace::clean -except => 'meta';
 
-#pod =head1 NAME
-#pod
-#pod MongoDB::GridFS - A file storage utility
-#pod
 #pod =head1 SYNOPSIS
 #pod
 #pod     use MongoDB::GridFS;
@@ -46,10 +42,6 @@ use namespace::clean -except => 'meta';
 #pod delete are always safe ops, insert, remove, and find_one are optionally safe),
 #pod using one over the other is a matter of preference.
 #pod
-#pod =head1 SEE ALSO
-#pod
-#pod Core documentation on GridFS: L<http://dochub.mongodb.org/core/gridfs>.
-#pod
 #pod =head1 ATTRIBUTES
 #pod
 #pod =head2 chunk_size
@@ -121,15 +113,8 @@ sub _build_chunks {
 # If they are not found, they will be created.
 sub BUILD {
     my ($self) = @_;
-   
-    # check for the required indexes in the system.indexes collection
-    my $count = $self->_database->get_collection('system.indexes')->count({key=>{filename => 1}});
-    $count   += $self->_database->get_collection('system.indexes')->count({key=>{files_id => 1, n => 1}});
-    
-    # if we don't have the required indexes, create them now.
-    if ($count < 2){
-       $self->_ensure_indexes();
-    }
+    $self->_ensure_indexes();
+    return;
 }
 
 
@@ -433,7 +418,7 @@ MongoDB::GridFS - A file storage utility
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -449,14 +434,6 @@ There are two interfaces for GridFS: a file-system/collection-like interface
 delete are always safe ops, insert, remove, and find_one are optionally safe),
 using one over the other is a matter of preference.
 
-=head1 NAME
-
-MongoDB::GridFS - A file storage utility
-
-=head1 SEE ALSO
-
-Core documentation on GridFS: L<http://dochub.mongodb.org/core/gridfs>.
-
 =head1 ATTRIBUTES
 
 =head2 chunk_size
@@ -575,9 +552,9 @@ Removes all files' metadata and contents.
 
 Returns a list of the files in the database.
 
-=head1 AUTHOR
+=head1 SEE ALSO
 
-  Kristina Chodorow <kristina at mongodb.org>
+Core documentation on GridFS: L<http://dochub.mongodb.org/core/gridfs>.
 
 =head1 AUTHORS
 
@@ -585,15 +562,15 @@ Returns a list of the files in the database.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -603,7 +580,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/GridFS/File.pm b/lib/MongoDB/GridFS/File.pm
index 1517aa0..b0c5207 100644
--- a/lib/MongoDB/GridFS/File.pm
+++ b/lib/MongoDB/GridFS/File.pm
@@ -20,17 +20,13 @@ package MongoDB::GridFS::File;
 # ABSTRACT: A Mongo GridFS file
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use MongoDB::GridFS;
 use IO::File;
 use Moose;
 use namespace::clean -except => 'meta';
 
-#pod =head1 NAME
-#pod
-#pod MongoDB::GridFS::File - A Mongo GridFS file
-#pod
 #pod =head1 SYNOPSIS
 #pod
 #pod     use MongoDB::GridFS::File;
@@ -85,6 +81,13 @@ sub print {
 
     my $cursor = $self->_grid->chunks->query({"files_id" => $self->info->{"_id"}})->sort({"n" => 1});
 
+    if ( $self->info->{length} && !$cursor->has_next ) {
+        MongoDB::Error->throw(
+            sprintf( "GridFS file corrupt: no chunks found for file ID '%s'",
+                $self->info->{_id} )
+        );
+    }
+
     while ((my $chunk = $cursor->next) && (!$length || $written < $length)) {
         my $len = length $chunk->{'data'};
 
@@ -168,7 +171,7 @@ MongoDB::GridFS::File - A Mongo GridFS file
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -178,10 +181,6 @@ version v0.705.0.0
     my $file = $grid->find_one;
     $file->print($outfile);
 
-=head1 NAME
-
-MongoDB::GridFS::File - A Mongo GridFS file
-
 =head1 ATTRIBUTES
 
 =head2 info
@@ -208,25 +207,21 @@ Return the number of bytes specified from the offset specified
 to the given file handle.  If no C<$length> or C<$offset> are
 given, the entire file is return.
 
-=head1 AUTHOR
-
-  Kristina Chodorow <kristina at mongodb.org>
-
 =head1 AUTHORS
 
 =over 4
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -236,7 +231,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Indexing.pod b/lib/MongoDB/Indexing.pod
index f5edfbb..dd19be8 100644
--- a/lib/MongoDB/Indexing.pod
+++ b/lib/MongoDB/Indexing.pod
@@ -30,7 +30,7 @@ MongoDB::Indexing - Indexing collections
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 CREATING AN INDEX
 
@@ -68,13 +68,17 @@ options.  Available options are:
 By default, indexes are not unique. To create a unique index, pass 
 C<< unique =E<gt> true >>.  C<true> can be L<boolean::true> or any other true value.
 
-=item C<< drop_dups => boolean >>
+=item C<< drop_dups => boolean >> (B<DEPRECATED>)
 
 If a unique index is being created on an existing set of data that has duplicate
 values, creating the index will fail.  To force the index creation by deleting 
 duplicate values, use this option.  Again, any value that evaluates to true will
 work.
 
+B<Warning>: this option is no longer supported MongoDB starting with server
+version 2.7.5.  This option is silently ignored by the server and unique
+index builds will fail if there are duplicate keys.
+
 =item C<safe =E<gt> boolean>
 
 If the update fails and safe is set, this function will return 0.  You should 
@@ -156,15 +160,15 @@ L<http://dochub.mongodb.org/core/geo>.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -174,7 +178,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/MongoClient.pm b/lib/MongoDB/MongoClient.pm
index 71fb300..4a2d1e9 100644
--- a/lib/MongoDB/MongoClient.pm
+++ b/lib/MongoDB/MongoClient.pm
@@ -19,7 +19,7 @@ package MongoDB::MongoClient;
 # ABSTRACT: A connection to a MongoDB server
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use MongoDB;
@@ -27,7 +27,9 @@ use MongoDB::Cursor;
 use MongoDB::BSON::Binary;
 use MongoDB::BSON::Regexp;
 use MongoDB::Error;
+use Authen::SCRAM::Client 0.003;
 use Digest::MD5;
+use MIME::Base64 qw/encode_base64 decode_base64/;
 use Tie::IxHash;
 use Time::HiRes qw/usleep/;
 use Carp 'carp', 'croak';
@@ -284,15 +286,13 @@ has inflate_regexps => (
 has min_wire_version => ( 
     is        => 'ro',
     isa       => 'Int',
-    required  => 1,
     default   => 0
 );
 
 has max_wire_version => (
     is        => 'ro',
     isa       => 'Int',
-    required  => 1,
-    default   => 2
+    default   => 3
 );
 
 has _use_write_cmd => ( 
@@ -338,6 +338,11 @@ sub BUILD {
         push @pairs, $self->host.":".$self->port;
     }
 
+    # Warn if SSL desired and not supported
+    if ( $self->ssl && ! $self->_compile_flags->{'--ssl'} ) {
+        carp "MongoDB::MongoClient not compiled with SSL; trying to connect without it.\n";
+    }
+
     # We cache our updated constructor arguments because we need them again for
     # creating new, per-host objects
     $self->_opts( $opts );
@@ -529,6 +534,21 @@ sub get_database {
     );
 }
 
+{ no warnings 'once'; *db = \&get_database }
+
+
+sub get_namespace {
+    my ($self, $ns) = @_;
+    confess "get_namespace requires a string argument"
+        unless defined($ns) && length($ns);
+    my ($db, $coll) = split /\./, $ns, 2;
+    confess "$ns is not a valid namespace"
+        unless defined($db) && defined($coll);
+    return $self->db($db)->coll($coll);
+}
+
+{ no warnings 'once'; *ns = \&get_namespace }
+
 sub _get_a_specific_connection {
     my ($self, $host) = @_;
 
@@ -862,12 +882,30 @@ sub rs_refresh {
 
 sub authenticate {
     my ($self, $dbname, $username, $password, $is_digest) = @_;
-    my $hash = $password;
-    
-    # create a hash if the password isn't yet encrypted
+    my $hash;
+
     if (!$is_digest) {
-        $hash = Digest::MD5::md5_hex("${username}:mongo:${password}");
+        $hash = Digest::MD5::md5_hex(encode("UTF-8", "${username}:mongo:${password}"));
+    }
+    else {
+        $hash = $password;
+    }
+
+    # find out if we support SCRAM-SHA-1
+    my $result = eval {
+        $self->get_database( $self->db_name )->_try_run_command( { "ismaster" => 1 } );
+    };
+
+    if ( $result && exists($result->{maxWireVersion}) && $result->{maxWireVersion} >= 3 ) {
+        return $self->_authenticate_scram_sha_1( $dbname, $username, $hash );
     }
+    else {
+        return $self->_authenticate_mongodb_cr( $dbname, $username, $hash );
+    }
+}
+
+sub _authenticate_mongodb_cr {
+    my ($self, $dbname, $username, $hash) = @_;
 
     # get the nonce
     my $db = $self->get_database($dbname);
@@ -886,10 +924,37 @@ sub authenticate {
              nonce => $nonce,
              key => $digest);
     $result = $db->run_command($login);
-    
+
     return $result;
 }
 
+sub _authenticate_scram_sha_1 {
+    my ($self, $dbname, $username, $hash) = @_;
+
+    my $client = Authen::SCRAM::Client->new(
+        username      => $username,
+        password      => $hash,
+        skip_saslprep => 1,
+    );
+
+    my ( $msg, $res, $sasl_resp, $conv_id, $done );
+    try {
+        $msg = encode_base64($client->first_msg, "");
+        $res = $self->_sasl_start( $msg, 'SCRAM-SHA-1', $dbname );
+        ( $sasl_resp, $conv_id, $done ) = @{$res}{qw/payload conversationId done/};
+        $msg = encode_base64($client->final_msg(decode_base64($sasl_resp)), "");
+        $res = $self->_sasl_continue( $msg, $conv_id, $dbname );
+        ( $sasl_resp, $conv_id, $done ) = @{$res}{qw/payload conversationId done/};
+        $client->validate(decode_base64($sasl_resp));
+        # might require an empty payload to complete SASL conversation
+        $res = $self->_sasl_continue( "", $conv_id, $dbname ) if !$done;
+    }
+    catch {
+        croak "Authentication failed: SCRAM-SHA-1 error: $_";
+    };
+
+    return $res;
+}
 
 sub fsync {
     my ($self, $args) = @_;
@@ -916,25 +981,26 @@ sub _w_want_safe {
     return 1;
 }
 
-sub _sasl_check { 
+sub _sasl_check {
     my ( $self, $res ) = @_;
 
     die "Invalid SASL response document from server:"
-        unless reftype $res eq reftype { };
+        unless ref $res eq 'HASH';
 
     if ( $res->{ok} != 1 ) { 
-        die "SASL authentication error: $res->{errmsg}";
+        croak "SASL authentication error: $res->{errmsg}";
     }
 
     return $res->{conversationId};
 }
 
-sub _sasl_start { 
-    my ( $self, $payload, $mechanism ) = @_;
+sub _sasl_start {
+    my ( $self, $payload, $mechanism, $database ) = @_;
+    $database ||= '$external';
 
     # warn "SASL start, payload = [$payload], mechanism = [$mechanism]\n";
 
-    my $res = $self->get_database( '$external' )->run_command( [ 
+    my $res = $self->get_database( $database )->run_command( [
         saslStart     => 1,
         mechanism     => $mechanism,
         payload       => $payload,
@@ -945,12 +1011,13 @@ sub _sasl_start {
 }
 
 
-sub _sasl_continue { 
-    my ( $self, $payload, $conv_id ) = @_;
+sub _sasl_continue {
+    my ( $self, $payload, $conv_id, $database ) = @_;
+    $database ||= '$external';
 
     # warn "SASL continue, payload = [$payload], conv ID = [$conv_id]";
 
-    my $res = $self->get_database( '$external' )->run_command( [ 
+    my $res = $self->get_database( $database )->run_command( [
         saslContinue     => 1,
         conversationId   => $conv_id,
         payload          => $payload
@@ -1015,7 +1082,7 @@ MongoDB::MongoClient - A connection to a MongoDB server
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -1234,8 +1301,9 @@ in the C<passives> field, and arbiters are in the C<arbiters> field.
 
 This tells the driver that you are connecting to an SSL mongodb instance.
 
-This option will be ignored if the driver was not compiled with the SSL flag. You must
-also be using a database server that supports SSL.
+If the driver was not compiled with SSL support, a warning will be issued and
+the driver will attempt to connect without it. You must also be using a
+database server that supports SSL.
 
 The driver must be built as follows for SSL support:
 
@@ -1330,6 +1398,17 @@ Lists all databases on the MongoDB server.
 
 Returns a L<MongoDB::Database> instance for the database with the given C<$name>.
 
+The C<db> method is an alias for C<get_database>.
+
+=head2 get_namespace
+
+    my $collection = $client->get_namespace('test.foo');
+
+Returns a L<MongoDB::collection> instance.  The argument must include the
+database name and collection name separated by a dot character.
+
+The C<ns> method is an alias for C<get_namespace>.
+
 =head2 authenticate ($dbname, $username, $password, $is_digest?)
 
     $client->authenticate('foo', 'username', 'secret');
@@ -1428,15 +1507,15 @@ The currently supported connection string options are ssl, connectTimeoutMS, w,
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -1446,7 +1525,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/OID.pm b/lib/MongoDB/OID.pm
index 51cbb21..fdf7cc7 100644
--- a/lib/MongoDB/OID.pm
+++ b/lib/MongoDB/OID.pm
@@ -19,16 +19,12 @@ package MongoDB::OID;
 # ABSTRACT: A Mongo Object ID
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use MongoDB;
 use namespace::clean -except => 'meta';
 
-#pod =head1 NAME
-#pod
-#pod MongoDB::OID - A Mongo ObjectId
-#pod
 #pod =head1 SYNOPSIS
 #pod
 #pod If no C<_id> field is provided when a document is inserted into the database, an 
@@ -50,14 +46,10 @@ use namespace::clean -except => 'meta';
 #pod     my $id3 = MongoDB::OID->new($id1->value);
 #pod     my $id4 = MongoDB::OID->new($id1);
 #pod
-#pod Now C<$id1>, C<$id2>, $<$id3> and C<$id4> will have the same value.
+#pod Now C<$id1>, C<$id2>, C<$id3> and C<$id4> will have the same value.
 #pod
 #pod OID generation is thread safe.
 #pod
-#pod =head1 SEE ALSO
-#pod
-#pod Core documentation on object ids: L<http://dochub.mongodb.org/core/objectids>.
-#pod
 #pod =head1 ATTRIBUTES
 #pod
 #pod =head2 value
@@ -172,7 +164,7 @@ MongoDB::OID - A Mongo Object ID
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -195,18 +187,10 @@ constructor.  For example:
     my $id3 = MongoDB::OID->new($id1->value);
     my $id4 = MongoDB::OID->new($id1);
 
-Now C<$id1>, C<$id2>, $<$id3> and C<$id4> will have the same value.
+Now C<$id1>, C<$id2>, C<$id3> and C<$id4> will have the same value.
 
 OID generation is thread safe.
 
-=head1 NAME
-
-MongoDB::OID - A Mongo ObjectId
-
-=head1 SEE ALSO
-
-Core documentation on object ids: L<http://dochub.mongodb.org/core/objectids>.
-
 =head1 ATTRIBUTES
 
 =head2 value
@@ -244,9 +228,9 @@ representation used by MongoDB, that is, an OID with the value
 "012345678901234567890123" will be represented as 
 C<{"$oid" : "012345678901234567890123"}>.
 
-=head1 AUTHOR
+=head1 SEE ALSO
 
-  Kristina Chodorow <kristina at mongodb.org>
+Core documentation on object ids: L<http://dochub.mongodb.org/core/objectids>.
 
 =head1 AUTHORS
 
@@ -254,15 +238,15 @@ C<{"$oid" : "012345678901234567890123"}>.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -272,7 +256,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Role/_LastError.pm b/lib/MongoDB/Role/_LastError.pm
index 02d7ad2..be07c3c 100644
--- a/lib/MongoDB/Role/_LastError.pm
+++ b/lib/MongoDB/Role/_LastError.pm
@@ -19,7 +19,7 @@ package MongoDB::Role::_LastError;
 # MongoDB interface for providing the last database error
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose::Role;
 use namespace::clean -except => 'meta';
diff --git a/lib/MongoDB/Role/_Remover.pm b/lib/MongoDB/Role/_Remover.pm
index 44dffb2..b0bff6d 100644
--- a/lib/MongoDB/Role/_Remover.pm
+++ b/lib/MongoDB/Role/_Remover.pm
@@ -19,7 +19,7 @@ package MongoDB::Role::_Remover;
 # Role for remove operations
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose::Role;
 use namespace::clean -except => 'meta';
diff --git a/lib/MongoDB/Role/_Updater.pm b/lib/MongoDB/Role/_Updater.pm
index 7145532..8c8ceeb 100644
--- a/lib/MongoDB/Role/_Updater.pm
+++ b/lib/MongoDB/Role/_Updater.pm
@@ -19,7 +19,7 @@ package MongoDB::Role::_Updater;
 # Role for update and replace operations
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use boolean;
 use Syntax::Keyword::Junction qw/any/;
diff --git a/lib/MongoDB/Role/_View.pm b/lib/MongoDB/Role/_View.pm
index dd6c5d2..bcfa148 100644
--- a/lib/MongoDB/Role/_View.pm
+++ b/lib/MongoDB/Role/_View.pm
@@ -19,7 +19,7 @@ package MongoDB::Role::_View;
 # Role providing a query document
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use MongoDB::_Types;
 use Moose::Role;
diff --git a/lib/MongoDB/Role/_WriteQueue.pm b/lib/MongoDB/Role/_WriteQueue.pm
index f21ea9e..b63c2e4 100644
--- a/lib/MongoDB/Role/_WriteQueue.pm
+++ b/lib/MongoDB/Role/_WriteQueue.pm
@@ -19,7 +19,7 @@ package MongoDB::Role::_WriteQueue;
 # MongoDB interface for queuing operations for execution
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose::Role;
 use namespace::clean -except => 'meta';
diff --git a/lib/MongoDB/Role/_Writeable.pm b/lib/MongoDB/Role/_Writeable.pm
index eafe550..f4fe8b0 100644
--- a/lib/MongoDB/Role/_Writeable.pm
+++ b/lib/MongoDB/Role/_Writeable.pm
@@ -19,7 +19,7 @@ package MongoDB::Role::_Writeable;
 # Role providing a write queue
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose::Role;
 use namespace::clean -except => 'meta';
diff --git a/lib/MongoDB/Timestamp.pm b/lib/MongoDB/Timestamp.pm
index d44c460..4dab410 100644
--- a/lib/MongoDB/Timestamp.pm
+++ b/lib/MongoDB/Timestamp.pm
@@ -20,7 +20,7 @@ package MongoDB::Timestamp;
 # ABSTRACT: Replication timestamp
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 #pod =head1 NAME
 #pod
@@ -80,7 +80,7 @@ MongoDB::Timestamp - Replication timestamp
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -109,15 +109,15 @@ Incrementing field.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -127,7 +127,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/Tutorial.pod b/lib/MongoDB/Tutorial.pod
index 5afbd47..8be0469 100644
--- a/lib/MongoDB/Tutorial.pod
+++ b/lib/MongoDB/Tutorial.pod
@@ -30,7 +30,7 @@ MongoDB::Tutorial - Getting started with MongoDB
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 DESCRIPTION
 
@@ -298,15 +298,15 @@ Check out L<MongoDB::Examples> for more examples.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -316,7 +316,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/WriteResult.pm b/lib/MongoDB/WriteResult.pm
index 5998437..b2bf115 100644
--- a/lib/MongoDB/WriteResult.pm
+++ b/lib/MongoDB/WriteResult.pm
@@ -19,7 +19,7 @@ package MongoDB::WriteResult;
 # ABSTRACT: MongoDB write result document
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose;
 use MongoDB::_Types;
@@ -229,7 +229,7 @@ MongoDB::WriteResult - MongoDB write result document
 
 =head1 VERSION
 
-version v0.705.0.0
+version v0.708.4.0
 
 =head1 SYNOPSIS
 
@@ -363,15 +363,15 @@ C<writeConcernErrors> or the empty string if there are no errors.
 
 =item *
 
-David Golden <david.golden at mongodb.org>
+David Golden <david at mongodb.com>
 
 =item *
 
-Mike Friedman <friedo at mongodb.com>
+Mike Friedman <friedo at friedo.com>
 
 =item *
 
-Kristina Chodorow <kristina at mongodb.org>
+Kristina Chodorow <k.chodorow at gmail.com>
 
 =item *
 
@@ -381,7 +381,7 @@ Florian Ragwitz <rafl at debian.org>
 
 =head1 COPYRIGHT AND LICENSE
 
-This software is Copyright (c) 2014 by MongoDB, Inc..
+This software is Copyright (c) 2015 by MongoDB, Inc..
 
 This is free software, licensed under:
 
diff --git a/lib/MongoDB/_Types.pm b/lib/MongoDB/_Types.pm
index dd190bc..52580ac 100644
--- a/lib/MongoDB/_Types.pm
+++ b/lib/MongoDB/_Types.pm
@@ -19,7 +19,7 @@ package MongoDB::_Types;
 # MongoDB Moose type definitions
 
 use version;
-our $VERSION = 'v0.705.0.0';
+our $VERSION = 'v0.708.4.0'; # from MongoDB-v0.708.4.0.tar.gz
 
 use Moose::Util::TypeConstraints;
 
diff --git a/mongo_link.c b/mongo_link.c
index 3fccdd0..3023207 100644
--- a/mongo_link.c
+++ b/mongo_link.c
@@ -28,13 +28,15 @@ static int mongo_link_timeout(int socket, time_t timeout);
 
 static void set_timeout(int socket, time_t timeout) {
 #ifdef WIN32
+  const char *tv_ptr;
   DWORD tv = (DWORD)timeout;
-  const char *tv_ptr = (const char*)&tv;
+  tv_ptr = (const char*)&tv;
 #else
+  const void *tv_ptr;
   struct timeval tv;
   tv.tv_sec = timeout / 1000;
   tv.tv_usec = (timeout % 1000) * 1000;
-  const void *tv_ptr = (void*)&tv;
+  tv_ptr = (void*)&tv;
 #endif
   setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, tv_ptr, sizeof(tv));
   setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, tv_ptr, sizeof(tv));
@@ -135,6 +137,8 @@ static void sasl_authenticate( SV *client, mongo_link *link ) {
 #endif  /* MONGO_SASL */
 
 void perl_mongo_connect(SV *client, mongo_link* link) {
+  SV* sasl_flag;
+
 #ifdef MONGO_SSL
   if(link->ssl){
     ssl_connect(link);
@@ -148,7 +152,7 @@ void perl_mongo_connect(SV *client, mongo_link* link) {
   link->sender = non_ssl_send;
   link->receiver = non_ssl_recv;
 
-  SV* sasl_flag = perl_mongo_call_method( client, "sasl", 0, 0 );
+  sasl_flag = perl_mongo_call_method( client, "sasl", 0, 0 );
 
   if ( link->master->connected && SvIV(sasl_flag) == 1 ) {
 #ifdef MONGO_SASL
@@ -511,7 +515,7 @@ int mongo_link_hear(SV *cursor_sv) {
   if ((sock = perl_mongo_master(link_sv, 0)) == -1) {
     set_disconnected(link_sv);
     SvREFCNT_dec(link_sv);
-    croak("can't get db response, not connected");
+    croak("can't get db response, not connected (during receive)");
   }
 
   timeout = SvIV(timeout_sv);
@@ -539,7 +543,7 @@ int mongo_link_hear(SV *cursor_sv) {
 
   if (get_header(sock, cursor_sv, link_sv) == 0) {
     SvREFCNT_dec(link_sv);
-    croak("can't get db response, not connected");
+    croak("can't get db response, not connected (invalid response header)");
     return 0;
   }
 
diff --git a/perl_mongo.c b/perl_mongo.c
index 99e6783..72f4007 100644
--- a/perl_mongo.c
+++ b/perl_mongo.c
@@ -36,12 +36,10 @@ static SV *bson_to_sv (bson_iter_t * iter, char *dt_type, int inflate_dbrefs, in
 static perl_mutex inc_mutex;
 #endif
 
-static int perl_mongo_inc = 0;
 int perl_mongo_machine_id;
 
 static SV *utf8_flag_on;
 static SV *use_binary;
-static SV *use_boolean;
 static SV *special_char;
 static SV *look_for_numbers;
 
@@ -49,7 +47,6 @@ void perl_mongo_init() {
   MUTEX_INIT(&inc_mutex);
   utf8_flag_on = get_sv("MongoDB::BSON::utf8_flag_on", 0);
   use_binary = get_sv("MongoDB::BSON::use_binary", 0);
-  use_boolean = get_sv("MongoDB::BSON::use_boolean", 0);
   special_char = get_sv("MongoDB::BSON::char", 0);
   look_for_numbers = get_sv("MongoDB::BSON::looks_like_number", 0);
 }
@@ -182,6 +179,10 @@ perl_mongo_call_function (const char *func, int num, ...) {
 }
 
 static void perl_mongo_regex_flags( char *flags_ptr, SV *re ) {
+  int ret_count;
+  SV *flags_sv;
+  SV *pat_sv;
+  char *flags;
   dSP;
   ENTER;
   SAVETMPS;
@@ -189,7 +190,7 @@ static void perl_mongo_regex_flags( char *flags_ptr, SV *re ) {
   XPUSHs (re);
   PUTBACK;
 
-  int ret_count = call_pv( "re::regexp_pattern", G_ARRAY );
+  ret_count = call_pv( "re::regexp_pattern", G_ARRAY );
   SPAGAIN;
 
   if ( ret_count != 2 ) { 
@@ -197,10 +198,10 @@ static void perl_mongo_regex_flags( char *flags_ptr, SV *re ) {
   }
 
   // regexp_pattern returns two items (in list context), the pattern and a list of flags
-  SV *flags_sv = POPs;
-  SV *pat_sv   = POPs;
+  flags_sv = POPs;
+  pat_sv   = POPs;
 
-  char *flags = SvPVutf8_nolen(flags_sv);
+  flags = SvPVutf8_nolen(flags_sv);
 
   strncpy( flags_ptr, flags, 7 );
 }
@@ -435,11 +436,6 @@ elem_to_sv (const bson_iter_t * iter, char *dt_type, int inflate_dbrefs, int inf
     bool d = bson_iter_bool(iter);
     int count;
 
-    if (!use_boolean) {
-      value = newSViv(d);
-      break;
-    }
-
     SAVETMPS;
 
     PUSHMARK(SP);
@@ -494,9 +490,11 @@ elem_to_sv (const bson_iter_t * iter, char *dt_type, int inflate_dbrefs, int inf
       // raw epoch
       value = newSViv(ms_i);
     } else if ( strcmp( dt_type, "DateTime::Tiny" ) == 0 ) {
+      time_t epoch;
+      struct tm *dt;
       datetime = sv_2mortal(newSVpv("DateTime::Tiny", 0));
-      time_t epoch = bson_iter_time_t(iter);
-      struct tm *dt = gmtime( &epoch );
+      epoch = bson_iter_time_t(iter);
+      dt = gmtime( &epoch );
 
       value = 
         perl_mongo_call_function("DateTime::Tiny::new", 13, datetime,
@@ -619,10 +617,11 @@ elem_to_sv (const bson_iter_t * iter, char *dt_type, int inflate_dbrefs, int inf
   case BSON_TYPE_CODE: {
     const char * code;
     uint32_t len;
-    
+    SV *code_sv;
+
     code = bson_iter_code(iter, &len);
 
-    SV * code_sv = sv_2mortal(newSVpvn(code, len));
+    code_sv = sv_2mortal(newSVpvn(code, len));
 
     value = perl_mongo_construct_instance("MongoDB::Code", "code", code_sv, NULL);
 
@@ -632,19 +631,19 @@ elem_to_sv (const bson_iter_t * iter, char *dt_type, int inflate_dbrefs, int inf
     const char * code;
     const uint8_t * scope;
     uint32_t code_len, scope_len;
-
-    code = bson_iter_codewscope(iter, &code_len, &scope_len, &scope);
-
-    SV * code_sv = sv_2mortal(newSVpvn(code, code_len));
-
+    SV * code_sv;
+    SV * scope_sv;
     bson_t bson;
     bson_iter_t child;
 
+    code = bson_iter_codewscope(iter, &code_len, &scope_len, &scope);
+    code_sv = sv_2mortal(newSVpvn(code, code_len));
+
     if ( ! ( bson_init_static(&bson, scope, scope_len) && bson_iter_init(&child, &bson) ) ) {
         croak("error iterating BSON type %d\n", bson_iter_type(iter));
     }
 
-    SV * scope_sv = bson_to_sv(&child, dt_type, inflate_dbrefs, inflate_regexps, client );
+    scope_sv = bson_to_sv(&child, dt_type, inflate_dbrefs, inflate_regexps, client );
     value = perl_mongo_construct_instance("MongoDB::Code", "code", code_sv, "scope", scope_sv, NULL);
 
     break;
@@ -719,10 +718,10 @@ perl_mongo_buffer_to_sv(buffer * buffer, char * dt_type, int inflate_dbrefs, int
 SV *
 perl_mongo_bson_to_sv (const bson_t * bson, char *dt_type, int inflate_dbrefs, int inflate_regexps, SV *client )
 {
+  bson_iter_t iter;
   utf8_flag_on = get_sv("MongoDB::BSON::utf8_flag_on", 0);
   use_binary = get_sv("MongoDB::BSON::use_binary", 0);
 
-  bson_iter_t iter;
   if ( ! bson_iter_init(&iter, bson) ) {
       croak( "error creating BSON iterator" );
   }
@@ -1034,6 +1033,12 @@ ixhash_to_bson(bson_t * bson, SV *sv, AV *ids, stackette *stack, int is_insert)
 
     str = SvPVutf8(*k, len);
     containsNullChar(str,len);
+
+    /* if we've already added the oid field, continue */
+    if (ids && strcmp(str, "_id") == 0) {
+        continue;
+    }
+
     append_sv(bson, str, *v, stack, is_insert);
   }
 
@@ -1096,7 +1101,7 @@ const char * clean_key(const char * str, int is_insert) {
   }
 
   if (special_char && SvPOK(special_char) && SvPV_nolen(special_char)[0] == str[0]) {
-    char * out = strdup(str);
+    char * out = savepv(str);
 
     *out = '$';
 
@@ -1115,14 +1120,14 @@ append_sv (bson_t * bson, const char * in_key, SV *sv, stackette *stack, int is_
     if (SvGMAGICAL(sv)) {
       mg_get(sv);
     }
-    else {
+  }
+
+  if (!SvOK(sv)) {
       bson_append_null(bson, key, -1);
-      if (in_key != key) free((char *)key);
+      if (in_key != key) Safefree((char *)key);
       return;
-    }
   }
-
-  if (SvROK (sv)) {
+  else if (SvROK(sv)) {
     if (sv_isobject (sv)) {
       /* OIDs */
       if (sv_derived_from (sv, "MongoDB::OID")) {
@@ -1369,7 +1374,8 @@ append_sv (bson_t * bson, const char * in_key, SV *sv, stackette *stack, int is_
         croak ("type (%s) unhandled", HvNAME(SvSTASH(SvRV(sv))));
       }
     } else {
-      switch (SvTYPE (SvRV (sv))) {
+      SV *deref = SvRV(sv);
+      switch (SvTYPE (deref)) {
       case SVt_PVHV: {
         /* hash */
         bson_t child;
@@ -1387,14 +1393,16 @@ append_sv (bson_t * bson, const char * in_key, SV *sv, stackette *stack, int is_
         bson_append_array_end(bson, &child);
         break;
       }
-      case SVt_PV:
-        /* binary */
-
-        serialize_binary(bson, key, BSON_SUBTYPE_BINARY, SvRV(sv));
-        break;
-      default:
-        sv_dump(SvRV(sv));
-        croak ("type (ref) unhandled");
+      default: {
+          if ( SvPOK(deref) ) {
+            /* binary */
+            serialize_binary(bson, key, BSON_SUBTYPE_BINARY, deref);
+          }
+          else {
+            sv_dump(deref);
+            croak ("type (ref) unhandled");
+          }
+        }
       }
     }
   } else {
@@ -1421,6 +1429,16 @@ append_sv (bson_t * bson, const char * in_key, SV *sv, stackette *stack, int is_
     }
 #endif
 
+#if PERL_REVISION==5 && PERL_VERSION<=18
+    /* Before 5.18, get magic would clear public flags. This restores them
+     * from private flags but ONLY if there is no public flag already, as
+     * we have nothing else to go on for serialization.
+     */
+    if (!(SvFLAGS(sv) & (SVf_IOK|SVf_NOK|SVf_POK))) {
+        SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
+    }
+#endif
+
     if (look_for_numbers && SvIOK(look_for_numbers) && SvIV(look_for_numbers)) {
       aggressively_number = looks_like_number(sv);
     }
@@ -1477,32 +1495,33 @@ append_sv (bson_t * bson, const char * in_key, SV *sv, stackette *stack, int is_
     }
   }
 
-  if (in_key != key) free((char *)key);
+  if (in_key != key) Safefree((char *)key);
 }
 
 static void serialize_regex_obj(bson_t *bson, const char *key, 
                                 const char *pattern, const char *flags ) { 
   size_t pattern_length = strlen( pattern );
-  size_t flags_length   = strlen( flags );
+  char *buf;
 
-  char *buf = malloc( pattern_length + 1 ); 
-  memcpy( buf, pattern, pattern_length );
+  Newx(buf, pattern_length + 1, char );
+  Copy(pattern, buf, pattern_length, char );
   buf[ pattern_length ] = '\0';
   bson_append_regex(bson, key, -1, buf, flags);
-  free(buf);
+  Safefree(buf);
 }
 
 static void serialize_regex(bson_t * bson, const char *key, REGEXP *re, SV * sv) {
   char flags[]     = {0,0,0,0,0};
+  char * buf;
   serialize_regex_flags(flags, sv);
 
-  char * buf = malloc(RX_PRELEN(re) + 1);
-  memcpy(buf, RX_PRECOMP(re), RX_PRELEN(re));
+  Newx(buf, (RX_PRELEN(re) + 1), char );
+  Copy(RX_PRECOMP(re), buf, RX_PRELEN(re), char );
   buf[RX_PRELEN(re)] = '\0';
 
   bson_append_regex(bson, key, -1, buf, flags);
 
-  free(buf);
+  Safefree(buf);
 }
 
 static void serialize_regex_flags(char * flags, SV *sv) {
@@ -1654,6 +1673,11 @@ perl_mongo_sv_to_bson (bson_t * bson, SV *sv, AV *ids) {
 
         str = SvPVutf8(*key, len);
 
+        /* if we've already added the oid field, continue */
+        if (ids && strcmp(str, "_id") == 0) {
+            continue;
+        }
+
         append_sv (bson, str, *val, EMPTY_STACK, is_insert);
       }
     }
diff --git a/t/00-report-prereqs.dd b/t/00-report-prereqs.dd
index b92dfdf..9357ad5 100644
--- a/t/00-report-prereqs.dd
+++ b/t/00-report-prereqs.dd
@@ -8,11 +8,14 @@ do { my $x = {
                       },
        'develop' => {
                       'requires' => {
-                                      'Test::Pod' => '1.41'
+                                      'Test::More' => '0',
+                                      'Test::Pod' => '1.41',
+                                      'Test::Version' => '1'
                                     }
                     },
        'runtime' => {
                       'requires' => {
+                                      'Authen::SCRAM::Client' => '0.003',
                                       'Carp' => '0',
                                       'Class::MOP::Class' => '0',
                                       'DateTime' => '0.78',
@@ -20,6 +23,7 @@ do { my $x = {
                                       'Encode' => '0',
                                       'Exporter' => '5.57',
                                       'IO::File' => '0',
+                                      'MIME::Base64' => '0',
                                       'Moose' => '0',
                                       'Moose::Meta::Class' => '0',
                                       'Moose::Role' => '0',
@@ -49,10 +53,8 @@ do { my $x = {
                                    },
                    'requires' => {
                                    'Data::Dumper' => '0',
-                                   'Data::Types' => '0',
                                    'DateTime::Tiny' => '0',
                                    'ExtUtils::MakeMaker' => '0',
-                                   'File::Slurp' => '0',
                                    'File::Spec' => '0',
                                    'File::Temp' => '0',
                                    'FileHandle' => '0',
@@ -63,7 +65,7 @@ do { my $x = {
                                    'Test::Warn' => '0',
                                    'bigint' => '0',
                                    'lib' => '0',
-                                   'threads' => '0',
+                                   'threads::shared' => '0',
                                    'utf8' => '0'
                                  }
                  }
diff --git a/t/00-report-prereqs.t b/t/00-report-prereqs.t
index 6e46540..d8d15ba 100644
--- a/t/00-report-prereqs.t
+++ b/t/00-report-prereqs.t
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 
-# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.018
+# This test was generated by Dist::Zilla::Plugin::Test::ReportPrereqs 0.021
 
 use Test::More tests => 1;
 
@@ -70,12 +70,6 @@ my @exclude = qw(
 # Add static prereqs to the included modules list
 my $static_prereqs = do 't/00-report-prereqs.dd';
 
-### XXX: Assume these are Runtime Requires
-my $static_prereqs_requires = $static_prereqs->{runtime}{requires};
-for my $mod (@include) {
-    $static_prereqs_requires->{$mod} = 0 unless exists $static_prereqs_requires->{$mod};
-}
-
 # Merge all prereqs (either with ::Prereqs or a hashref)
 my $full_prereqs = _merge_prereqs(
     ( $HAS_CPAN_META ? $cpan_meta_pre->new : {} ),
@@ -97,11 +91,16 @@ my @full_reports;
 my @dep_errors;
 my $req_hash = $HAS_CPAN_META ? $full_prereqs->as_string_hash : $full_prereqs;
 
-for my $phase ( qw(configure build test runtime develop) ) {
+# Add static includes into a fake section
+for my $mod (@include) {
+    $req_hash->{other}{modules}{$mod} = 0;
+}
+
+for my $phase ( qw(configure build test runtime develop other) ) {
     next unless $req_hash->{$phase};
     next if ($phase eq 'develop' and not $ENV{AUTHOR_TESTING});
 
-    for my $type ( qw(requires recommends suggests conflicts) ) {
+    for my $type ( qw(requires recommends suggests conflicts modules) ) {
         next unless $req_hash->{$phase}{$type};
 
         my $title = ucfirst($phase).' '.ucfirst($type);
@@ -151,9 +150,16 @@ for my $phase ( qw(configure build test runtime develop) ) {
             my $ml = _max( map { length $_->[0] } @reports );
             my $wl = _max( map { length $_->[1] } @reports );
             my $hl = _max( map { length $_->[2] } @reports );
-            splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl];
 
-            push @full_reports, map { sprintf("    %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports;
+            if ($type eq 'modules') {
+                splice @reports, 1, 0, ["-" x $ml, "", "-" x $hl];
+                push @full_reports, map { sprintf("    %*s %*s\n", -$ml, $_->[0], $hl, $_->[2]) } @reports;
+            }
+            else {
+                splice @reports, 1, 0, ["-" x $ml, "-" x $wl, "-" x $hl];
+                push @full_reports, map { sprintf("    %*s %*s %*s\n", -$ml, $_->[0], $wl, $_->[1], $hl, $_->[2]) } @reports;
+            }
+
             push @full_reports, "\n";
         }
     }
diff --git a/t/bson.t b/t/bson.t
index 9407e01..b09c1a5 100644
--- a/t/bson.t
+++ b/t/bson.t
@@ -24,7 +24,6 @@ use MongoDB;
 use MongoDB::OID;
 use boolean;
 use DateTime;
-use Data::Types qw(:float);
 use Encode;
 use Tie::IxHash;
 use Test::Fatal;
@@ -77,7 +76,7 @@ my $c = $testdb->get_collection('bar');
 
     is($obj->{'n'}, undef);
     is($obj->{'l'}, 234234124);
-    is($obj->{'d'}, 23.23451452);
+    ok( abs( $obj->{'d'} - 23.23451452) < 1e-6 );
     is($obj->{'b'}, true);
     is($obj->{'a'}->{'foo'}, 'bar');
     is($obj->{'a'}->{'n'}, undef);
@@ -254,7 +253,7 @@ package main;
     $c->save($p);
 
     my $person = $c->find_one;
-    ok(is_float($person->{'age'}));
+    is($person->{'age'}, 22, "roundtrip number");
 }
 
 # warn on floating timezone
@@ -266,6 +265,13 @@ package main;
     is($warned, 1, "warn on floating timezone");
 }
 
+# epoch should be legal
+{
+    my $date = DateTime->from_epoch( epoch => 0 );
+    is( exception { $c->insert( { "date" => $date } ) },
+        undef, "inserting DateTime at epoch succeeds" );
+}
+
 # half-conversion to int type
 {
     $c->drop;
@@ -413,4 +419,30 @@ package main;
     is ( $obj->{$testkey}, 1 );
 }
 
+subtest "PERL-489 ref to PVNV" => sub {
+    my $value = 42.2;
+    $value = "hello";
+    is(
+        exception { $c->insert( { value => \$value } ) },
+        undef,
+        "inserting ref to PVNV is not fatal",
+    );
+};
+
+subtest "PERL-543 IxHash undef" => sub {
+    $c->drop;
+    my %h;
+    tie(%h, 'Tie::IxHash', x => undef);
+    $c->insert(\%h);
+    my $doc = $c->find_one;
+    is( $doc->{x}, undef, "round-trip undef with IxHash" );
+
+    $c->drop;
+    my %doc = ( x => undef );
+    $c->insert(\%doc);
+    $doc = $c->find_one;
+    is( $doc->{x}, undef, "round-trip undef with regular hash" );
+};
+
+
 done_testing;
diff --git a/t/bulk.t b/t/bulk.t
index 257f56a..7549861 100644
--- a/t/bulk.t
+++ b/t/bulk.t
@@ -1022,21 +1022,6 @@ for my $method (qw/initialize_ordered_bulk_op initialize_unordered_bulk_op/) {
     };
 }
 
-note("NO JOURNAL");
-for my $method (qw/initialize_ordered_bulk_op initialize_unordered_bulk_op/) {
-    subtest "$method: no journal" => sub {
-        plan skip_all => 'needs a standalone server without journaling'
-          unless $is_standalone && !exists $server_status->{dur};
-
-        $coll->drop;
-        my $bulk = $coll->$method;
-        $bulk->insert( {} );
-        my $err = exception { $bulk->execute( { j => 1 } ) };
-        isa_ok( $err, 'MongoDB::DatabaseError', "executing j:1 on nojournal throws error" );
-        like( $err->message, qr/journal/, "error message mentions journal" );
-    };
-}
-
 note("QA-477 W>1 AGAINST STANDALONE");
 for my $method (qw/initialize_ordered_bulk_op initialize_unordered_bulk_op/) {
     subtest "$method: w > 1 against standalone (explicit)" => sub {
diff --git a/t/collection.t b/t/collection.t
index c7baab5..c3482f1 100644
--- a/t/collection.t
+++ b/t/collection.t
@@ -22,7 +22,6 @@ use Test::Fatal;
 use Test::Warn;
 
 use utf8;
-use Data::Types qw(:float);
 use Tie::IxHash;
 use Encode qw(encode decode);
 use MongoDB::Timestamp; # needed if db is being run as master
@@ -56,6 +55,21 @@ my $tied;
     $testdb->drop;
 }
 
+# get_namespace
+{
+    $testdb->drop;
+    my $dbname = $testdb->name;
+
+    $coll = $conn->get_namespace("$dbname.test_collection");
+    isa_ok($coll, 'MongoDB::Collection');
+    is($coll->name, 'test_collection', 'get name');
+
+    $coll = $conn->ns("$dbname.test_collection");
+    isa_ok($coll, 'MongoDB::Collection');
+    is($coll->name, 'test_collection', 'get name');
+
+}
+
 # very small insert
 {
     $id = $coll->insert({_id => 1});
@@ -126,138 +140,6 @@ my $tied;
     is($coll->count, 0, 'remove() deleted everything (won\'t work on an old version of Mongo)');
 }
 
-# basic indexes
-{
-    my $res;
-
-    $coll->drop;
-    for (my $i=0; $i<10; $i++) {
-        $coll->insert({'x' => $i, 'z' => 3, 'w' => 4});
-        $coll->insert({'x' => $i, 'y' => 2, 'z' => 3, 'w' => 4});
-    }
-
-    $coll->drop;
-    ok(!$coll->get_indexes, 'no indexes yet');
-
-    my $indexes = Tie::IxHash->new(foo => 1, bar => 1, baz => 1);
-    $res = $coll->ensure_index($indexes);
-    if ( $server_version >= v2.6.0 ) {
-        ok $res->{ok};
-    } else { 
-        ok(!defined $res);
-    }
-
-    my $err = $testdb->last_error;
-    is($err->{ok}, 1);
-    is($err->{err}, undef);
-
-    $indexes = Tie::IxHash->new(foo => 1, bar => 1);
-    $res = $coll->ensure_index($indexes);
-
-    if ( $server_version >= v2.6.0 ) {
-        ok $res->{ok};
-    } else { 
-        ok(!defined $res);
-    }
-
-    $coll->insert({foo => 1, bar => 1, baz => 1, boo => 1});
-    $coll->insert({foo => 1, bar => 1, baz => 1, boo => 2});
-    is($coll->count, 2);
-
-    $res = $coll->ensure_index({boo => 1}, {unique => 1});
-
-    if ( $server_version >= v2.6.0 ) {
-        ok $res->{ok};
-    } else { 
-        ok(!defined $res);
-    }
-
-    eval { $coll->insert({foo => 3, bar => 3, baz => 3, boo => 2}) };
-
-    is($coll->count, 2, 'unique index');
-
-    my @indexes = $coll->get_indexes;
-    is(scalar @indexes, 4, 'three custom indexes and the default _id_ index');
-    is_deeply(
-        [sort keys %{ $indexes[1]->{key} }],
-        [sort qw/foo bar baz/],
-    );
-    is_deeply(
-        [sort keys %{ $indexes[2]->{key} }],
-        [sort qw/foo bar/],
-    );
-
-    $coll->drop_index($indexes[1]->{name});
-    @indexes = $coll->get_indexes;
-    is(scalar @indexes, 3);
-    is_deeply(
-        [sort keys %{ $indexes[1]->{key} }],
-        [sort qw/foo bar/],
-    );
-
-    $coll->drop;
-    ok(!$coll->get_indexes, 'no indexes after dropping');
-
-    # make sure this still works
-    $coll->ensure_index({"foo" => 1});
-    @indexes = $coll->get_indexes;
-    is(scalar @indexes, 2, '1 custom index and the default _id_ index');
-    $coll->drop;
-}
-
-# test ensure index with drop_dups
-{
-
-    $coll->insert({foo => 1, bar => 1, baz => 1, boo => 1});
-    $coll->insert({foo => 1, bar => 1, baz => 1, boo => 2});
-    is($coll->count, 2);
-
-    eval { $coll->ensure_index({foo => 1}, {unique => 1}) };
-    like( $@, qr/E11000/, "got expected error creating unique index with dups" );
-
-    my $res = $coll->ensure_index({foo => 1}, {unique => 1, drop_dups => 1});
-
-    if ( $server_version >= v2.6.0 ) {
-        ok $res->{ok};
-    } else {
-        ok(!defined $res);
-    }
-
-    $coll->drop;
-}
-
-
-# test new form of ensure index
-{
-    my $res;
-    $res = $coll->ensure_index({foo => 1, bar => -1, baz => 1});
-
-    if ( $server_version >= v2.6.0 ) {
-        ok $res->{ok};
-    } else { 
-        ok(!defined $res);
-    }
-
-    $res = $coll->ensure_index([foo => 1, bar => 1]);
-
-    if ( $server_version >= v2.6.0 ) {
-        ok $res->{ok};
-    } else { 
-        ok(!defined $res);
-    }
-
-    $coll->insert({foo => 1, bar => 1, baz => 1, boo => 1});
-    $coll->insert({foo => 1, bar => 1, baz => 1, boo => 2});
-    is($coll->count, 2);
-
-    # unique index
-    $coll->ensure_index({boo => 1}, {unique => 1});
-    eval { $coll->insert({foo => 3, bar => 3, baz => 3, boo => 2}) };
-    is($coll->count, 2, 'unique index');
-
-    $coll->drop;
-}
-
 # doubles
 {
     my $pi = 3.14159265;
@@ -272,7 +154,7 @@ my $tied;
     $object->{'price'} = 123.19;
     $coll->insert($object);
     my $auto = $coll->find_one;
-    ok(is_float($auto->{'price'}));
+    like($auto->{'price'}, qr/^123\.\d+/, "round trip float looks like float");
     ok(abs($auto->{'price'} - $object->{'price'}) < .000000001);
 }
 
@@ -528,27 +410,19 @@ SKIP: {
     }
 }
 
-# safe remove/update
+# safe update
 {
     $coll->drop;
+    $coll->ensure_index({name => 1}, {unique => 1});
+    $coll->insert( {name => 'Alice'} );
+    $coll->insert( {name => 'Bob'} );
 
-    $ok = $coll->remove;
-    is($ok, 1, 'unsafe remove');
-    is($testdb->last_error->{n}, 0);
-
-    my $syscoll = $testdb->get_collection('system.indexes');
-    eval {
-        $ok = $syscoll->remove({}, {safe => 1});
-    };
-
-    like($@, qr/cannot delete from system namespace|not authorized/, 'remove from system.indexes should fail');
-
-    $coll->insert({x=>1});
-    $ok = $coll->update({}, {'$inc' => {x => 1}});
-    is($ok->{ok}, 1);
-
-    $ok = $coll->update({}, {'$inc' => {x => 2}}, {safe => 1});
-    is($ok->{ok}, 1);
+    for my $h ( undef, { safe => 1 } ) {
+        my $err = exception { $coll->update( { name => 'Alice'}, { '$set' => { name => 'Bob' } }, $h ) };
+        my $case = $h ? "explicit" : "default";
+        ok( $err, "bad update with $case safe gives error");
+        ok( $coll->update( { name => 'Alice' }, { '$set' => { age => 23 } }, $h ), "did legal update" );
+    }
 }
 
 # save
@@ -566,13 +440,6 @@ SKIP: {
 
     my $z = $coll->find_one;
     is($z->{"hello"}, 3);
-
-    my $syscoll = $testdb->get_collection('system.indexes');
-    eval {
-        $ok = $syscoll->save({_id => 'foo'}, {safe => 1});
-    };
-
-    like($@, qr/cannot update system collection|not authorized/, 'save to system.indexes should fail');
 }
 
 # find
@@ -621,7 +488,7 @@ SKIP: {
 {
 
     $ok = $coll->ensure_index({"x.y" => 1}, {"name" => "foo"});
-    my $index = $coll->_database->get_collection("system.indexes")->find_one({"name" => "foo"});
+    my ($index) = grep { $_->{name} eq 'foo' } $coll->get_indexes;
     ok($index);
     ok($index->{'key'});
     ok($index->{'key'}->{'x.y'});
@@ -637,11 +504,11 @@ SKIP: {
     is($coll->count, 20);
 
     eval { $coll->ensure_index({"y" => 1}, {"unique" => 1, "name" => "foo"}) };
-    my $index = $coll->_database->get_collection("system.indexes")->find_one({"name" => "foo"});
+    my ($index) = grep { $_->{name} eq 'foo' } $coll->get_indexes;
     ok(!$index);
 
     $coll->ensure_index({"y" => 1}, {"unique" => 1, "sparse" => 1, "name" => "foo"});
-    $index = $coll->_database->get_collection("system.indexes")->find_one({"name" => "foo"});
+    ($index) = grep { $_->{name} eq 'foo' } $coll->get_indexes;
     ok($index);
 
     $coll->drop;
@@ -673,21 +540,22 @@ subtest 'text indices' => sub {
         ok(!defined $res);
     }
 
-    my $syscoll = $testdb->get_collection('system.indexes');
-    my $text_index = $syscoll->find_one({name => 'testTextIndex'});
+    my ($text_index) = grep { $_->{name} eq 'testTextIndex' } $coll->get_indexes;
     is($text_index->{'default_language'}, 'spanish', 'default_language option works');
     is($text_index->{'language_override'}, 'language', 'language_override option works');
     is($text_index->{'weights'}->{'w1'}, 5, 'weights option works 1');
     is($text_index->{'weights'}->{'w2'}, 10, 'weights option works 2');
 
-    my $search = $testdb->run_command(['text' => 'test_text', 'search' => 'world']);
-
-    # 2.6 changed the response format for text search results, and deprecated
-    # the 'text' command. On 2.4, mongos doesn't report the default language
-    # and provides stats per shard instead of in total.
-    if ( ! ( $server_version >= v2.6.0 || $conn->_is_mongos) ) {
-        is($search->{'language'}, 'spanish', 'text search uses preferred language');
-        is($search->{'stats'}->{'nfound'}, 10, 'correct number of results found');
+    # 2.6 deprecated 'text' command and added '$text' operator; also the
+    # result format changed.
+    if ( $server_version >= v2.6.0 ) {
+        my $n_found =()= $coll->find( { '$text' => { '$search' => 'world' } } )->all;
+        is( $n_found, 10, "correct number of results found" );
+    }
+    else {
+        my $results =
+          $testdb->run_command( [ 'text' => 'test_text', 'search' => 'world' ] )->{results};
+        is( scalar(@$results), 10, "correct number of results found" );
     }
 
     $coll->drop;
@@ -931,7 +799,7 @@ sub _check_parallel_results {
     local $Test::Builder::Level = $Test::Builder::Level+1;
 
     my %seen;
-    my $count;
+    my $count = 0;
     for my $i (0 .. $#cursors ) {
         my @chunk = $cursors[$i]->all;
         if ( $num_docs ) {
diff --git a/t/connection.t b/t/connection.t
index 3131243..58d4be2 100644
--- a/t/connection.t
+++ b/t/connection.t
@@ -137,6 +137,7 @@ subtest "options" => sub {
 
         my $ssl = "true";
         my $timeout = 40000;
+        local $SIG{__WARN__} = sub {};
         my $client = MongoDB::MongoClient->new({host => "mongodb://localhost/?ssl=$ssl&connectTimeoutMS=$timeout", auto_connect => 0});
 
         is( $client->ssl, 1, "connect with ssl set" );
@@ -193,7 +194,7 @@ subtest "options" => sub {
 {
 
     is $conn->min_wire_version, 0, 'default min wire version';
-    is $conn->max_wire_version, 2, 'default max wire version';
+    is $conn->max_wire_version, 3, 'default max wire version';
 
     like(
         exception { MongoDBTest::build_client( min_wire_version => 99, max_wire_version => 100) },
diff --git a/t/cursor.t b/t/cursor.t
index 5dc5635..ae976fc 100644
--- a/t/cursor.t
+++ b/t/cursor.t
@@ -189,15 +189,27 @@ $testdb->drop;
 # explain
 {
     my $exp = $cursor->explain;
-    is($exp->{'n'}, 501, 'explain');
-    is($exp->{'cursor'}, 'BasicCursor');
 
-    $cursor->reset;
-    $exp = $cursor->limit(20)->explain;
-    is(20, $exp->{'n'}, 'explain limit');
-    $cursor->reset;
-    $exp = $cursor->limit(-20)->explain;
-    is(20, $exp->{'n'});
+    if ( $server_version >= v2.7.3 ) {
+        is ($exp->{executionStats}{nReturned}, 501, "count of items" );
+        $cursor->reset;
+        $exp = $cursor->limit(20)->explain;
+        is ($exp->{executionStats}{nReturned}, 20, "explain with limit" );
+        $cursor->reset;
+        $exp = $cursor->limit(-20)->explain;
+        is ($exp->{executionStats}{nReturned}, 20, "explain with negative limit" );
+    }
+    else {
+        is($exp->{'n'}, 501, 'explain');
+        is($exp->{'cursor'}, 'BasicCursor');
+
+        $cursor->reset;
+        $exp = $cursor->limit(20)->explain;
+        is(20, $exp->{'n'}, 'explain limit');
+        $cursor->reset;
+        $exp = $cursor->limit(-20)->explain;
+        is(20, $exp->{'n'});
+    }
 }
 
 # hint
diff --git a/t/database.t b/t/database.t
index a3503d4..f9af356 100644
--- a/t/database.t
+++ b/t/database.t
@@ -47,24 +47,30 @@ my $server_version = server_version($conn);
 # collection_names
 {
     is(scalar $testdb->collection_names, 0, 'no collections');
+
     my $coll = $testdb->get_collection('test');
-    is($coll->count, 0, 'collection is empty');
 
-    is($coll->find_one, undef, 'nothing for find_one');
+    my $cmd = [ create => "test_capped", capped => 1, size => 10000 ];
+    $testdb->run_command($cmd);
+    my $cap = $testdb->get_collection("test_capped");
+
+    $coll->ensure_index([ name => 1]);
+    $cap->ensure_index([ name => 1]);
 
-    my $id = $coll->insert({ just => 'another', perl => 'hacker' });
+    ok($coll->insert({name => 'Alice'}), "create test collection");
+    ok($cap->insert({name => 'Bob'}), "create capped collection");
 
-    is(scalar $testdb->collection_names, 2, 'test and system.indexes');
-    ok((grep { $_ eq 'test' } $testdb->collection_names), 'collection_names');
-    is($coll->count, 1, 'count');
-    is($coll->find_one->{perl}, 'hacker', 'find_one');
-    is($coll->find_one->{_id}->value, $id->value, 'insert id');
+    my %names = map {; $_ => 1 } $testdb->collection_names;
+    for my $k ( qw/test test_capped/ ) {
+        ok( exists $names{$k}, "collection_names included $k" );
+    }
 }
 
 # non-existent command
 {
     my $result = $testdb->run_command({ foo => 'bar' });
-    like ($result, qr/no such cmd|unrecognized command/, "error from non-existent command");
+    # server keeps changing what it sends
+    like ($result, qr/no such command|no such cmd|unrecognized command/, "error from non-existent command");
 }
 
 # getlasterror
diff --git a/t/gridfs.t b/t/gridfs.t
index 2f52ca2..3c69839 100644
--- a/t/gridfs.t
+++ b/t/gridfs.t
@@ -18,9 +18,9 @@
 use strict;
 use warnings;
 use Test::More;
+use Test::Fatal;
 use IO::File;
 use File::Temp;
-use File::Slurp qw(read_file write_file);
 use MongoDB::Timestamp; # needed if db is being run as master
 
 use MongoDB;
@@ -34,13 +34,16 @@ use MongoDBTest qw/build_client get_test_db/;
 
 my $testdb = get_test_db(build_client());
 
-plan tests => 62;
-
 my $dumb_str;
 my $now;
 my $file;
 my $save_id;
 
+# XXX work around SERVER-18062; create collection to initialize DB for
+# sharded collection so gridfs index creation doesn't fail
+$testdb->coll("testtesttest")->insert({});
+
+# DB initialized, so now get gridfs object
 my $grid = $testdb->get_gridfs;
 $grid->drop;
 
@@ -204,7 +207,7 @@ $grid->drop;
         my $txt = "HELLO" x 1_000_000; # 5MB
         
         my $fh = File::Temp->new;
-        write_file( $fh->filename, $txt ) || die $!;
+        $fh->printflush( $txt ) or die $!;
         $fh->seek(0, 0);
 
         $grid->insert( $fh, { filename => $fh->filename } );
@@ -288,3 +291,46 @@ $grid->drop;
     is($file, undef);
 }
 
+subtest "empty file" => sub {
+    $grid->drop;
+    is( $grid->chunks->count, 0, "0 chunks exist" );
+
+    my $txt = "";
+
+    my $basicfh;
+    open( $basicfh, '<', \$txt );
+
+    my $fh = FileHandle->new;
+    $fh->fdopen( $basicfh, 'r' );
+    ok( $grid->insert( $fh, { filename => 'hello.txt' } ), "inserted" );
+
+    is( $grid->chunks->count, 0, "0 chunks still" );
+
+    $file = $grid->find_one;
+    is( $file->info->{filename}, 'hello.txt', "filename" );
+    is( $file->info->{length},   0,           "length" );
+    is( $file->slurp,            "",          "slurp" );
+};
+
+# no chunks for file with length asserts
+{
+    $grid->drop;
+
+    my $img = new IO::File("t/img.png", "r") or die $!;
+    $img->binmode;
+
+    ok( my $id = $grid->put($img), "inserted file" );
+
+    # delete chunks to simulate corruption
+    my $res = $grid->chunks->remove({"files_id" => $id});
+    ok( $res, "deleted chunks" );
+
+    like(
+        exception { $file = $grid->get($id)->slurp },
+        qr/GridFS file corrupt.*\Q$id\E/,
+        "invalid file throws error"
+    );
+
+}
+
+done_testing;
diff --git a/t/indexes.t b/t/indexes.t
new file mode 100644
index 0000000..b0b4fc0
--- /dev/null
+++ b/t/indexes.t
@@ -0,0 +1,195 @@
+#
+#  Copyright 2009-2013 MongoDB, Inc.
+#
+#  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.
+#
+
+use strict;
+use warnings;
+use Test::More 0.96;
+use Test::Deep qw/!blessed/;
+use Test::Fatal;
+use Test::Warn;
+
+use utf8;
+
+use MongoDB;
+
+use lib "t/lib";
+use MongoDBTest qw/build_client get_test_db server_version server_type/;
+
+my $conn           = build_client();
+my $testdb         = get_test_db($conn);
+my $server_version = server_version($conn);
+my $server_type    = server_type($conn);
+my $coll           = $testdb->get_collection("foo");
+
+# basic indexes
+subtest 'basic indexes' => sub {
+    $coll->drop;
+    my $res;
+
+    $coll->drop;
+    for ( my $i = 0; $i < 10; $i++ ) {
+        $coll->insert( { 'x' => $i, 'z' => 3, 'w' => 4 } );
+        $coll->insert( { 'x' => $i, 'y' => 2, 'z' => 3, 'w' => 4 } );
+    }
+
+    $coll->drop;
+    ok( !$coll->get_indexes, 'no indexes yet' );
+
+    my $indexes = Tie::IxHash->new( foo => 1, bar => 1, baz => 1 );
+    $res = $coll->ensure_index($indexes);
+    if ( $server_version >= v2.6.0 ) {
+        ok $res->{ok};
+    }
+    else {
+        ok( !defined $res );
+    }
+
+    my $err = $testdb->last_error;
+    is( $err->{ok},  1 );
+    is( $err->{err}, undef );
+
+    $indexes = Tie::IxHash->new( foo => 1, bar => 1 );
+    $res = $coll->ensure_index($indexes);
+
+    if ( $server_version >= v2.6.0 ) {
+        ok $res->{ok};
+    }
+    else {
+        ok( !defined $res );
+    }
+
+    $coll->insert( { foo => 1, bar => 1, baz => 1, boo => 1 } );
+    $coll->insert( { foo => 1, bar => 1, baz => 1, boo => 2 } );
+    is( $coll->count, 2 );
+
+    $res = $coll->ensure_index( { boo => 1 }, { unique => 1 } );
+
+    if ( $server_version >= v2.6.0 ) {
+        ok $res->{ok};
+    }
+    else {
+        ok( !defined $res );
+    }
+
+    eval { $coll->insert( { foo => 3, bar => 3, baz => 3, boo => 2 } ) };
+
+    is( $coll->count, 2, 'unique index' );
+
+    my @indexes = $coll->get_indexes;
+    is( scalar @indexes, 4, 'three custom indexes and the default _id_ index' );
+    my ($foobarbaz) = grep { $_->{name} eq 'foo_1_bar_1_baz_1' } @indexes;
+    is_deeply( [ sort keys %{ $foobarbaz->{key} } ], [ sort qw/foo bar baz/ ], );
+    my ($foobar) = grep { $_->{name} eq 'foo_1_bar_1' } @indexes;
+    is_deeply( [ sort keys %{ $foobar->{key} } ], [ sort qw/foo bar/ ], );
+
+    $coll->drop_index('foo_1_bar_1_baz_1');
+    @indexes = $coll->get_indexes;
+    is( scalar @indexes, 3 );
+    ok( ( !scalar grep { $_->{name} eq 'foo_1_bar_1_baz_1' } @indexes ),
+        "right index deleted" );
+
+    $coll->drop;
+    ok( !$coll->get_indexes, 'no indexes after dropping' );
+
+    # make sure this still works
+    $coll->ensure_index( { "foo" => 1 } );
+    @indexes = $coll->get_indexes;
+    is( scalar @indexes, 2, '1 custom index and the default _id_ index' );
+};
+
+# test ensure index with drop_dups
+subtest 'drop dups' => sub {
+    $coll->drop;
+
+    $coll->insert( { foo => 1, bar => 1, baz => 1, boo => 1 } );
+    $coll->insert( { foo => 1, bar => 1, baz => 1, boo => 2 } );
+    is( $coll->count, 2 );
+
+    eval { $coll->ensure_index( { foo => 1 }, { unique => 1 } ) };
+    like( $@, qr/E11000/, "got expected error creating unique index with dups" );
+
+    # prior to 2.7.5, drop_dups was respected
+    if ( $server_version < v2.7.5 ) {
+        my $res = $coll->ensure_index( { foo => 1 }, { unique => 1, drop_dups => 1 } );
+
+        if ( $server_version >= v2.6.0 ) {
+            ok $res->{ok};
+        }
+        else {
+            ok( !defined $res );
+        }
+    }
+
+};
+
+# test new form of ensure index
+subtest 'new form of ensure index' => sub {
+    $coll->drop;
+
+    my $res;
+    $res = $coll->ensure_index( { foo => 1, bar => -1, baz => 1 } );
+
+    if ( $server_version >= v2.6.0 ) {
+        ok $res->{ok};
+    }
+    else {
+        ok( !defined $res );
+    }
+
+    $res = $coll->ensure_index( [ foo => 1, bar => 1 ] );
+
+    if ( $server_version >= v2.6.0 ) {
+        ok $res->{ok};
+    }
+    else {
+        ok( !defined $res );
+    }
+
+    $coll->insert( { foo => 1, bar => 1, baz => 1, boo => 1 } );
+    $coll->insert( { foo => 1, bar => 1, baz => 1, boo => 2 } );
+    is( $coll->count, 2 );
+
+    # unique index
+    $coll->ensure_index( { boo => 1 }, { unique => 1 } );
+    eval { $coll->insert( { foo => 3, bar => 3, baz => 3, boo => 2 } ) };
+    is( $coll->count, 2, 'unique index' );
+};
+
+subtest '2d index with options' => sub {
+    $coll->drop;
+
+    $coll->ensure_index( { loc => '2d' }, { bits => 32, sparse => 1 } );
+
+    my ($index) = grep { $_->{name} eq 'loc_2d' } $coll->get_indexes;
+
+    ok( $index,           "created 2d index" );
+    ok( $index->{sparse}, "sparse option set on index" );
+    is( $index->{bits}, 32, "bits option set on index" );
+};
+
+subtest 'ensure index arbitrary options' => sub {
+    my $res;
+    $res = $coll->ensure_index( { wibble => 1 }, { notReallyAnOption => { foo => 1 } } );
+    my ($index) = grep { $_->{name} eq 'wibble_1' } $coll->get_indexes;
+    ok( $index, "created index" );
+    cmp_deeply(
+        $index->{notReallyAnOption},
+        { foo => 1 },
+        "arbitrary option set on index"
+    );
+};
+
+done_testing;
diff --git a/t/lib/MongoDBTest.pm b/t/lib/MongoDBTest.pm
index 7e862f7..ef16579 100644
--- a/t/lib/MongoDBTest.pm
+++ b/t/lib/MongoDBTest.pm
@@ -26,7 +26,10 @@ use MongoDB;
 use Test::More;
 use version;
 
-our @EXPORT_OK = ( 'build_client', 'get_test_db', 'server_version', 'server_type' );
+our @EXPORT_OK = qw(
+  build_client get_test_db server_version server_type clear_testdbs
+);
+
 my @testdbs;
 
 # abstract building a connection
@@ -95,8 +98,11 @@ sub server_type {
     else {
         $server_type = 'Unknown';
     }
+    return $server_type;
 }
 
+sub clear_testdbs { @testdbs = () }
+
 # cleanup test dbs
 END {
     for my $db (@testdbs) {
diff --git a/t/threads/basic.t b/t/threads/basic.t
index 0c329cf..8220bec 100644
--- a/t/threads/basic.t
+++ b/t/threads/basic.t
@@ -17,14 +17,14 @@
 
 use strict;
 use warnings;
-use Test::More;
 use Config;
+use if $Config{usethreads}, 'threads';
+use Test::More;
 
 BEGIN { plan skip_all => 'requires threads' unless $Config{usethreads} }
 
 use MongoDB;
 use Try::Tiny;
-use threads;
 
 use lib "t/lib";
 use MongoDBTest qw/build_client get_test_db/;
diff --git a/t/threads/bson.t b/t/threads/bson.t
new file mode 100644
index 0000000..c88b9f1
--- /dev/null
+++ b/t/threads/bson.t
@@ -0,0 +1,89 @@
+#
+#  Copyright 2015
+#
+#  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.
+#
+
+use strict;
+use warnings;
+use Config;
+use if $Config{usethreads}, 'threads';
+use Test::More;
+
+BEGIN {
+    plan skip_all => 'requires threads' unless $Config{usethreads};
+    plan skip_all => 'needs Perl 5.10.1' unless $] ge '5.010001';
+}
+
+use MongoDB;
+use Try::Tiny;
+use threads::shared;
+
+use lib "t/lib";
+
+my $class = "MongoDB::BSON";
+
+require_ok($class);
+
+my $var       = { a => 0.1 +0 };
+my $clone     = shared_clone $var;
+my $enc_var   = MongoDB::BSON::encode_bson($var);
+my $enc_clone = MongoDB::BSON::encode_bson($clone);
+
+_bson_is( $enc_var, $enc_clone,
+    "encoded top level hash and encoded top level shared hash" );
+_bson_is(
+    MongoDB::BSON::encode_bson( { data => $var } ),
+    MongoDB::BSON::encode_bson( { data => $clone } ),
+    "encoded hash and encoded shared hash"
+);
+_bson_is(
+    MongoDB::BSON::encode_bson( { data => $var->{a} } ),
+    MongoDB::BSON::encode_bson( { data => $clone->{a} } ),
+    "encoded double and encoded shared clone of double"
+);
+
+threads->create(
+    sub {
+        _bson_is(
+            MongoDB::BSON::encode_bson($var),
+            MongoDB::BSON::encode_bson($clone),
+            "(in thread) encoded top level hash and encoded top level shared hash"
+        );
+        _bson_is(
+            MongoDB::BSON::encode_bson( { data => $var } ),
+            MongoDB::BSON::encode_bson( { data => $clone } ),
+            "(in thread) encoded hash and encoded shared hash"
+        );
+        _bson_is(
+            MongoDB::BSON::encode_bson( { data => $var->{a} } ),
+            MongoDB::BSON::encode_bson( { data => $clone->{a} } ),
+            "(in thread) encoded double and encoded shared clone of double"
+        );
+    }
+)->join;
+
+sub _bson_is {
+    my ( $got, $exp, $label ) = @_;
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+    ok( $got eq $exp, $label )
+      or diag "     Got:", _hexdump($got), "\nExpected:", _hexdump($exp), "\n";
+}
+
+sub _hexdump {
+    my $str = shift;
+    $str =~ s{([^[:graph:]])}{sprintf("\\x{%02x}",ord($1))}ge;
+    return $str;
+}
+
+done_testing();
diff --git a/t/threads/cursor.t b/t/threads/cursor.t
index 59eab64..8e4f9fa 100644
--- a/t/threads/cursor.t
+++ b/t/threads/cursor.t
@@ -17,13 +17,14 @@
 
 use strict;
 use warnings;
-use Test::More;
 use Config;
+use if $Config{usethreads}, 'threads';
+use Test::More;
+
 BEGIN { plan skip_all => 'requires threads' unless $Config{usethreads} }
 
 use MongoDB;
 use Try::Tiny;
-use threads;
 
 use lib "t/lib";
 use MongoDBTest qw/build_client get_test_db/;
diff --git a/t/threads/oid.t b/t/threads/oid.t
index 720c718..de92640 100644
--- a/t/threads/oid.t
+++ b/t/threads/oid.t
@@ -16,15 +16,15 @@
 
 use strict;
 use warnings;
-use Test::More;
 use Config;
+use if $Config{usethreads}, 'threads';
+use Test::More;
+
 BEGIN { plan skip_all => 'requires threads' unless $Config{usethreads} }
 
 use MongoDB;
 use MongoDB::OID;
 
-use threads;
-
 my @threads = map {
     threads->create(sub {
         [map { MongoDB::OID->build_value } 0 .. 3]
diff --git a/t/types.t b/t/types.t
index 3865a21..6d3a201 100644
--- a/t/types.t
+++ b/t/types.t
@@ -275,28 +275,17 @@ SKIP: {
     is($x->{'ts'}->inc, $t->inc);
 }
 
-# use_boolean
+# boolean objects
 {
     $coll->drop;
 
-    $MongoDB::BSON::use_boolean = 0;
-
     $coll->insert({"x" => boolean::true, "y" => boolean::false});
     my $x = $coll->find_one;
 
-    isa_ok($x->{x}, 'SCALAR');
-    isa_ok($x->{y}, 'SCALAR');
-    is($x->{x}, 1);
-    is($x->{y}, 0);
-
-    $MongoDB::BSON::use_boolean = 1;
-
-    $x = $coll->find_one;
-
-    isa_ok($x->{x}, 'boolean');
-    isa_ok($x->{y}, 'boolean');
-    is($x->{x}, boolean::true);
-    is($x->{y}, boolean::false);
+    is( ref $x->{x}, 'boolean', "roundtrip boolean field x");
+    is( ref $x->{y}, 'boolean', "roundtrip boolean field y");
+    ok( $x->{x}, "x is true");
+    ok( ! $x->{y}, "y is false");
 }
 
 # unrecognized obj
diff --git a/xs/Cursor.xs b/xs/Cursor.xs
index 6b58155..fe600bf 100644
--- a/xs/Cursor.xs
+++ b/xs/Cursor.xs
@@ -160,7 +160,7 @@ static int has_next(SV *self, mongo_cursor *cursor) {
   if(mongo_link_say(link, &buf) == -1) {
     SvREFCNT_dec(link);
     Safefree(buf.start);
-    die("can't get db response, not connected");
+    die("can't get db response, not connected (sending OP_GET_MORE)");
     return 0;
   }
 
@@ -222,9 +222,10 @@ _init (self, ...)
         SV *self
     PREINIT:
         mongo_cursor *cursor;
+        SV *sv;
     CODE:
         Newxz(cursor, 1, mongo_cursor);
-        SV *sv = ST(1);
+        sv = ST(1);
 
         /* initialize a cursor ID manually if we are getting constructed
            from an aggregation result */
@@ -273,6 +274,11 @@ next (self)
         AV *agg_batch;
         SV *agg_doc;
         SV *ns;
+        char *dt_type;
+        int inflate_dbrefs;
+        int inflate_regexps;
+        int agg_batch_size;
+        char *fullname;
     CODE:
         cursor = get_cursor(self);
         if (has_next(self, cursor)) {
@@ -283,11 +289,11 @@ next (self)
           agg_batch_size_sv   = perl_mongo_call_reader( self, "_agg_batch_size" );
           ns                  = perl_mongo_call_reader( self, "_ns" );
 
-          char *dt_type       = SvOK( dt_type_sv ) ? SvPV_nolen( dt_type_sv ) : NULL;
-          int inflate_dbrefs  = SvIV( inflate_dbrefs_sv );
-          int inflate_regexps = SvIV( inflate_regexps_sv );
-          int agg_batch_size  = SvIV( agg_batch_size_sv );
-          char *fullname     = SvPV_nolen(ns);
+          dt_type             = SvOK( dt_type_sv ) ? SvPV_nolen( dt_type_sv ) : NULL;
+          inflate_dbrefs      = SvIV( inflate_dbrefs_sv );
+          inflate_regexps     = SvIV( inflate_regexps_sv );
+          agg_batch_size      = SvIV( agg_batch_size_sv );
+          fullname            = SvPV_nolen(ns);
 
           if ( agg_batch_size > 0 ) { 
             agg_batch = (AV *)SvRV( perl_mongo_call_reader( self, "_agg_first_batch" ) );
diff --git a/xs/Mongo.xs b/xs/Mongo.xs
index 84de85d..58aff31 100644
--- a/xs/Mongo.xs
+++ b/xs/Mongo.xs
@@ -35,7 +35,6 @@ BOOT:
         gv_fetchpv("MongoDB::BSON::looks_like_number",  GV_ADDMULTI, SVt_IV);
         gv_fetchpv("MongoDB::BSON::char",  GV_ADDMULTI, SVt_IV);
         gv_fetchpv("MongoDB::BSON::utf8_flag_on",  GV_ADDMULTI, SVt_IV);
-        gv_fetchpv("MongoDB::BSON::use_boolean",  GV_ADDMULTI, SVt_IV);
         gv_fetchpv("MongoDB::BSON::use_binary",  GV_ADDMULTI, SVt_IV);
         perl_mongo_init();
 
diff --git a/xs/MongoClient.xs b/xs/MongoClient.xs
index 7d3b9f9..12a95b2 100644
--- a/xs/MongoClient.xs
+++ b/xs/MongoClient.xs
@@ -254,7 +254,7 @@ send(self, str)
      CODE:
          RETVAL = mongo_link_say(self, &buf);
          if (RETVAL == -1) {
-           die("can't get db response, not connected");
+           die("can't get db response, not connected (during send)");
          }
      OUTPUT:
          RETVAL
diff --git a/xt/release/test-version.t b/xt/author/test-version.t
similarity index 54%
rename from xt/release/test-version.t
rename to xt/author/test-version.t
index b7a0f17..204eaf8 100644
--- a/xt/release/test-version.t
+++ b/xt/author/test-version.t
@@ -2,14 +2,16 @@ use strict;
 use warnings;
 use Test::More;
 
-# generated by Dist::Zilla::Plugin::Test::Version 0.002004
-BEGIN { eval "use Test::Version; 1;" or die $@; }
+# generated by Dist::Zilla::Plugin::Test::Version 1.05
+use Test::Version;
 
-my @imports = ( 'version_all_ok' );
+my @imports = qw( version_all_ok );
 
 my $params = {
-    is_strict   => 0,
-    has_version => 1,
+    is_strict      => 0,
+    has_version    => 1,
+    multiple       => 0,
+
 };
 
 push @imports, $params
diff --git a/xt/release/check-jira-in-changes.t b/xt/release/check-jira-in-changes.t
index 12b80e0..df53423 100644
--- a/xt/release/check-jira-in-changes.t
+++ b/xt/release/check-jira-in-changes.t
@@ -8,7 +8,7 @@ use warnings;
 use Test::More tests => 1;
 
 my @commits = split /\n/, <<'EOC';
-eb166da PERL-406 Allow count methods to work with query hints
+343512c PERL-555 Fixes serialization of thread-shared variables
 
 EOC
 
@@ -24,7 +24,7 @@ for my $commit ( @commits ) {
 
 # grab Changes lines from new version to next un-indented line
 open my $fh, "<:encoding(UTF-8)", "Changes";
-my @content = grep { /^v0.705.0.0(?:\s+|$)/ ... /^\S/ } <$fh>;
+my @content = grep { /^v0.708.4.0(?:\s+|$)/ ... /^\S/ } <$fh>;
 
 # drop the version line
 shift @content;

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-perl/packages/libmongodb-perl.git



More information about the Pkg-perl-cvs-commits mailing list