From 951f15990194d637e013bc4e70ed7089a1a62bc4 Mon Sep 17 00:00:00 2001
From: Daniel Swarbrick <daniel.swarbrick@gmail.com>
Date: Thu, 10 May 2012 11:03:04 +0200
Subject: [PATCH] update mongo-c-driver to 0.5.2

---
 .../event_handlers/mod_cdr_mongodb/Makefile   |   6 +-
 .../mod_cdr_mongodb/driver/HISTORY.md         |  30 +
 .../mod_cdr_mongodb/driver/README.md          |   4 +-
 .../mod_cdr_mongodb/driver/SConstruct         | 178 ------
 .../mod_cdr_mongodb/driver/src/bson.c         | 308 ++++++----
 .../mod_cdr_mongodb/driver/src/bson.h         | 241 +++++---
 .../mod_cdr_mongodb/driver/src/encoding.c     |   2 +-
 .../mod_cdr_mongodb/driver/src/encoding.h     |   6 +-
 .../mod_cdr_mongodb/driver/src/env.h          |  39 ++
 .../mod_cdr_mongodb/driver/src/env_posix.c    | 165 +++++
 .../mod_cdr_mongodb/driver/src/env_standard.c | 168 +++++
 .../mod_cdr_mongodb/driver/src/env_win32.c    | 183 ++++++
 .../mod_cdr_mongodb/driver/src/gridfs.c       | 115 ++--
 .../mod_cdr_mongodb/driver/src/gridfs.h       |  64 +-
 .../mod_cdr_mongodb/driver/src/md5.c          |   6 +-
 .../mod_cdr_mongodb/driver/src/md5.h          |  19 +-
 .../mod_cdr_mongodb/driver/src/mongo.c        | 576 +++++++++++++-----
 .../mod_cdr_mongodb/driver/src/mongo.h        | 191 ++++--
 .../mod_cdr_mongodb/driver/src/net.c          |  98 ---
 .../mod_cdr_mongodb/driver/src/net.h          |  57 --
 .../mod_cdr_mongodb/driver/src/numbers.c      |   2 +-
 .../mod_cdr_mongodb/driver/src/platform.h     |  94 ---
 .../driver/src/platform/linux/net.c           | 183 ------
 .../driver/src/platform/linux/net.h           |  51 --
 24 files changed, 1598 insertions(+), 1188 deletions(-)
 delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/SConstruct
 create mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/env.h
 create mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c
 create mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_standard.c
 create mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_win32.c
 delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.c
 delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.h
 delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform.h
 delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.c
 delete mode 100644 src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.h

diff --git a/src/mod/event_handlers/mod_cdr_mongodb/Makefile b/src/mod/event_handlers/mod_cdr_mongodb/Makefile
index b9e04b983d..6a412a0f66 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/Makefile
+++ b/src/mod/event_handlers/mod_cdr_mongodb/Makefile
@@ -2,8 +2,8 @@ include ../../../../build/modmake.rules
 
 MONGODB_DRIVER=./driver/src
 LOCAL_CFLAGS=-I$(MONGODB_DRIVER)
-LOCAL_OBJS=$(MONGODB_DRIVER)/md5.o \
-	   $(MONGODB_DRIVER)/mongo.o $(MONGODB_DRIVER)/net.o \
-	   $(MONGODB_DRIVER)/bson.o $(MONGODB_DRIVER)/numbers.o $(MONGODB_DRIVER)/encoding.o \
+LOCAL_OBJS=$(MONGODB_DRIVER)/encoding.o $(MONGODB_DRIVER)/env_posix.o \
+	   $(MONGODB_DRIVER)/bson.o $(MONGODB_DRIVER)/md5.o \
+	   $(MONGODB_DRIVER)/mongo.o $(MONGODB_DRIVER)/numbers.o
 
 local_depend: $(LOCAL_OBJS)
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/HISTORY.md b/src/mod/event_handlers/mod_cdr_mongodb/driver/HISTORY.md
index f3f0fab21d..1659192909 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/HISTORY.md
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/HISTORY.md
@@ -1,5 +1,35 @@
 # MongoDB C Driver History
 
+## 0.5.2
+2012-5-4
+
+* Validate collection and database names on insert.
+* Validate insert limits using max BSON size.
+* Support getaddrinfo and SO_RCVTIMEO and SO_SNDTIMEO on Windows.
+* Store errno/WSAGetLastError() on errors.
+* Various bug fixes and refactorings.
+* Update error reporting docs.
+
+## 0.5.1
+
+* Env for POSIX, WIN32, and standard C.
+* Various bug fixes.
+
+## 0.5
+2012-3-31
+
+* Separate cursor-specific errors into their own enum: mongo_cursor_error_t.
+* Catch $err return on bad queries and store the result in conn->getlasterrorcode
+  and conn->getlasterrstr.
+* On queries that return $err, set cursor->err to MONGO_CURSOR_QUERY_FAIL.
+* When passing bad BSON to a cursor object, set cursor->err to MONGO_CURSOR_BSON_ERROR,
+  and store the specific BSON error on the conn->err field.
+* Remove bson_copy_basic().
+* bson_copy() will copy finished bson objects only.
+* bson_copy() returns BSON_OK on success and BSON_ERROR on failure.
+* Added a Makefile for easy compile and install on Linux and OS X.
+* Replica set connect fixes.
+
 ## 0.4
 
 THIS RELEASE INCLUDES NUMEROUS BACKWARD-BREAKING CHANGES.
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/README.md b/src/mod/event_handlers/mod_cdr_mongodb/driver/README.md
index 1afe39e69c..d8c7526683 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/README.md
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/README.md
@@ -12,9 +12,9 @@ Until the 1.0 release, this driver should be considered alpha. Keep in mind that
 # Building
 
 First check out the version you want to build. *Always build from a particular tag, since HEAD may be
-a work in progress.* For example, to build version 0.4, run:
+a work in progress.* For example, to build version 0.5.2, run:
 
-    git checkout v0.4
+    git checkout v0.5.2
 
 You can then build the driver with scons:
 
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/SConstruct b/src/mod/event_handlers/mod_cdr_mongodb/driver/SConstruct
deleted file mode 100644
index d3be2d89a6..0000000000
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/SConstruct
+++ /dev/null
@@ -1,178 +0,0 @@
-# -*- mode: python; -*-
-
-VERSION = "0.4"
-
-# --- options ----
-AddOption('--test-server',
-          dest='test_server',
-          default='127.0.0.1',
-          type='string',
-          nargs=1,
-          action='store',
-          help='IP address of server to use for testing')
-
-AddOption('--seed-start-port',
-          dest='seed_start_port',
-          default=30000,
-          type='int',
-          nargs=1,
-          action='store',
-          help='IP address of server to use for testing')
-
-AddOption('--c99',
-          dest='use_c99',
-          default=False,
-          action='store_true',
-          help='Compile with c99 (recommended for gcc)')
-
-AddOption('--d',
-          dest='optimize',
-          default=True,
-          action='store_false',
-          help='disable optimizations')
-
-AddOption('--use-platform',
-          dest='compile_platform',
-          default='GENERIC',
-          type='string',
-          nargs=1,
-          action='store',
-          help='Compile for a specific platform to take advantage '
-               ' of particular system features. For the moment, this include timeouts only.'
-               ' Current options include LINUX, '
-               ' GENERIC, and CUSTOM. If you specific CUSTOM, you must place a'
-               ' system-specific implementation of net.h and net.c in src/platform/custom/')
-
-import os, sys
-
-env = Environment( ENV=os.environ )
-
-#  ---- Docs ----
-def build_docs(env, target, source):
-    buildscript_path = os.path.join(os.path.abspath("docs"))
-    sys.path.insert(0, buildscript_path)
-    import buildscripts
-    from buildscripts import docs
-    docs.main()
-
-env.Alias("docs", [], [build_docs])
-env.AlwaysBuild("docs")
-
-# ---- Platforms ----
-PLATFORM_TEST_DIR = None
-if "LINUX" == GetOption('compile_platform'):
-    env.Append( CPPFLAGS=" -D_MONGO_USE_LINUX_SYSTEM" )
-    NET_LIB = "src/platform/linux/net.c"
-    PLATFORM_TEST_DIR = "test/platform/linux/"
-    PLATFORM_TESTS = [ "timeouts" ]
-elif "CUSTOM" == GetOption('compile_platform'):
-    env.Append( CPPFLAGS=" -D_MONGO_USE_CUSTOM_SYSTEM" )
-    NET_LIB = "src/platform/custom/net.c"
-else:
-    NET_LIB = "src/net.c"
-
-# ---- Libraries ----
-if os.sys.platform in ["darwin", "linux2"]:
-    env.Append( CPPFLAGS=" -pedantic -Wall -ggdb -DMONGO_HAVE_STDINT" )
-    env.Append( CPPPATH=["/opt/local/include/"] )
-    env.Append( LIBPATH=["/opt/local/lib/"] )
-
-    if GetOption('use_c99'):
-        env.Append( CFLAGS=" -std=c99 " )
-        env.Append( CXXDEFINES="MONGO_HAVE_STDINT" )
-    else:
-        env.Append( CFLAGS=" -ansi " )
-
-    if GetOption('optimize'):
-        env.Append( CPPFLAGS=" -O3 " )
-        # -O3 benchmarks *significantly* faster than -O2 when disabling networking
-elif 'win32' == os.sys.platform:
-    env.Append( LIBS='ws2_32' )
-
-#we shouldn't need these options in c99 mode
-if not GetOption('use_c99'):
-    conf = Configure(env)
-
-    if not conf.CheckType('int64_t'):
-        if conf.CheckType('int64_t', '#include <stdint.h>\n'):
-            conf.env.Append( CPPDEFINES="MONGO_HAVE_STDINT" )
-        elif conf.CheckType('int64_t', '#include <unistd.h>\n'):
-            conf.env.Append( CPPDEFINES="MONGO_HAVE_UNISTD" )
-        elif conf.CheckType('__int64'):
-            conf.env.Append( CPPDEFINES="MONGO_USE__INT64" )
-        elif conf.CheckType('long long int'):
-            conf.env.Append( CPPDEFINES="MONGO_USE_LONG_LONG_INT" )
-        else:
-            print "*** what is your 64 bit int type? ****"
-            Exit(1)
-
-    env = conf.Finish()
-
-have_libjson = False
-conf = Configure(env)
-if conf.CheckLib('json'):
-    have_libjson = True
-env = conf.Finish()
-
-if sys.byteorder == 'big':
-    env.Append( CPPDEFINES="MONGO_BIG_ENDIAN" )
-
-env.Append( CPPPATH=["src/"] )
-
-coreFiles = ["src/md5.c" ]
-mFiles = [ "src/mongo.c", NET_LIB, "src/gridfs.c"]
-bFiles = [ "src/bson.c", "src/numbers.c", "src/encoding.c"]
-mLibFiles = coreFiles + mFiles + bFiles
-bLibFiles = coreFiles + bFiles
-m = env.Library( "mongoc" ,  mLibFiles )
-b = env.Library( "bson" , bLibFiles  )
-env.Default( env.Alias( "lib" , [ m[0] , b[0] ] ) )
-
-if os.sys.platform == "linux2":
-    env.Append( SHLINKFLAGS="-shared -Wl,-soname,libmongoc.so." + VERSION )
-    env.Append( SHLINKFLAGS = "-shared -Wl,-soname,libbson.so." + VERSION )
-
-dynm = env.SharedLibrary( "mongoc" , mLibFiles )
-dynb = env.SharedLibrary( "bson" , bLibFiles )
-env.Default( env.Alias( "sharedlib" , [ dynm[0] , dynb[0] ] ) )
-
-
-
-# ---- Benchmarking ----
-benchmarkEnv = env.Clone()
-benchmarkEnv.Append( CPPDEFINES=[('TEST_SERVER', r'\"%s\"'%GetOption('test_server')),
-('SEED_START_PORT', r'%d'%GetOption('seed_start_port'))] )
-benchmarkEnv.Append( LIBS=[m, b] )
-benchmarkEnv.Prepend( LIBPATH=["."] )
-benchmarkEnv.Program( "benchmark" ,  [ "test/benchmark.c"] )
-
-# ---- Tests ----
-testEnv = benchmarkEnv.Clone()
-testCoreFiles = [ ]
-
-def run_tests( root, tests ):
-    for name in tests:
-        filename = "%s/%s.c" % (root, name)
-        exe = "test_" + name
-        test = testEnv.Program( exe , testCoreFiles + [filename]  )
-        test_alias = testEnv.Alias('test', [test], test[0].abspath + ' 2> ' + os.path.devnull)
-        AlwaysBuild(test_alias)
-
-tests = Split("sizes resize endian_swap bson bson_subobject simple update errors "
-"count_delete auth gridfs validate examples helpers oid functions cursors replica_set")
-
-# Run standard tests
-run_tests("test", tests)
-
-# Run platform tests
-if not PLATFORM_TEST_DIR is None:
-    run_tests( PLATFORM_TEST_DIR, PLATFORM_TESTS )
-
-if have_libjson:
-    tests.append('json')
-    testEnv.Append( LIBS=["json"] )
-
-# special case for cpptest
-test = testEnv.Program( 'test_cpp' , testCoreFiles + ['test/cpptest.cpp']  )
-test_alias = testEnv.Alias('test', [test], test[0].abspath + ' 2> '+ os.path.devnull)
-AlwaysBuild(test_alias)
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.c
index 349f42284c..26d17d8696 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.c
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.c
@@ -33,7 +33,11 @@ static const int zero = 0;
 void *( *bson_malloc_func )( size_t ) = malloc;
 void *( *bson_realloc_func )( void *, size_t ) = realloc;
 void  ( *bson_free )( void * ) = free;
+#ifdef R_SAFETY_NET
+bson_printf_func bson_printf;
+#else
 bson_printf_func bson_printf = printf;
+#endif
 bson_fprintf_func bson_fprintf = fprintf;
 bson_sprintf_func bson_sprintf = sprintf;
 
@@ -48,33 +52,32 @@ static int ( *oid_inc_func )( void )  = NULL;
    READING
    ------------------------------ */
 
-bson *bson_empty( bson *obj ) {
+MONGO_EXPORT bson* bson_create() {
+	return (bson*)bson_malloc(sizeof(bson));
+}
+
+MONGO_EXPORT void bson_dispose(bson* b) {
+	bson_free(b);
+}
+
+MONGO_EXPORT bson *bson_empty( bson *obj ) {
     static char *data = "\005\0\0\0\0";
     bson_init_data( obj, data );
     obj->finished = 1;
     obj->err = 0;
+    obj->errstr = NULL;
     obj->stackPos = 0;
     return obj;
 }
 
-void bson_copy_basic( bson *out, const bson *in ) {
-    if ( !out ) return;
+MONGO_EXPORT int bson_copy( bson *out, const bson *in ) {
+    if ( !out ) return BSON_ERROR;
+    if ( !in->finished ) return BSON_ERROR;
     bson_init_size( out, bson_size( in ) );
     memcpy( out->data, in->data, bson_size( in ) );
-}
+    out->finished = 1;
 
-void bson_copy( bson *out, const bson *in ) {
-    int i;
-
-    if ( !out ) return;
-    bson_copy_basic( out, in );
-    out->cur = out->data + ( in->cur - in->data );
-    out->dataSize = in->dataSize;
-    out->finished = in->finished;
-    out->stackPos = in->stackPos;
-    out->err = in->err;
-    for( i=0; i<out->stackPos; i++ )
-        out->stack[i] = in->stack[i];
+    return BSON_OK;
 }
 
 int bson_init_data( bson *b, char *data ) {
@@ -82,6 +85,12 @@ int bson_init_data( bson *b, char *data ) {
     return BSON_OK;
 }
 
+int bson_init_finished_data( bson *b, char *data ) {
+    bson_init_data( b, data );
+    b->finished = 1;
+    return BSON_OK;
+}
+
 static void _bson_reset( bson *b ) {
     b->finished = 0;
     b->stackPos = 0;
@@ -89,7 +98,7 @@ static void _bson_reset( bson *b ) {
     b->errstr = NULL;
 }
 
-int bson_size( const bson *b ) {
+MONGO_EXPORT int bson_size( const bson *b ) {
     int i;
     if ( ! b || ! b->data )
         return 0;
@@ -97,7 +106,12 @@ int bson_size( const bson *b ) {
     return i;
 }
 
-const char *bson_data( bson *b ) {
+MONGO_EXPORT int bson_buffer_size( const bson *b ) {
+    return (b->cur - b->data + 1);
+}
+
+
+MONGO_EXPORT const char *bson_data( const bson *b ) {
     return (const char *)b->data;
 }
 
@@ -146,14 +160,14 @@ static char hexbyte( char hex ) {
     }
 }
 
-void bson_oid_from_string( bson_oid_t *oid, const char *str ) {
+MONGO_EXPORT void bson_oid_from_string( bson_oid_t *oid, const char *str ) {
     int i;
     for ( i=0; i<12; i++ ) {
         oid->bytes[i] = ( hexbyte( str[2*i] ) << 4 ) | hexbyte( str[2*i + 1] );
     }
 }
 
-void bson_oid_to_string( const bson_oid_t *oid, char *str ) {
+MONGO_EXPORT void bson_oid_to_string( const bson_oid_t *oid, char *str ) {
     static const char hex[16] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
     int i;
     for ( i=0; i<12; i++ ) {
@@ -163,15 +177,15 @@ void bson_oid_to_string( const bson_oid_t *oid, char *str ) {
     str[24] = '\0';
 }
 
-void bson_set_oid_fuzz( int ( *func )( void ) ) {
+MONGO_EXPORT void bson_set_oid_fuzz( int ( *func )( void ) ) {
     oid_fuzz_func = func;
 }
 
-void bson_set_oid_inc( int ( *func )( void ) ) {
+MONGO_EXPORT void bson_set_oid_inc( int ( *func )( void ) ) {
     oid_inc_func = func;
 }
 
-void bson_oid_gen( bson_oid_t *oid ) {
+MONGO_EXPORT void bson_oid_gen( bson_oid_t *oid ) {
     static int incr = 0;
     static int fuzz = 0;
     int i;
@@ -196,18 +210,18 @@ void bson_oid_gen( bson_oid_t *oid ) {
     bson_big_endian32( &oid->ints[2], &i );
 }
 
-time_t bson_oid_generated_time( bson_oid_t *oid ) {
+MONGO_EXPORT time_t bson_oid_generated_time( bson_oid_t *oid ) {
     time_t out;
     bson_big_endian32( &out, &oid->ints[0] );
 
     return out;
 }
 
-void bson_print( bson *b ) {
+MONGO_EXPORT void bson_print( const bson *b ) {
     bson_print_raw( b->data , 0 );
 }
 
-void bson_print_raw( const char *data , int depth ) {
+MONGO_EXPORT void bson_print_raw( const char *data , int depth ) {
     bson_iterator i;
     const char *key;
     int temp;
@@ -223,69 +237,69 @@ void bson_print_raw( const char *data , int depth ) {
         key = bson_iterator_key( &i );
 
         for ( temp=0; temp<=depth; temp++ )
-            printf( "\t" );
+            bson_printf( "\t" );
         bson_printf( "%s : %d \t " , key , t );
         switch ( t ) {
         case BSON_DOUBLE:
-            printf( "%f" , bson_iterator_double( &i ) );
+            bson_printf( "%f" , bson_iterator_double( &i ) );
             break;
         case BSON_STRING:
-            printf( "%s" , bson_iterator_string( &i ) );
+            bson_printf( "%s" , bson_iterator_string( &i ) );
             break;
         case BSON_SYMBOL:
-            printf( "SYMBOL: %s" , bson_iterator_string( &i ) );
+            bson_printf( "SYMBOL: %s" , bson_iterator_string( &i ) );
             break;
         case BSON_OID:
             bson_oid_to_string( bson_iterator_oid( &i ), oidhex );
-            printf( "%s" , oidhex );
+            bson_printf( "%s" , oidhex );
             break;
         case BSON_BOOL:
-            printf( "%s" , bson_iterator_bool( &i ) ? "true" : "false" );
+            bson_printf( "%s" , bson_iterator_bool( &i ) ? "true" : "false" );
             break;
         case BSON_DATE:
-            printf( "%ld" , ( long int )bson_iterator_date( &i ) );
+            bson_printf( "%ld" , ( long int )bson_iterator_date( &i ) );
             break;
         case BSON_BINDATA:
-            printf( "BSON_BINDATA" );
+            bson_printf( "BSON_BINDATA" );
             break;
         case BSON_UNDEFINED:
-            printf( "BSON_UNDEFINED" );
+            bson_printf( "BSON_UNDEFINED" );
             break;
         case BSON_NULL:
-            printf( "BSON_NULL" );
+            bson_printf( "BSON_NULL" );
             break;
         case BSON_REGEX:
-            printf( "BSON_REGEX: %s", bson_iterator_regex( &i ) );
+            bson_printf( "BSON_REGEX: %s", bson_iterator_regex( &i ) );
             break;
         case BSON_CODE:
-            printf( "BSON_CODE: %s", bson_iterator_code( &i ) );
+            bson_printf( "BSON_CODE: %s", bson_iterator_code( &i ) );
             break;
         case BSON_CODEWSCOPE:
-            printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) );
+            bson_printf( "BSON_CODE_W_SCOPE: %s", bson_iterator_code( &i ) );
             bson_init( &scope );
             bson_iterator_code_scope( &i, &scope );
-            printf( "\n\t SCOPE: " );
+            bson_printf( "\n\t SCOPE: " );
             bson_print( &scope );
             break;
         case BSON_INT:
-            printf( "%d" , bson_iterator_int( &i ) );
+            bson_printf( "%d" , bson_iterator_int( &i ) );
             break;
         case BSON_LONG:
-            printf( "%lld" , ( long long int )bson_iterator_long( &i ) );
+            bson_printf( "%lld" , ( uint64_t )bson_iterator_long( &i ) );
             break;
         case BSON_TIMESTAMP:
             ts = bson_iterator_timestamp( &i );
-            printf( "i: %d, t: %d", ts.i, ts.t );
+            bson_printf( "i: %d, t: %d", ts.i, ts.t );
             break;
         case BSON_OBJECT:
         case BSON_ARRAY:
-            printf( "\n" );
+            bson_printf( "\n" );
             bson_print_raw( bson_iterator_value( &i ) , depth + 1 );
             break;
         default:
             bson_errprintf( "can't print type : %d\n" , t );
         }
-        printf( "\n" );
+        bson_printf( "\n" );
     }
 }
 
@@ -293,17 +307,25 @@ void bson_print_raw( const char *data , int depth ) {
    ITERATOR
    ------------------------------ */
 
-void bson_iterator_init( bson_iterator *i, const bson *b ) {
+MONGO_EXPORT bson_iterator* bson_iterator_create() {
+    return (bson_iterator*)malloc(sizeof(bson_iterator*));
+}
+
+MONGO_EXPORT void bson_iterator_dispose(bson_iterator* i) {
+    free(i);
+}
+
+MONGO_EXPORT void bson_iterator_init( bson_iterator *i, const bson *b ) {
     i->cur = b->data + 4;
     i->first = 1;
 }
 
-void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ) {
+MONGO_EXPORT void bson_iterator_from_buffer( bson_iterator *i, const char *buffer ) {
     i->cur = buffer + 4;
     i->first = 1;
 }
 
-bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) {
+MONGO_EXPORT bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) {
     bson_iterator_init( it, (bson *)obj );
     while( bson_iterator_next( it ) ) {
         if ( strcmp( name, bson_iterator_key( it ) ) == 0 )
@@ -312,11 +334,11 @@ bson_type bson_find( bson_iterator *it, const bson *obj, const char *name ) {
     return bson_iterator_type( it );
 }
 
-bson_bool_t bson_iterator_more( const bson_iterator *i ) {
+MONGO_EXPORT bson_bool_t bson_iterator_more( const bson_iterator *i ) {
     return *( i->cur );
 }
 
-bson_type bson_iterator_next( bson_iterator *i ) {
+MONGO_EXPORT bson_type bson_iterator_next( bson_iterator *i ) {
     int ds;
 
     if ( i->first ) {
@@ -384,15 +406,15 @@ bson_type bson_iterator_next( bson_iterator *i ) {
     return ( bson_type )( *i->cur );
 }
 
-bson_type bson_iterator_type( const bson_iterator *i ) {
+MONGO_EXPORT bson_type bson_iterator_type( const bson_iterator *i ) {
     return ( bson_type )i->cur[0];
 }
 
-const char *bson_iterator_key( const bson_iterator *i ) {
+MONGO_EXPORT const char *bson_iterator_key( const bson_iterator *i ) {
     return i->cur + 1;
 }
 
-const char *bson_iterator_value( const bson_iterator *i ) {
+MONGO_EXPORT const char *bson_iterator_value( const bson_iterator *i ) {
     const char *t = i->cur + 1;
     t += strlen( t ) + 1;
     return t;
@@ -422,11 +444,11 @@ bson_bool_t bson_iterator_bool_raw( const bson_iterator *i ) {
     return bson_iterator_value( i )[0];
 }
 
-bson_oid_t *bson_iterator_oid( const bson_iterator *i ) {
+MONGO_EXPORT bson_oid_t *bson_iterator_oid( const bson_iterator *i ) {
     return ( bson_oid_t * )bson_iterator_value( i );
 }
 
-int bson_iterator_int( const bson_iterator *i ) {
+MONGO_EXPORT int bson_iterator_int( const bson_iterator *i ) {
     switch ( bson_iterator_type( i ) ) {
     case BSON_INT:
         return bson_iterator_int_raw( i );
@@ -439,7 +461,7 @@ int bson_iterator_int( const bson_iterator *i ) {
     }
 }
 
-double bson_iterator_double( const bson_iterator *i ) {
+MONGO_EXPORT double bson_iterator_double( const bson_iterator *i ) {
     switch ( bson_iterator_type( i ) ) {
     case BSON_INT:
         return bson_iterator_int_raw( i );
@@ -452,7 +474,7 @@ double bson_iterator_double( const bson_iterator *i ) {
     }
 }
 
-int64_t bson_iterator_long( const bson_iterator *i ) {
+MONGO_EXPORT int64_t bson_iterator_long( const bson_iterator *i ) {
     switch ( bson_iterator_type( i ) ) {
     case BSON_INT:
         return bson_iterator_int_raw( i );
@@ -465,14 +487,29 @@ int64_t bson_iterator_long( const bson_iterator *i ) {
     }
 }
 
-bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ) {
+MONGO_EXPORT bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i ) {
     bson_timestamp_t ts;
     bson_little_endian32( &( ts.i ), bson_iterator_value( i ) );
     bson_little_endian32( &( ts.t ), bson_iterator_value( i ) + 4 );
     return ts;
 }
 
-bson_bool_t bson_iterator_bool( const bson_iterator *i ) {
+
+MONGO_EXPORT int bson_iterator_timestamp_time( const bson_iterator *i ) {
+    int time;
+    bson_little_endian32( &time, bson_iterator_value( i ) + 4 );
+    return time;
+}
+
+
+MONGO_EXPORT int bson_iterator_timestamp_increment( const bson_iterator *i ) {
+    int increment;
+    bson_little_endian32( &increment, bson_iterator_value( i ) );
+    return increment;
+}
+
+
+MONGO_EXPORT bson_bool_t bson_iterator_bool( const bson_iterator *i ) {
     switch ( bson_iterator_type( i ) ) {
     case BSON_BOOL:
         return bson_iterator_bool_raw( i );
@@ -490,15 +527,21 @@ bson_bool_t bson_iterator_bool( const bson_iterator *i ) {
     }
 }
 
-const char *bson_iterator_string( const bson_iterator *i ) {
-    return bson_iterator_value( i ) + 4;
+MONGO_EXPORT const char *bson_iterator_string( const bson_iterator *i ) {
+    switch ( bson_iterator_type( i ) ) {
+    case BSON_STRING:
+    case BSON_SYMBOL:
+        return bson_iterator_value( i ) + 4;
+    default:
+        return "";
+    }
 }
 
 int bson_iterator_string_len( const bson_iterator *i ) {
     return bson_iterator_int_raw( i );
 }
 
-const char *bson_iterator_code( const bson_iterator *i ) {
+MONGO_EXPORT const char *bson_iterator_code( const bson_iterator *i ) {
     switch ( bson_iterator_type( i ) ) {
     case BSON_STRING:
     case BSON_CODE:
@@ -510,57 +553,59 @@ const char *bson_iterator_code( const bson_iterator *i ) {
     }
 }
 
-void bson_iterator_code_scope( const bson_iterator *i, bson *scope ) {
+MONGO_EXPORT void bson_iterator_code_scope( const bson_iterator *i, bson *scope ) {
     if ( bson_iterator_type( i ) == BSON_CODEWSCOPE ) {
         int code_len;
         bson_little_endian32( &code_len, bson_iterator_value( i )+4 );
         bson_init_data( scope, ( void * )( bson_iterator_value( i )+8+code_len ) );
+        _bson_reset( scope );
+        scope->finished = 1;
     } else {
         bson_empty( scope );
     }
 }
 
-bson_date_t bson_iterator_date( const bson_iterator *i ) {
+MONGO_EXPORT bson_date_t bson_iterator_date( const bson_iterator *i ) {
     return bson_iterator_long_raw( i );
 }
 
-time_t bson_iterator_time_t( const bson_iterator *i ) {
+MONGO_EXPORT time_t bson_iterator_time_t( const bson_iterator *i ) {
     return bson_iterator_date( i ) / 1000;
 }
 
-int bson_iterator_bin_len( const bson_iterator *i ) {
+MONGO_EXPORT int bson_iterator_bin_len( const bson_iterator *i ) {
     return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD )
            ? bson_iterator_int_raw( i ) - 4
            : bson_iterator_int_raw( i );
 }
 
-char bson_iterator_bin_type( const bson_iterator *i ) {
+MONGO_EXPORT char bson_iterator_bin_type( const bson_iterator *i ) {
     return bson_iterator_value( i )[4];
 }
 
-const char *bson_iterator_bin_data( const bson_iterator *i ) {
+MONGO_EXPORT const char *bson_iterator_bin_data( const bson_iterator *i ) {
     return ( bson_iterator_bin_type( i ) == BSON_BIN_BINARY_OLD )
            ? bson_iterator_value( i ) + 9
            : bson_iterator_value( i ) + 5;
 }
 
-const char *bson_iterator_regex( const bson_iterator *i ) {
+MONGO_EXPORT const char *bson_iterator_regex( const bson_iterator *i ) {
     return bson_iterator_value( i );
 }
 
-const char *bson_iterator_regex_opts( const bson_iterator *i ) {
+MONGO_EXPORT const char *bson_iterator_regex_opts( const bson_iterator *i ) {
     const char *p = bson_iterator_value( i );
     return p + strlen( p ) + 1;
 
 }
 
-void bson_iterator_subobject( const bson_iterator *i, bson *sub ) {
+MONGO_EXPORT void bson_iterator_subobject( const bson_iterator *i, bson *sub ) {
     bson_init_data( sub, ( char * )bson_iterator_value( i ) );
     _bson_reset( sub );
     sub->finished = 1;
 }
 
-void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ) {
+MONGO_EXPORT void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub ) {
     bson_iterator_from_buffer( sub, bson_iterator_value( i ) );
 }
 
@@ -578,7 +623,7 @@ static void _bson_init_size( bson *b, int size ) {
     _bson_reset( b );
 }
 
-void bson_init( bson *b ) {
+MONGO_EXPORT void bson_init( bson *b ) {
     _bson_init_size( b, initialBufferSize );
 }
 
@@ -635,7 +680,7 @@ int bson_ensure_space( bson *b, const int bytesNeeded ) {
     return BSON_OK;
 }
 
-int bson_finish( bson *b ) {
+MONGO_EXPORT int bson_finish( bson *b ) {
     int i;
 
     if( b->err & BSON_NOT_UTF8 )
@@ -652,12 +697,14 @@ int bson_finish( bson *b ) {
     return BSON_OK;
 }
 
-void bson_destroy( bson *b ) {
-    bson_free( b->data );
-    b->err = 0;
-    b->data = 0;
-    b->cur = 0;
-    b->finished = 1;
+MONGO_EXPORT void bson_destroy( bson *b ) {
+    if (b) {
+        bson_free( b->data );
+        b->err = 0;
+        b->data = 0;
+        b->cur = 0;
+        b->finished = 1;
+    }
 }
 
 static int bson_append_estart( bson *b, int type, const char *name, const int dataSize ) {
@@ -686,41 +733,41 @@ static int bson_append_estart( bson *b, int type, const char *name, const int da
    BUILDING TYPES
    ------------------------------ */
 
-int bson_append_int( bson *b, const char *name, const int i ) {
+MONGO_EXPORT int bson_append_int( bson *b, const char *name, const int i ) {
     if ( bson_append_estart( b, BSON_INT, name, 4 ) == BSON_ERROR )
         return BSON_ERROR;
     bson_append32( b , &i );
     return BSON_OK;
 }
 
-int bson_append_long( bson *b, const char *name, const int64_t i ) {
+MONGO_EXPORT int bson_append_long( bson *b, const char *name, const int64_t i ) {
     if ( bson_append_estart( b , BSON_LONG, name, 8 ) == BSON_ERROR )
         return BSON_ERROR;
     bson_append64( b , &i );
     return BSON_OK;
 }
 
-int bson_append_double( bson *b, const char *name, const double d ) {
+MONGO_EXPORT int bson_append_double( bson *b, const char *name, const double d ) {
     if ( bson_append_estart( b, BSON_DOUBLE, name, 8 ) == BSON_ERROR )
         return BSON_ERROR;
     bson_append64( b , &d );
     return BSON_OK;
 }
 
-int bson_append_bool( bson *b, const char *name, const bson_bool_t i ) {
+MONGO_EXPORT int bson_append_bool( bson *b, const char *name, const bson_bool_t i ) {
     if ( bson_append_estart( b, BSON_BOOL, name, 1 ) == BSON_ERROR )
         return BSON_ERROR;
     bson_append_byte( b , i != 0 );
     return BSON_OK;
 }
 
-int bson_append_null( bson *b, const char *name ) {
+MONGO_EXPORT int bson_append_null( bson *b, const char *name ) {
     if ( bson_append_estart( b , BSON_NULL, name, 0 ) == BSON_ERROR )
         return BSON_ERROR;
     return BSON_OK;
 }
 
-int bson_append_undefined( bson *b, const char *name ) {
+MONGO_EXPORT int bson_append_undefined( bson *b, const char *name ) {
     if ( bson_append_estart( b, BSON_UNDEFINED, name, 0 ) == BSON_ERROR )
         return BSON_ERROR;
     return BSON_OK;
@@ -741,31 +788,31 @@ int bson_append_string_base( bson *b, const char *name,
     return BSON_OK;
 }
 
-int bson_append_string( bson *b, const char *name, const char *value ) {
+MONGO_EXPORT int bson_append_string( bson *b, const char *name, const char *value ) {
     return bson_append_string_base( b, name, value, strlen ( value ), BSON_STRING );
 }
 
-int bson_append_symbol( bson *b, const char *name, const char *value ) {
+MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *value ) {
     return bson_append_string_base( b, name, value, strlen ( value ), BSON_SYMBOL );
 }
 
-int bson_append_code( bson *b, const char *name, const char *value ) {
+MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *value ) {
     return bson_append_string_base( b, name, value, strlen ( value ), BSON_CODE );
 }
 
-int bson_append_string_n( bson *b, const char *name, const char *value, int len ) {
+MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *value, int len ) {
     return bson_append_string_base( b, name, value, len, BSON_STRING );
 }
 
-int bson_append_symbol_n( bson *b, const char *name, const char *value, int len ) {
+MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *value, int len ) {
     return bson_append_string_base( b, name, value, len, BSON_SYMBOL );
 }
 
-int bson_append_code_n( bson *b, const char *name, const char *value, int len ) {
+MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *value, int len ) {
     return bson_append_string_base( b, name, value, len, BSON_CODE );
 }
 
-int bson_append_code_w_scope_n( bson *b, const char *name,
+MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name,
                                 const char *code, int len, const bson *scope ) {
 
     int sl = len + 1;
@@ -779,11 +826,11 @@ int bson_append_code_w_scope_n( bson *b, const char *name,
     return BSON_OK;
 }
 
-int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ) {
+MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope ) {
     return bson_append_code_w_scope_n( b, name, code, strlen ( code ), scope );
 }
 
-int bson_append_binary( bson *b, const char *name, char type, const char *str, int len ) {
+MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, int len ) {
     if ( type == BSON_BIN_BINARY_OLD ) {
         int subtwolen = len + 4;
         if ( bson_append_estart( b, BSON_BINDATA, name, 4+1+4+len ) == BSON_ERROR )
@@ -802,20 +849,20 @@ int bson_append_binary( bson *b, const char *name, char type, const char *str, i
     return BSON_OK;
 }
 
-int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ) {
+MONGO_EXPORT int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid ) {
     if ( bson_append_estart( b, BSON_OID, name, 12 ) == BSON_ERROR )
         return BSON_ERROR;
     bson_append( b , oid , 12 );
     return BSON_OK;
 }
 
-int bson_append_new_oid( bson *b, const char *name ) {
+MONGO_EXPORT int bson_append_new_oid( bson *b, const char *name ) {
     bson_oid_t oid;
     bson_oid_gen( &oid );
     return bson_append_oid( b, name, &oid );
 }
 
-int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ) {
+MONGO_EXPORT int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts ) {
     const int plen = strlen( pattern )+1;
     const int olen = strlen( opts )+1;
     if ( bson_append_estart( b, BSON_REGEX, name, plen + olen ) == BSON_ERROR )
@@ -827,14 +874,14 @@ int bson_append_regex( bson *b, const char *name, const char *pattern, const cha
     return BSON_OK;
 }
 
-int bson_append_bson( bson *b, const char *name, const bson *bson ) {
+MONGO_EXPORT int bson_append_bson( bson *b, const char *name, const bson *bson ) {
     if ( bson_append_estart( b, BSON_OBJECT, name, bson_size( bson ) ) == BSON_ERROR )
         return BSON_ERROR;
     bson_append( b , bson->data , bson_size( bson ) );
     return BSON_OK;
 }
 
-int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) {
+MONGO_EXPORT int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) {
     bson_iterator next = *elem;
     int size;
 
@@ -854,7 +901,7 @@ int bson_append_element( bson *b, const char *name_or_null, const bson_iterator
     return BSON_OK;
 }
 
-int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ) {
+MONGO_EXPORT int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ) {
     if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
 
     bson_append32( b , &( ts->i ) );
@@ -863,31 +910,39 @@ int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts ) {
     return BSON_OK;
 }
 
-int bson_append_date( bson *b, const char *name, bson_date_t millis ) {
+MONGO_EXPORT int bson_append_timestamp2( bson *b, const char *name, int time, int increment ) {
+    if ( bson_append_estart( b, BSON_TIMESTAMP, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
+
+    bson_append32( b , &increment );
+    bson_append32( b , &time );
+    return BSON_OK;
+}
+
+MONGO_EXPORT int bson_append_date( bson *b, const char *name, bson_date_t millis ) {
     if ( bson_append_estart( b, BSON_DATE, name, 8 ) == BSON_ERROR ) return BSON_ERROR;
     bson_append64( b , &millis );
     return BSON_OK;
 }
 
-int bson_append_time_t( bson *b, const char *name, time_t secs ) {
+MONGO_EXPORT int bson_append_time_t( bson *b, const char *name, time_t secs ) {
     return bson_append_date( b, name, ( bson_date_t )secs * 1000 );
 }
 
-int bson_append_start_object( bson *b, const char *name ) {
+MONGO_EXPORT int bson_append_start_object( bson *b, const char *name ) {
     if ( bson_append_estart( b, BSON_OBJECT, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
     b->stack[ b->stackPos++ ] = b->cur - b->data;
     bson_append32( b , &zero );
     return BSON_OK;
 }
 
-int bson_append_start_array( bson *b, const char *name ) {
+MONGO_EXPORT int bson_append_start_array( bson *b, const char *name ) {
     if ( bson_append_estart( b, BSON_ARRAY, name, 5 ) == BSON_ERROR ) return BSON_ERROR;
     b->stack[ b->stackPos++ ] = b->cur - b->data;
     bson_append32( b , &zero );
     return BSON_OK;
 }
 
-int bson_append_finish_object( bson *b ) {
+MONGO_EXPORT int bson_append_finish_object( bson *b ) {
     char *start;
     int i;
     if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
@@ -900,22 +955,25 @@ int bson_append_finish_object( bson *b ) {
     return BSON_OK;
 }
 
-int bson_append_finish_array( bson *b ) {
-    return bson_append_finish_object( b );
+MONGO_EXPORT double bson_int64_to_double( int64_t i64 ) {
+  return (double)i64;
 }
 
+MONGO_EXPORT int bson_append_finish_array( bson *b ) {
+    return bson_append_finish_object( b );
+}
 
 /* Error handling and allocators. */
 
 static bson_err_handler err_handler = NULL;
 
-bson_err_handler set_bson_err_handler( bson_err_handler func ) {
+MONGO_EXPORT bson_err_handler set_bson_err_handler( bson_err_handler func ) {
     bson_err_handler old = err_handler;
     err_handler = func;
     return old;
 }
 
-void *bson_malloc( int size ) {
+MONGO_EXPORT void *bson_malloc( int size ) {
     void *p;
     p = bson_malloc_func( size );
     bson_fatal_msg( !!p, "malloc() failed" );
@@ -933,7 +991,9 @@ int _bson_errprintf( const char *format, ... ) {
     va_list ap;
     int ret;
     va_start( ap, format );
+#ifndef R_SAFETY_NET
     ret = vfprintf( stderr, format, ap );
+#endif
     va_end( ap );
 
     return ret;
@@ -961,9 +1021,10 @@ void bson_fatal_msg( int ok , const char *msg ) {
     if ( err_handler ) {
         err_handler( msg );
     }
-
+#ifndef R_SAFETY_NET
     bson_errprintf( "error: %s\n" , msg );
     exit( -5 );
+#endif
 }
 
 
@@ -976,3 +1037,28 @@ void bson_numstr( char *str, int i ) {
     else
         bson_sprintf( str,"%d", i );
 }
+
+MONGO_EXPORT void bson_swap_endian64( void *outp, const void *inp ) {
+    const char *in = ( const char * )inp;
+    char *out = ( char * )outp;
+
+    out[0] = in[7];
+    out[1] = in[6];
+    out[2] = in[5];
+    out[3] = in[4];
+    out[4] = in[3];
+    out[5] = in[2];
+    out[6] = in[1];
+    out[7] = in[0];
+
+}
+
+MONGO_EXPORT void bson_swap_endian32( void *outp, const void *inp ) {
+    const char *in = ( const char * )inp;
+    char *out = ( char * )outp;
+
+    out[0] = in[3];
+    out[1] = in[2];
+    out[2] = in[1];
+    out[3] = in[0];
+}
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.h
index 2e385b9160..b83d1ca9c9 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.h
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/bson.h
@@ -3,7 +3,7 @@
  * @brief BSON Declarations
  */
 
-/*    Copyright 2009-2011 10gen Inc.
+/*    Copyright 2009-2012 10gen Inc.
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -18,16 +18,63 @@
  *    limitations under the License.
  */
 
-#ifndef _BSON_H_
-#define _BSON_H_
+#ifndef BSON_H_
+#define BSON_H_
 
-#include "platform.h"
 #include <time.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <stdarg.h>
 
+#ifdef __GNUC__
+    #define MONGO_INLINE static __inline__
+    #define MONGO_EXPORT
+#else
+    #define MONGO_INLINE static
+    #ifdef MONGO_STATIC_BUILD
+        #define MONGO_EXPORT
+    #elif defined(MONGO_DLL_BUILD)
+        #define MONGO_EXPORT __declspec(dllexport)
+    #else
+        #define MONGO_EXPORT __declspec(dllimport)
+    #endif
+#endif
+
+#ifdef __cplusplus
+#define MONGO_EXTERN_C_START extern "C" {
+#define MONGO_EXTERN_C_END }
+#else
+#define MONGO_EXTERN_C_START
+#define MONGO_EXTERN_C_END
+#endif
+
+#if defined(MONGO_HAVE_STDINT) || __STDC_VERSION__ >= 199901L
+#include <stdint.h>
+#elif defined(MONGO_HAVE_UNISTD)
+#include <unistd.h>
+#elif defined(MONGO_USE__INT64)
+typedef __int64 int64_t;
+typedef unsigned __int64 uint64_t;
+#elif defined(MONGO_USE_LONG_LONG_INT)
+typedef long long int int64_t;
+typedef unsigned long long int uint64_t;
+#else
+#error Must compile with c99 or define MONGO_HAVE_STDINT, MONGO_HAVE_UNISTD, MONGO_USE__INT64, or MONGO_USE_LONG_INT.
+#endif
+
+#ifdef MONGO_BIG_ENDIAN
+#define bson_little_endian64(out, in) ( bson_swap_endian64(out, in) )
+#define bson_little_endian32(out, in) ( bson_swap_endian32(out, in) )
+#define bson_big_endian64(out, in) ( memcpy(out, in, 8) )
+#define bson_big_endian32(out, in) ( memcpy(out, in, 4) )
+#else
+#define bson_little_endian64(out, in) ( memcpy(out, in, 8) )
+#define bson_little_endian32(out, in) ( memcpy(out, in, 4) )
+#define bson_big_endian64(out, in) ( bson_swap_endian64(out, in) )
+#define bson_big_endian32(out, in) ( bson_swap_endian32(out, in) )
+#endif
+
 MONGO_EXTERN_C_START
 
 #define BSON_OK 0
@@ -84,12 +131,12 @@ typedef struct {
 } bson_iterator;
 
 typedef struct {
-    char *data;
-    char *cur;
-    int dataSize;
-    bson_bool_t finished;
-    int stack[32];
-    int stackPos;
+    char *data;    /**< Pointer to a block of data in this BSON object. */
+    char *cur;     /**< Pointer to the current position. */
+    int dataSize;  /**< The number of bytes allocated to char *data. */
+    bson_bool_t finished; /**< When finished, the BSON object can no longer be modified. */
+    int stack[32];        /**< A stack used to keep track of nested BSON elements. */
+    int stackPos;         /**< Index of current stack position. */
     int err; /**< Bitfield representing errors or warnings on this buffer */
     char *errstr; /**< A string representation of the most recent error or warning. */
 } bson;
@@ -112,6 +159,9 @@ typedef struct {
    READING
    ------------------------------ */
 
+MONGO_EXPORT bson* bson_create();
+MONGO_EXPORT void  bson_dispose(bson* b);
+
 /**
  * Size of a BSON object.
  *
@@ -119,21 +169,22 @@ typedef struct {
  *
  * @return the size.
  */
-int bson_size( const bson *b );
+MONGO_EXPORT int bson_size( const bson *b );
+MONGO_EXPORT int bson_buffer_size( const bson *b );
 
 /**
  * Print a string representation of a BSON object.
  *
  * @param b the BSON object to print.
  */
-void bson_print( bson *b );
+MONGO_EXPORT void bson_print( const bson *b );
 
 /**
  * Return a pointer to the raw buffer stored by this bson object.
  *
  * @param b a BSON object
  */
-const char *bson_data( bson *b );
+MONGO_EXPORT const char *bson_data( const bson *b );
 
 /**
  * Print a string representation of a BSON object.
@@ -141,7 +192,7 @@ const char *bson_data( bson *b );
  * @param bson the raw data to print.
  * @param depth the depth to recurse the object.x
  */
-void bson_print_raw( const char *bson , int depth );
+MONGO_EXPORT void bson_print_raw( const char *bson , int depth );
 
 /**
  * Advance a bson_iterator to the named field.
@@ -152,15 +203,18 @@ void bson_print_raw( const char *bson , int depth );
  *
  * @return the type of the found object or BSON_EOO if it is not found.
  */
-bson_type bson_find( bson_iterator *it, const bson *obj, const char *name );
+MONGO_EXPORT bson_type bson_find( bson_iterator *it, const bson *obj, const char *name );
 
+
+MONGO_EXPORT bson_iterator* bson_iterator_create();
+MONGO_EXPORT void bson_iterator_dispose(bson_iterator*);
 /**
  * Initialize a bson_iterator.
  *
  * @param i the bson_iterator to initialize.
  * @param bson the BSON object to associate with the iterator.
  */
-void bson_iterator_init( bson_iterator *i , const bson *b );
+MONGO_EXPORT void bson_iterator_init( bson_iterator *i , const bson *b );
 
 /**
  * Initialize a bson iterator from a const char* buffer. Note
@@ -169,7 +223,7 @@ void bson_iterator_init( bson_iterator *i , const bson *b );
  * @param i the bson_iterator to initialize.
  * @param buffer the buffer to point to.
  */
-void bson_iterator_from_buffer( bson_iterator *i, const char *buffer );
+MONGO_EXPORT void bson_iterator_from_buffer( bson_iterator *i, const char *buffer );
 
 /* more returns true for eoo. best to loop with bson_iterator_next(&it) */
 /**
@@ -179,7 +233,7 @@ void bson_iterator_from_buffer( bson_iterator *i, const char *buffer );
  *
  * @return  returns true if there is more data.
  */
-bson_bool_t bson_iterator_more( const bson_iterator *i );
+MONGO_EXPORT bson_bool_t bson_iterator_more( const bson_iterator *i );
 
 /**
  * Point the iterator at the next BSON object.
@@ -188,7 +242,7 @@ bson_bool_t bson_iterator_more( const bson_iterator *i );
  *
  * @return the type of the next BSON object.
  */
-bson_type bson_iterator_next( bson_iterator *i );
+MONGO_EXPORT bson_type bson_iterator_next( bson_iterator *i );
 
 /**
  * Get the type of the BSON object currently pointed to by the iterator.
@@ -197,7 +251,7 @@ bson_type bson_iterator_next( bson_iterator *i );
  *
  * @return  the type of the current BSON object.
  */
-bson_type bson_iterator_type( const bson_iterator *i );
+MONGO_EXPORT bson_type bson_iterator_type( const bson_iterator *i );
 
 /**
  * Get the key of the BSON object currently pointed to by the iterator.
@@ -206,7 +260,7 @@ bson_type bson_iterator_type( const bson_iterator *i );
  *
  * @return the key of the current BSON object.
  */
-const char *bson_iterator_key( const bson_iterator *i );
+MONGO_EXPORT const char *bson_iterator_key( const bson_iterator *i );
 
 /**
  * Get the value of the BSON object currently pointed to by the iterator.
@@ -215,7 +269,7 @@ const char *bson_iterator_key( const bson_iterator *i );
  *
  * @return  the value of the current BSON object.
  */
-const char *bson_iterator_value( const bson_iterator *i );
+MONGO_EXPORT const char *bson_iterator_value( const bson_iterator *i );
 
 /* these convert to the right type (return 0 if non-numeric) */
 /**
@@ -226,7 +280,7 @@ const char *bson_iterator_value( const bson_iterator *i );
  *
  * @return  the value of the current BSON object.
  */
-double bson_iterator_double( const bson_iterator *i );
+MONGO_EXPORT double bson_iterator_double( const bson_iterator *i );
 
 /**
  * Get the int value of the BSON object currently pointed to by the iterator.
@@ -235,7 +289,7 @@ double bson_iterator_double( const bson_iterator *i );
  *
  * @return  the value of the current BSON object.
  */
-int bson_iterator_int( const bson_iterator *i );
+MONGO_EXPORT int bson_iterator_int( const bson_iterator *i );
 
 /**
  * Get the long value of the BSON object currently pointed to by the iterator.
@@ -244,7 +298,7 @@ int bson_iterator_int( const bson_iterator *i );
  *
  * @return the value of the current BSON object.
  */
-int64_t bson_iterator_long( const bson_iterator *i );
+MONGO_EXPORT int64_t bson_iterator_long( const bson_iterator *i );
 
 /* return the bson timestamp as a whole or in parts */
 /**
@@ -255,7 +309,9 @@ int64_t bson_iterator_long( const bson_iterator *i );
  *
  * @return the value of the current BSON object.
  */
-bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i );
+MONGO_EXPORT bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i );
+MONGO_EXPORT int bson_iterator_timestamp_time( const bson_iterator *i );
+MONGO_EXPORT int bson_iterator_timestamp_increment( const bson_iterator *i );
 
 /**
  * Get the boolean value of the BSON object currently pointed to by
@@ -267,7 +323,7 @@ bson_timestamp_t bson_iterator_timestamp( const bson_iterator *i );
  */
 /* false: boolean false, 0 in any type, or null */
 /* true: anything else (even empty strings and objects) */
-bson_bool_t bson_iterator_bool( const bson_iterator *i );
+MONGO_EXPORT bson_bool_t bson_iterator_bool( const bson_iterator *i );
 
 /**
  * Get the double value of the BSON object currently pointed to by the
@@ -318,7 +374,7 @@ bson_bool_t bson_iterator_bool_raw( const bson_iterator *i );
  *
  * @return the value of the current BSON object.
  */
-bson_oid_t *bson_iterator_oid( const bson_iterator *i );
+MONGO_EXPORT bson_oid_t *bson_iterator_oid( const bson_iterator *i );
 
 /**
  * Get the string value of the BSON object currently pointed to by the
@@ -329,7 +385,7 @@ bson_oid_t *bson_iterator_oid( const bson_iterator *i );
  * @return  the value of the current BSON object.
  */
 /* these can also be used with bson_code and bson_symbol*/
-const char *bson_iterator_string( const bson_iterator *i );
+MONGO_EXPORT const char *bson_iterator_string( const bson_iterator *i );
 
 /**
  * Get the string length of the BSON object currently pointed to by the
@@ -352,7 +408,7 @@ int bson_iterator_string_len( const bson_iterator *i );
  */
 /* works with bson_code, bson_codewscope, and BSON_STRING */
 /* returns NULL for everything else */
-const char *bson_iterator_code( const bson_iterator *i );
+MONGO_EXPORT const char *bson_iterator_code( const bson_iterator *i );
 
 /**
  * Calls bson_empty on scope if not a bson_codewscope
@@ -361,7 +417,7 @@ const char *bson_iterator_code( const bson_iterator *i );
  * @param scope the bson scope.
  */
 /* calls bson_empty on scope if not a bson_codewscope */
-void bson_iterator_code_scope( const bson_iterator *i, bson *scope );
+MONGO_EXPORT void bson_iterator_code_scope( const bson_iterator *i, bson *scope );
 
 /**
  * Get the date value of the BSON object currently pointed to by the
@@ -372,7 +428,7 @@ void bson_iterator_code_scope( const bson_iterator *i, bson *scope );
  * @return the date value of the current BSON object.
  */
 /* both of these only work with bson_date */
-bson_date_t bson_iterator_date( const bson_iterator *i );
+MONGO_EXPORT bson_date_t bson_iterator_date( const bson_iterator *i );
 
 /**
  * Get the time value of the BSON object currently pointed to by the
@@ -382,7 +438,7 @@ bson_date_t bson_iterator_date( const bson_iterator *i );
  *
  * @return the time value of the current BSON object.
  */
-time_t bson_iterator_time_t( const bson_iterator *i );
+MONGO_EXPORT time_t bson_iterator_time_t( const bson_iterator *i );
 
 /**
  * Get the length of the BSON binary object currently pointed to by the
@@ -392,7 +448,7 @@ time_t bson_iterator_time_t( const bson_iterator *i );
  *
  * @return the length of the current BSON binary object.
  */
-int bson_iterator_bin_len( const bson_iterator *i );
+MONGO_EXPORT int bson_iterator_bin_len( const bson_iterator *i );
 
 /**
  * Get the type of the BSON binary object currently pointed to by the
@@ -402,7 +458,7 @@ int bson_iterator_bin_len( const bson_iterator *i );
  *
  * @return the type of the current BSON binary object.
  */
-char bson_iterator_bin_type( const bson_iterator *i );
+MONGO_EXPORT char bson_iterator_bin_type( const bson_iterator *i );
 
 /**
  * Get the value of the BSON binary object currently pointed to by the
@@ -412,7 +468,7 @@ char bson_iterator_bin_type( const bson_iterator *i );
  *
  * @return the value of the current BSON binary object.
  */
-const char *bson_iterator_bin_data( const bson_iterator *i );
+MONGO_EXPORT const char *bson_iterator_bin_data( const bson_iterator *i );
 
 /**
  * Get the value of the BSON regex object currently pointed to by the
@@ -422,7 +478,7 @@ const char *bson_iterator_bin_data( const bson_iterator *i );
  *
  * @return the value of the current BSON regex object.
  */
-const char *bson_iterator_regex( const bson_iterator *i );
+MONGO_EXPORT const char *bson_iterator_regex( const bson_iterator *i );
 
 /**
  * Get the options of the BSON regex object currently pointed to by the
@@ -432,7 +488,7 @@ const char *bson_iterator_regex( const bson_iterator *i );
  *
  * @return the options of the current BSON regex object.
  */
-const char *bson_iterator_regex_opts( const bson_iterator *i );
+MONGO_EXPORT const char *bson_iterator_regex_opts( const bson_iterator *i );
 
 /* these work with BSON_OBJECT and BSON_ARRAY */
 /**
@@ -442,7 +498,7 @@ const char *bson_iterator_regex_opts( const bson_iterator *i );
  * @param i the bson_iterator.
  * @param sub the BSON subobject destination.
  */
-void bson_iterator_subobject( const bson_iterator *i, bson *sub );
+MONGO_EXPORT void bson_iterator_subobject( const bson_iterator *i, bson *sub );
 
 /**
  * Get a bson_iterator that on the BSON subobject.
@@ -450,7 +506,7 @@ void bson_iterator_subobject( const bson_iterator *i, bson *sub );
  * @param i the bson_iterator.
  * @param sub the iterator to point at the BSON subobject.
  */
-void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub );
+MONGO_EXPORT void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub );
 
 /* str must be at least 24 hex chars + null byte */
 /**
@@ -459,7 +515,7 @@ void bson_iterator_subiterator( const bson_iterator *i, bson_iterator *sub );
  * @param oid the bson_oid_t destination.
  * @param str a null terminated string comprised of at least 24 hex chars.
  */
-void bson_oid_from_string( bson_oid_t *oid, const char *str );
+MONGO_EXPORT void bson_oid_from_string( bson_oid_t *oid, const char *str );
 
 /**
  * Create a string representation of the bson_oid_t.
@@ -467,14 +523,14 @@ void bson_oid_from_string( bson_oid_t *oid, const char *str );
  * @param oid the bson_oid_t source.
  * @param str the string representation destination.
  */
-void bson_oid_to_string( const bson_oid_t *oid, char *str );
+MONGO_EXPORT void bson_oid_to_string( const bson_oid_t *oid, char *str );
 
 /**
  * Create a bson_oid object.
  *
  * @param oid the destination for the newly created bson_oid_t.
  */
-void bson_oid_gen( bson_oid_t *oid );
+MONGO_EXPORT void bson_oid_gen( bson_oid_t *oid );
 
 /**
  * Set a function to be used to generate the second four bytes
@@ -482,7 +538,7 @@ void bson_oid_gen( bson_oid_t *oid );
  *
  * @param func a pointer to a function that returns an int.
  */
-void bson_set_oid_fuzz( int ( *func )( void ) );
+MONGO_EXPORT void bson_set_oid_fuzz( int ( *func )( void ) );
 
 /**
  * Set a function to be used to generate the incrementing part
@@ -491,14 +547,14 @@ void bson_set_oid_fuzz( int ( *func )( void ) );
  *
  * @param func a pointer to a function that returns an int.
  */
-void bson_set_oid_inc( int ( *func )( void ) );
+MONGO_EXPORT void bson_set_oid_inc( int ( *func )( void ) );
 
 /**
  * Get the time a bson_oid_t was created.
  *
  * @param oid the bson_oid_t.
  */
-time_t bson_oid_generated_time( bson_oid_t *oid ); /* Gives the time the OID was created */
+MONGO_EXPORT time_t bson_oid_generated_time( bson_oid_t *oid ); /* Gives the time the OID was created */
 
 /* ----------------------------
    BUILDING
@@ -512,7 +568,7 @@ time_t bson_oid_generated_time( bson_oid_t *oid ); /* Gives the time the OID was
  *  @note When finished, you must pass the bson object to
  *      bson_destroy( ).
  */
-void bson_init( bson *b );
+MONGO_EXPORT void bson_init( bson *b );
 
 /**
  * Initialize a BSON object, and point its data
@@ -524,6 +580,7 @@ void bson_init( bson *b );
  * @return BSON_OK or BSON_ERROR.
  */
 int bson_init_data( bson *b , char *data );
+int bson_init_finished_data( bson *b, char *data ) ;
 
 /**
  * Initialize a BSON object, and set its
@@ -555,7 +612,7 @@ int bson_ensure_space( bson *b, const int bytesNeeded );
  * @return the standard error code. To deallocate memory,
  *   call bson_destroy on the bson object.
  */
-int bson_finish( bson *b );
+MONGO_EXPORT int bson_finish( bson *b );
 
 /**
  * Destroy a bson object.
@@ -563,7 +620,7 @@ int bson_finish( bson *b );
  * @param b the bson object to destroy.
  *
  */
-void bson_destroy( bson *b );
+MONGO_EXPORT void bson_destroy( bson *b );
 
 /**
  * Returns a pointer to a static empty BSON object.
@@ -573,23 +630,17 @@ void bson_destroy( bson *b );
  * @return the empty initialized BSON object.
  */
 /* returns pointer to static empty bson object */
-bson *bson_empty( bson *obj );
-
-/**
- * Copy BSON data only from one object to another.
- *
- * @param out the copy destination BSON object.
- * @param in the copy source BSON object.
- */
-void bson_copy_basic( bson *out, const bson *in );
+MONGO_EXPORT bson *bson_empty( bson *obj );
 
 /**
  * Make a complete copy of the a BSON object.
+ * The source bson object must be in a finished
+ * state; otherwise, the copy will fail.
  *
  * @param out the copy destination BSON object.
  * @param in the copy source BSON object.
  */
-void bson_copy( bson *out, const bson *in ); /* puts data in new buffer. NOOP if out==NULL */
+MONGO_EXPORT int bson_copy( bson *out, const bson *in ); /* puts data in new buffer. NOOP if out==NULL */
 
 /**
  * Append a previously created bson_oid_t to a bson object.
@@ -600,7 +651,7 @@ void bson_copy( bson *out, const bson *in ); /* puts data in new buffer. NOOP if
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid );
+MONGO_EXPORT int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid );
 
 /**
  * Append a bson_oid_t to a bson.
@@ -610,7 +661,7 @@ int bson_append_oid( bson *b, const char *name, const bson_oid_t *oid );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_new_oid( bson *b, const char *name );
+MONGO_EXPORT int bson_append_new_oid( bson *b, const char *name );
 
 /**
  * Append an int to a bson.
@@ -621,7 +672,7 @@ int bson_append_new_oid( bson *b, const char *name );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_int( bson *b, const char *name, const int i );
+MONGO_EXPORT int bson_append_int( bson *b, const char *name, const int i );
 
 /**
  * Append an long to a bson.
@@ -632,7 +683,7 @@ int bson_append_int( bson *b, const char *name, const int i );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_long( bson *b, const char *name, const int64_t i );
+MONGO_EXPORT int bson_append_long( bson *b, const char *name, const int64_t i );
 
 /**
  * Append an double to a bson.
@@ -643,7 +694,7 @@ int bson_append_long( bson *b, const char *name, const int64_t i );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_double( bson *b, const char *name, const double d );
+MONGO_EXPORT int bson_append_double( bson *b, const char *name, const double d );
 
 /**
  * Append a string to a bson.
@@ -654,7 +705,7 @@ int bson_append_double( bson *b, const char *name, const double d );
  *
  * @return BSON_OK or BSON_ERROR.
 */
-int bson_append_string( bson *b, const char *name, const char *str );
+MONGO_EXPORT int bson_append_string( bson *b, const char *name, const char *str );
 
 /**
  * Append len bytes of a string to a bson.
@@ -666,7 +717,7 @@ int bson_append_string( bson *b, const char *name, const char *str );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_string_n( bson *b, const char *name, const char *str, int len );
+MONGO_EXPORT int bson_append_string_n( bson *b, const char *name, const char *str, int len );
 
 /**
  * Append a symbol to a bson.
@@ -677,7 +728,7 @@ int bson_append_string_n( bson *b, const char *name, const char *str, int len );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_symbol( bson *b, const char *name, const char *str );
+MONGO_EXPORT int bson_append_symbol( bson *b, const char *name, const char *str );
 
 /**
  * Append len bytes of a symbol to a bson.
@@ -689,7 +740,7 @@ int bson_append_symbol( bson *b, const char *name, const char *str );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_symbol_n( bson *b, const char *name, const char *str, int len );
+MONGO_EXPORT int bson_append_symbol_n( bson *b, const char *name, const char *str, int len );
 
 /**
  * Append code to a bson.
@@ -701,7 +752,7 @@ int bson_append_symbol_n( bson *b, const char *name, const char *str, int len );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_code( bson *b, const char *name, const char *str );
+MONGO_EXPORT int bson_append_code( bson *b, const char *name, const char *str );
 
 /**
  * Append len bytes of code to a bson.
@@ -713,7 +764,7 @@ int bson_append_code( bson *b, const char *name, const char *str );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_code_n( bson *b, const char *name, const char *str, int len );
+MONGO_EXPORT int bson_append_code_n( bson *b, const char *name, const char *str, int len );
 
 /**
  * Append code to a bson with scope.
@@ -725,7 +776,7 @@ int bson_append_code_n( bson *b, const char *name, const char *str, int len );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope );
+MONGO_EXPORT int bson_append_code_w_scope( bson *b, const char *name, const char *code, const bson *scope );
 
 /**
  * Append len bytes of code to a bson with scope.
@@ -738,7 +789,7 @@ int bson_append_code_w_scope( bson *b, const char *name, const char *code, const
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, int size, const bson *scope );
+MONGO_EXPORT int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, int size, const bson *scope );
 
 /**
  * Append binary data to a bson.
@@ -751,7 +802,7 @@ int bson_append_code_w_scope_n( bson *b, const char *name, const char *code, int
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_binary( bson *b, const char *name, char type, const char *str, int len );
+MONGO_EXPORT int bson_append_binary( bson *b, const char *name, char type, const char *str, int len );
 
 /**
  * Append a bson_bool_t to a bson.
@@ -762,7 +813,7 @@ int bson_append_binary( bson *b, const char *name, char type, const char *str, i
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_bool( bson *b, const char *name, const bson_bool_t v );
+MONGO_EXPORT int bson_append_bool( bson *b, const char *name, const bson_bool_t v );
 
 /**
  * Append a null value to a bson.
@@ -772,7 +823,7 @@ int bson_append_bool( bson *b, const char *name, const bson_bool_t v );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_null( bson *b, const char *name );
+MONGO_EXPORT int bson_append_null( bson *b, const char *name );
 
 /**
  * Append an undefined value to a bson.
@@ -782,7 +833,7 @@ int bson_append_null( bson *b, const char *name );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_undefined( bson *b, const char *name );
+MONGO_EXPORT int bson_append_undefined( bson *b, const char *name );
 
 /**
  * Append a regex value to a bson.
@@ -794,7 +845,7 @@ int bson_append_undefined( bson *b, const char *name );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts );
+MONGO_EXPORT int bson_append_regex( bson *b, const char *name, const char *pattern, const char *opts );
 
 /**
  * Append bson data to a bson.
@@ -805,7 +856,7 @@ int bson_append_regex( bson *b, const char *name, const char *pattern, const cha
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_bson( bson *b, const char *name, const bson *bson );
+MONGO_EXPORT int bson_append_bson( bson *b, const char *name, const bson *bson );
 
 /**
  * Append a BSON element to a bson from the current point of an iterator.
@@ -816,7 +867,7 @@ int bson_append_bson( bson *b, const char *name, const bson *bson );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem );
+MONGO_EXPORT int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem );
 
 /**
  * Append a bson_timestamp_t value to a bson.
@@ -827,7 +878,8 @@ int bson_append_element( bson *b, const char *name_or_null, const bson_iterator
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts );
+MONGO_EXPORT int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts );
+MONGO_EXPORT int bson_append_timestamp2( bson *b, const char *name, int time, int increment );
 
 /* these both append a bson_date */
 /**
@@ -839,7 +891,7 @@ int bson_append_timestamp( bson *b, const char *name, bson_timestamp_t *ts );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_date( bson *b, const char *name, bson_date_t millis );
+MONGO_EXPORT int bson_append_date( bson *b, const char *name, bson_date_t millis );
 
 /**
  * Append a time_t value to a bson.
@@ -850,7 +902,7 @@ int bson_append_date( bson *b, const char *name, bson_date_t millis );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_time_t( bson *b, const char *name, time_t secs );
+MONGO_EXPORT int bson_append_time_t( bson *b, const char *name, time_t secs );
 
 /**
  * Start appending a new object to a bson.
@@ -860,7 +912,7 @@ int bson_append_time_t( bson *b, const char *name, time_t secs );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_start_object( bson *b, const char *name );
+MONGO_EXPORT int bson_append_start_object( bson *b, const char *name );
 
 /**
  * Start appending a new array to a bson.
@@ -870,7 +922,7 @@ int bson_append_start_object( bson *b, const char *name );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_start_array( bson *b, const char *name );
+MONGO_EXPORT int bson_append_start_array( bson *b, const char *name );
 
 /**
  * Finish appending a new object or array to a bson.
@@ -879,7 +931,7 @@ int bson_append_start_array( bson *b, const char *name );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_finish_object( bson *b );
+MONGO_EXPORT int bson_append_finish_object( bson *b );
 
 /**
  * Finish appending a new object or array to a bson. This
@@ -889,13 +941,13 @@ int bson_append_finish_object( bson *b );
  *
  * @return BSON_OK or BSON_ERROR.
  */
-int bson_append_finish_array( bson *b );
+MONGO_EXPORT int bson_append_finish_array( bson *b );
 
 void bson_numstr( char *str, int i );
 
 void bson_incnumstr( char *str );
 
-/* Error handling and stadard library function over-riding. */
+/* Error handling and standard library function over-riding. */
 /* -------------------------------------------------------- */
 
 /* bson_err_handlers shouldn't return!!! */
@@ -912,7 +964,6 @@ extern void ( *bson_free )( void * );
 extern bson_printf_func bson_printf;
 extern bson_fprintf_func bson_fprintf;
 extern bson_sprintf_func bson_sprintf;
-
 extern bson_printf_func bson_errprintf;
 
 /**
@@ -924,7 +975,7 @@ extern bson_printf_func bson_errprintf;
  *
  * @sa malloc(3)
  */
-void *bson_malloc( int size );
+MONGO_EXPORT void *bson_malloc( int size );
 
 /**
  * Changes the size of allocated memory and checks return value,
@@ -946,7 +997,7 @@ void *bson_realloc( void *ptr, int size );
  *
  * @return the old error handling function, or NULL.
  */
-bson_err_handler set_bson_err_handler( bson_err_handler func );
+MONGO_EXPORT bson_err_handler set_bson_err_handler( bson_err_handler func );
 
 /* does nothing if ok != 0 */
 /**
@@ -971,5 +1022,15 @@ void bson_fatal_msg( int ok, const char *msg );
  */
 void bson_builder_error( bson *b );
 
+/**
+ * Cast an int64_t to double. This is necessary for embedding in
+ * certain environments.
+ *
+ */
+MONGO_EXPORT double bson_int64_to_double( int64_t i64 );
+
+MONGO_EXPORT void bson_swap_endian32( void *outp, const void *inp );
+MONGO_EXPORT void bson_swap_endian64( void *outp, const void *inp );
+
 MONGO_EXTERN_C_END
 #endif
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.c
index 8d2da1502f..00ecf18c92 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.c
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009-2011 10gen, Inc.
+ * Copyright 2009-2012 10gen, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.h
index a2a07c6d5d..f13c31ee89 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.h
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/encoding.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009-2011 10gen, Inc.
+ * Copyright 2009-2012 10gen, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef _BSON_ENCODING_H_
-#define _BSON_ENCODING_H_
+#ifndef BSON_ENCODING_H_
+#define BSON_ENCODING_H_
 
 MONGO_EXTERN_C_START
 
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env.h
new file mode 100644
index 0000000000..463ee32f79
--- /dev/null
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env.h
@@ -0,0 +1,39 @@
+/** @file env.h */
+
+/*    Copyright 2009-2012 10gen 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.
+ */
+
+/* Header for generic net.h */
+#ifndef MONGO_ENV_H_
+#define MONGO_ENV_H_
+
+#include "mongo.h"
+
+MONGO_EXTERN_C_START
+
+/* This is a no-op in the generic implementation. */
+int mongo_env_set_socket_op_timeout( mongo *conn, int millis );
+int mongo_env_read_socket( mongo *conn, void *buf, int len );
+int mongo_env_write_socket( mongo *conn, const void *buf, int len );
+int mongo_env_socket_connect( mongo *conn, const char *host, int port );
+
+/* Initialize socket services */
+MONGO_EXPORT int mongo_env_sock_init( void );
+
+/* Close a socket */
+MONGO_EXPORT int mongo_env_close_socket( int socket );
+
+MONGO_EXTERN_C_END
+#endif
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c
new file mode 100644
index 0000000000..f1020ca80d
--- /dev/null
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_posix.c
@@ -0,0 +1,165 @@
+/* env_posix.c */
+
+/*    Copyright 2009-2012 10gen 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.
+ */
+
+/* Networking and other niceties for POSIX systems. */
+#include "env.h"
+#include "mongo.h"
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#ifndef NI_MAXSERV
+# define NI_MAXSERV 32
+#endif
+
+int mongo_env_close_socket( int socket ) {
+    return close( socket );
+}
+
+int mongo_env_sock_init( void ) {
+    return 0;
+}
+
+int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
+    const char *cbuf = buf;
+#ifdef __APPLE__
+    int flags = 0;
+#else
+    int flags = MSG_NOSIGNAL;
+#endif
+
+    while ( len ) {
+        int sent = send( conn->sock, cbuf, len, flags );
+        if ( sent == -1 ) {
+            if (errno == EPIPE)
+                conn->connected = 0;
+            __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno );
+            return MONGO_ERROR;
+        }
+        cbuf += sent;
+        len -= sent;
+    }
+
+    return MONGO_OK;
+}
+
+int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
+    char *cbuf = buf;
+    while ( len ) {
+        int sent = recv( conn->sock, cbuf, len, 0 );
+        if ( sent == 0 || sent == -1 ) {
+            __mongo_set_error( conn, MONGO_IO_ERROR, strerror( errno ), errno );
+            return MONGO_ERROR;
+        }
+        cbuf += sent;
+        len -= sent;
+    }
+
+    return MONGO_OK;
+}
+
+int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) {
+    struct timeval tv;
+    tv.tv_sec = millis / 1000;
+    tv.tv_usec = ( millis % 1000 ) * 1000;
+
+    if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof( tv ) ) == -1 ) {
+        conn->err = MONGO_IO_ERROR;
+        __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.", errno );
+        return MONGO_ERROR;
+    }
+
+    if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof( tv ) ) == -1 ) {
+        __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.", errno );
+        return MONGO_ERROR;
+    }
+
+    return MONGO_OK;
+}
+
+int mongo_env_socket_connect( mongo *conn, const char *host, int port ) {
+    char port_str[NI_MAXSERV];
+    int status;
+
+    struct addrinfo ai_hints;
+    struct addrinfo *ai_list = NULL;
+    struct addrinfo *ai_ptr = NULL;
+
+    conn->sock = 0;
+    conn->connected = 0;
+    sprintf(port_str,"%d",port);
+
+    bson_sprintf( port_str, "%d", port );
+
+    memset( &ai_hints, 0, sizeof( ai_hints ) );
+#ifdef AI_ADDRCONFIG
+    ai_hints.ai_flags = AI_ADDRCONFIG;
+#endif
+    ai_hints.ai_family = AF_UNSPEC;
+    ai_hints.ai_socktype = SOCK_STREAM;
+
+    status = getaddrinfo( host, port_str, &ai_hints, &ai_list );
+    if ( status != 0 ) {
+        bson_errprintf( "getaddrinfo failed: %s", gai_strerror( status ) );
+        conn->err = MONGO_CONN_ADDR_FAIL;
+        return MONGO_ERROR;
+    }
+
+    for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) {
+        conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype, ai_ptr->ai_protocol );
+        if ( conn->sock < 0 ) {
+            conn->sock = 0;
+            continue;
+        }
+
+        status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen );
+        if ( status != 0 ) {
+            mongo_env_close_socket( conn->sock );
+            conn->sock = 0;
+            continue;
+        }
+
+        if ( ai_ptr->ai_protocol == IPPROTO_TCP ) {
+            int flag = 1;
+
+            setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY,
+                        ( void * ) &flag, sizeof( flag ) );
+            if ( conn->op_timeout_ms > 0 )
+                mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms );
+        }
+
+        conn->connected = 1;
+        break;
+    }
+
+    freeaddrinfo( ai_list );
+
+    if ( ! conn->connected ) {
+        conn->err = MONGO_CONN_FAIL;
+        return MONGO_ERROR;
+    }
+
+    return MONGO_OK;
+}
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_standard.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_standard.c
new file mode 100644
index 0000000000..36fa9f65c4
--- /dev/null
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_standard.c
@@ -0,0 +1,168 @@
+/* env_standard.c */
+
+/*    Copyright 2009-2012 10gen 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.
+ */
+
+/* Vanilla networking designed to work on all systems. */
+#include "env.h"
+#include <errno.h>
+#include <string.h>
+
+#ifdef _WIN32
+    #ifdef _MSC_VER
+        #include <ws2tcpip.h>  // send,recv,socklen_t etc
+        #include <wspiapi.h>   // addrinfo
+    #else
+        #include <windows.h>
+        #include <winsock.h>
+        typedef int socklen_t;
+    #endif
+#else
+#include <arpa/inet.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <fcntl.h>
+#include <unistd.h>
+#endif
+
+#ifndef NI_MAXSERV
+# define NI_MAXSERV 32
+#endif
+
+int mongo_env_close_socket( int socket ) {
+#ifdef _WIN32
+    return closesocket( socket );
+#else
+    return close( socket );
+#endif
+}
+
+int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
+    const char *cbuf = buf;
+#ifdef _WIN32
+    int flags = 0;
+#else
+#ifdef __APPLE__
+    int flags = 0;
+#else
+    int flags = MSG_NOSIGNAL;
+#endif
+#endif
+
+    while ( len ) {
+        int sent = send( conn->sock, cbuf, len, flags );
+        if ( sent == -1 ) {
+            if (errno == EPIPE) 
+                conn->connected = 0;
+            conn->err = MONGO_IO_ERROR;
+            return MONGO_ERROR;
+        }
+        cbuf += sent;
+        len -= sent;
+    }
+
+    return MONGO_OK;
+}
+
+int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
+    char *cbuf = buf;
+    while ( len ) {
+        int sent = recv( conn->sock, cbuf, len, 0 );
+        if ( sent == 0 || sent == -1 ) {
+            conn->err = MONGO_IO_ERROR;
+            return MONGO_ERROR;
+        }
+        cbuf += sent;
+        len -= sent;
+    }
+
+    return MONGO_OK;
+}
+
+/* This is a no-op in the generic implementation. */
+int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) {
+    return MONGO_OK;
+}
+
+int mongo_env_socket_connect( mongo *conn, const char *host, int port ) {
+    struct sockaddr_in sa;
+    socklen_t addressSize;
+    int flag = 1;
+
+    if ( ( conn->sock = socket( AF_INET, SOCK_STREAM, 0 ) ) < 0 ) {
+        conn->sock = 0;
+        conn->err = MONGO_CONN_NO_SOCKET;
+        return MONGO_ERROR;
+    }
+
+    memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) );
+    sa.sin_family = AF_INET;
+    sa.sin_port = htons( port );
+    sa.sin_addr.s_addr = inet_addr( host );
+    addressSize = sizeof( sa );
+
+    if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) {
+        mongo_env_close_socket( conn->sock );
+        conn->connected = 0;
+        conn->sock = 0;
+        conn->err = MONGO_CONN_FAIL;
+        return MONGO_ERROR;
+    }
+
+    setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) );
+
+    if( conn->op_timeout_ms > 0 )
+        mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms );
+
+    conn->connected = 1;
+
+    return MONGO_OK;
+}
+
+MONGO_EXPORT int mongo_env_sock_init( void ) {
+
+#if defined(_WIN32)
+    WSADATA wsaData;
+    WORD wVers;
+#elif defined(SIGPIPE)
+    struct sigaction act;
+#endif
+
+    static int called_once;
+    static int retval;
+    if (called_once) return retval;
+    called_once = 1;
+
+#if defined(_WIN32)
+    wVers = MAKEWORD(1, 1);
+    retval = (WSAStartup(wVers, &wsaData) == 0);
+#elif defined(MACINTOSH)
+    GUSISetup(GUSIwithInternetSockets);
+    retval = 1;
+#elif defined(SIGPIPE)
+    retval = 1;
+    if (sigaction(SIGPIPE, (struct sigaction *)NULL, &act) < 0)
+        retval = 0;
+    else if (act.sa_handler == SIG_DFL) {
+        act.sa_handler = SIG_IGN;
+        if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) < 0)
+            retval = 0;
+    }
+#endif
+    return retval;
+}
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_win32.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_win32.c
new file mode 100644
index 0000000000..0b301cea61
--- /dev/null
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/env_win32.c
@@ -0,0 +1,183 @@
+/* env_win32.c */
+
+/*    Copyright 2009-2012 10gen 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.
+ */
+
+/* Networking and other niceties for WIN32. */
+#include "env.h"
+#include "mongo.h"
+#include <string.h>
+
+#ifdef _MSC_VER
+#include <ws2tcpip.h>  // send,recv,socklen_t etc
+#include <wspiapi.h>   // addrinfo
+#else
+#include <windows.h>
+#include <winsock.h>
+typedef int socklen_t;
+#endif
+
+#ifndef NI_MAXSERV
+# define NI_MAXSERV 32
+#endif
+
+static void mongo_clear_errors( mongo *conn ) {
+    conn->err = 0;
+    memset( conn->errstr, 0, MONGO_ERR_LEN );
+}
+
+int mongo_env_close_socket( int socket ) {
+    return closesocket( socket );
+}
+
+int mongo_env_write_socket( mongo *conn, const void *buf, int len ) {
+    const char *cbuf = buf;
+    int flags = 0;
+
+    while ( len ) {
+        int sent = send( conn->sock, cbuf, len, flags );
+        if ( sent == -1 ) {
+            __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() );
+            conn->connected = 0;
+            return MONGO_ERROR;
+        }
+        cbuf += sent;
+        len -= sent;
+    }
+
+    return MONGO_OK;
+}
+
+int mongo_env_read_socket( mongo *conn, void *buf, int len ) {
+    char *cbuf = buf;
+
+    while ( len ) {
+        int sent = recv( conn->sock, cbuf, len, 0 );
+        if ( sent == 0 || sent == -1 ) {
+            __mongo_set_error( conn, MONGO_IO_ERROR, NULL, WSAGetLastError() );
+            return MONGO_ERROR;
+        }
+        cbuf += sent;
+        len -= sent;
+    }
+
+    return MONGO_OK;
+}
+
+int mongo_env_set_socket_op_timeout( mongo *conn, int millis ) {
+    if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&millis,
+                     sizeof( millis ) ) == -1 ) {
+        __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_RCVTIMEO failed.",
+                           WSAGetLastError() );
+        return MONGO_ERROR;
+    }
+
+    if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&millis,
+                     sizeof( millis ) ) == -1 ) {
+        __mongo_set_error( conn, MONGO_IO_ERROR, "setsockopt SO_SNDTIMEO failed.",
+                           WSAGetLastError() );
+        return MONGO_ERROR;
+    }
+
+    return MONGO_OK;
+}
+
+int mongo_env_socket_connect( mongo *conn, const char *host, int port ) {
+    char port_str[NI_MAXSERV];
+    char errstr[MONGO_ERR_LEN];
+    int status;
+
+    struct addrinfo ai_hints;
+    struct addrinfo *ai_list = NULL;
+    struct addrinfo *ai_ptr = NULL;
+
+    conn->sock = 0;
+    conn->connected = 0;
+
+    bson_sprintf( port_str, "%d", port );
+
+    memset( &ai_hints, 0, sizeof( ai_hints ) );
+    ai_hints.ai_family = AF_UNSPEC;
+    ai_hints.ai_socktype = SOCK_STREAM;
+    ai_hints.ai_protocol = IPPROTO_TCP;
+
+    status = getaddrinfo( host, port_str, &ai_hints, &ai_list );
+    if ( status != 0 ) {
+        bson_sprintf( errstr, "getaddrinfo failed with error %d", status );
+        __mongo_set_error( conn, MONGO_CONN_ADDR_FAIL, errstr, WSAGetLastError() );
+        return MONGO_ERROR;
+    }
+
+    for ( ai_ptr = ai_list; ai_ptr != NULL; ai_ptr = ai_ptr->ai_next ) {
+        conn->sock = socket( ai_ptr->ai_family, ai_ptr->ai_socktype,
+                             ai_ptr->ai_protocol );
+
+        if ( conn->sock < 0 ) {
+            __mongo_set_error( conn, MONGO_SOCKET_ERROR, "socket() failed",
+                               WSAGetLastError() );
+            conn->sock = 0;
+            continue;
+        }
+
+        status = connect( conn->sock, ai_ptr->ai_addr, ai_ptr->ai_addrlen );
+        if ( status != 0 ) {
+            __mongo_set_error( conn, MONGO_SOCKET_ERROR, "connect() failed",
+                           WSAGetLastError() );
+            mongo_env_close_socket( conn->sock );
+            conn->sock = 0;
+            continue;
+        }
+
+        if ( ai_ptr->ai_protocol == IPPROTO_TCP ) {
+            int flag = 1;
+
+            setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY,
+                        ( void * ) &flag, sizeof( flag ) );
+
+            if ( conn->op_timeout_ms > 0 )
+                mongo_env_set_socket_op_timeout( conn, conn->op_timeout_ms );
+        }
+
+        conn->connected = 1;
+        break;
+    }
+
+    freeaddrinfo( ai_list );
+
+    if ( ! conn->connected ) {
+        conn->err = MONGO_CONN_FAIL;
+        return MONGO_ERROR;
+    } 
+    else {
+        mongo_clear_errors( conn );
+        return MONGO_OK;
+    }
+}
+
+MONGO_EXPORT int mongo_env_sock_init( void ) {
+
+    WSADATA wsaData;
+    WORD wVers;
+    static int called_once;
+    static int retval;
+
+    if (called_once) return retval;
+
+    called_once = 1;
+    wVers = MAKEWORD(1, 1);
+    retval = (WSAStartup(wVers, &wsaData) == 0);
+
+    return retval;
+}
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.c
index f51b397d3f..9b2d1455ef 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.c
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.c
@@ -1,6 +1,6 @@
 /* gridfs.c */
 
-/*    Copyright 2009-2011 10gen Inc.
+/*    Copyright 2009-2012 10gen Inc.
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -21,6 +21,27 @@
 #include <string.h>
 #include <assert.h>
 
+MONGO_EXPORT gridfs* gridfs_create() {
+    return (gridfs*)bson_malloc(sizeof(gridfs));
+}
+
+MONGO_EXPORT void gridfs_dispose(gridfs* gfs) {
+    free(gfs);
+}
+
+MONGO_EXPORT gridfile* gridfile_create() {
+    return (gridfile*)bson_malloc(sizeof(gridfile));
+}
+
+MONGO_EXPORT void gridfile_dispose(gridfile* gf) {
+    free(gf);
+}
+
+MONGO_EXPORT void gridfile_get_descriptor(gridfile* gf, bson* out) {
+    *out = *gf->meta;
+}
+
+
 static bson *chunk_new( bson_oid_t id, int chunkNumber,
                         const char *data, int len ) {
     bson *b = bson_malloc( sizeof( bson ) );
@@ -104,7 +125,7 @@ int gridfs_init( mongo *client, const char *dbname, const char *prefix,
     return MONGO_OK;
 }
 
-void gridfs_destroy( gridfs *gfs ) {
+MONGO_EXPORT void gridfs_destroy( gridfs *gfs ) {
     if ( gfs == NULL ) return;
     if ( gfs->dbname ) bson_free( ( char * )gfs->dbname );
     if ( gfs->prefix ) bson_free( ( char * )gfs->prefix );
@@ -120,14 +141,17 @@ static int gridfs_insert_file( gridfs *gfs, const char *name,
     bson res;
     bson_iterator it;
     int result;
+    int64_t d;
 
     /* Check run md5 */
     bson_init( &command );
     bson_append_oid( &command, "filemd5", &id );
     bson_append_string( &command, "root", gfs->prefix );
     bson_finish( &command );
-    assert( mongo_run_command( gfs->client, gfs->dbname, &command, &res ) == MONGO_OK );
+    result = mongo_run_command( gfs->client, gfs->dbname, &command, &res );
     bson_destroy( &command );
+    if (result != MONGO_OK)
+        return result;
 
     /* Create and insert BSON for file metadata */
     bson_init( &ret );
@@ -137,7 +161,8 @@ static int gridfs_insert_file( gridfs *gfs, const char *name,
     }
     bson_append_long( &ret, "length", length );
     bson_append_int( &ret, "chunkSize", DEFAULT_CHUNK_SIZE );
-    bson_append_date( &ret, "uploadDate", ( bson_date_t )1000*time( NULL ) );
+    d = ( bson_date_t )1000*time( NULL );
+    bson_append_date( &ret, "uploadDate", d);
     bson_find( &it, &res, "md5" );
     bson_append_string( &ret, "md5", bson_iterator_string( &it ) );
     bson_destroy( &res );
@@ -151,7 +176,7 @@ static int gridfs_insert_file( gridfs *gfs, const char *name,
     return result;
 }
 
-int gridfs_store_buffer( gridfs *gfs, const char *data,
+MONGO_EXPORT int gridfs_store_buffer( gridfs *gfs, const char *data,
                           gridfs_offset length, const char *remotename,
                           const char *contenttype ) {
 
@@ -163,7 +188,7 @@ int gridfs_store_buffer( gridfs *gfs, const char *data,
     bson *oChunk;
 
     /* Large files Assertion */
-    assert( length <= 0xffffffff );
+    /* assert( length <= 0xffffffff ); */
 
     /* Generate and append an oid*/
     bson_oid_gen( &id );
@@ -183,7 +208,7 @@ int gridfs_store_buffer( gridfs *gfs, const char *data,
     return gridfs_insert_file( gfs, remotename, id, length, contenttype );
 }
 
-void gridfile_writer_init( gridfile *gfile, gridfs *gfs,
+MONGO_EXPORT void gridfile_writer_init( gridfile *gfile, gridfs *gfs,
                            const char *remote_name, const char *content_type ) {
     gfile->gfs = gfs;
 
@@ -200,7 +225,7 @@ void gridfile_writer_init( gridfile *gfile, gridfs *gfs,
     strcpy( ( char * )gfile->content_type, content_type );
 }
 
-void gridfile_write_buffer( gridfile *gfile, const char *data,
+MONGO_EXPORT void gridfile_write_buffer( gridfile *gfile, const char *data,
     gridfs_offset length ) {
 
     int bytes_left = 0;
@@ -221,14 +246,13 @@ void gridfile_write_buffer( gridfile *gfile, const char *data,
         gfile->pending_len += length;
 
     } else { /* At least one chunk of data to write */
+        chunks_to_write = to_write / DEFAULT_CHUNK_SIZE;
+        bytes_left = to_write % DEFAULT_CHUNK_SIZE;
 
         /* If there's a pending chunk to be written, we need to combine
          * the buffer provided up to DEFAULT_CHUNK_SIZE.
          */
         if ( gfile->pending_len > 0 ) {
-            chunks_to_write = to_write / DEFAULT_CHUNK_SIZE;
-            bytes_left = to_write % DEFAULT_CHUNK_SIZE;
-
             data_partial_len = DEFAULT_CHUNK_SIZE - gfile->pending_len;
             buffer = ( char * )bson_malloc( DEFAULT_CHUNK_SIZE );
             memcpy( buffer, gfile->pending_data, gfile->pending_len );
@@ -270,7 +294,7 @@ void gridfile_write_buffer( gridfile *gfile, const char *data,
     }
 }
 
-int gridfile_writer_done( gridfile *gfile ) {
+MONGO_EXPORT int gridfile_writer_done( gridfile *gfile ) {
 
     /* write any remaining pending chunk data.
      * pending data will always take up less than one chunk */
@@ -307,8 +331,11 @@ int gridfs_store_file( gridfs *gfs, const char *filename,
 
     /* Open the file and the correct stream */
     if ( strcmp( filename, "-" ) == 0 ) fd = stdin;
-    else fd = fopen( filename, "rb" );
-    assert( fd != NULL ); /* No such file */
+    else {
+        fd = fopen( filename, "rb" );
+        if (fd == NULL)
+            return MONGO_ERROR;
+    }
 
     /* Generate and append an oid*/
     bson_oid_gen( &id );
@@ -339,7 +366,7 @@ int gridfs_store_file( gridfs *gfs, const char *filename,
     return gridfs_insert_file( gfs, remotename, id, length, contenttype );
 }
 
-void gridfs_remove_filename( gridfs *gfs, const char *filename ) {
+MONGO_EXPORT void gridfs_remove_filename( gridfs *gfs, const char *filename ) {
     bson query;
     mongo_cursor *files;
     bson file;
@@ -433,7 +460,7 @@ int gridfile_init( gridfs *gfs, bson *meta, gridfile *gfile )
     return MONGO_OK;
 }
 
-void gridfile_destroy( gridfile *gfile )
+MONGO_EXPORT void gridfile_destroy( gridfile *gfile )
 
 {
     bson_destroy( gfile->meta );
@@ -444,21 +471,21 @@ bson_bool_t gridfile_exists( gridfile *gfile ) {
     return ( bson_bool_t )( gfile != NULL || gfile->meta == NULL );
 }
 
-const char *gridfile_get_filename( gridfile *gfile ) {
+MONGO_EXPORT const char *gridfile_get_filename( gridfile *gfile ) {
     bson_iterator it;
 
     bson_find( &it, gfile->meta, "filename" );
     return bson_iterator_string( &it );
 }
 
-int gridfile_get_chunksize( gridfile *gfile ) {
+MONGO_EXPORT int gridfile_get_chunksize( gridfile *gfile ) {
     bson_iterator it;
 
     bson_find( &it, gfile->meta, "chunkSize" );
     return bson_iterator_int( &it );
 }
 
-gridfs_offset gridfile_get_contentlength( gridfile *gfile ) {
+MONGO_EXPORT gridfs_offset gridfile_get_contentlength( gridfile *gfile ) {
     bson_iterator it;
 
     bson_find( &it, gfile->meta, "length" );
@@ -469,7 +496,7 @@ gridfs_offset gridfile_get_contentlength( gridfile *gfile ) {
         return ( gridfs_offset )bson_iterator_long( &it );
 }
 
-const char *gridfile_get_contenttype( gridfile *gfile ) {
+MONGO_EXPORT const char *gridfile_get_contenttype( gridfile *gfile ) {
     bson_iterator it;
 
     if ( bson_find( &it, gfile->meta, "contentType" ) )
@@ -477,14 +504,14 @@ const char *gridfile_get_contenttype( gridfile *gfile ) {
     else return NULL;
 }
 
-bson_date_t gridfile_get_uploaddate( gridfile *gfile ) {
+MONGO_EXPORT bson_date_t gridfile_get_uploaddate( gridfile *gfile ) {
     bson_iterator it;
 
     bson_find( &it, gfile->meta, "uploadDate" );
     return bson_iterator_date( &it );
 }
 
-const char *gridfile_get_md5( gridfile *gfile ) {
+MONGO_EXPORT const char *gridfile_get_md5( gridfile *gfile ) {
     bson_iterator it;
 
     bson_find( &it, gfile->meta, "md5" );
@@ -505,20 +532,16 @@ bson_bool_t gridfile_get_boolean( gridfile *gfile, const char *name ) {
     return bson_iterator_bool( &it );
 }
 
-bson gridfile_get_metadata( gridfile *gfile ) {
-    bson sub;
+MONGO_EXPORT void gridfile_get_metadata( gridfile *gfile, bson* out ) {
     bson_iterator it;
 
-    if ( bson_find( &it, gfile->meta, "metadata" ) ) {
-        bson_iterator_subobject( &it, &sub );
-        return sub;
-    } else {
-        bson_empty( &sub );
-        return sub;
-    }
+    if ( bson_find( &it, gfile->meta, "metadata" ) )
+        bson_iterator_subobject( &it, out );
+    else
+        bson_empty( out );
 }
 
-int gridfile_get_numchunks( gridfile *gfile ) {
+MONGO_EXPORT int gridfile_get_numchunks( gridfile *gfile ) {
     bson_iterator it;
     gridfs_offset length;
     gridfs_offset chunkSize;
@@ -539,11 +562,12 @@ int gridfile_get_numchunks( gridfile *gfile ) {
            : ( int )( numchunks );
 }
 
-bson gridfile_get_chunk( gridfile *gfile, int n ) {
+MONGO_EXPORT void gridfile_get_chunk( gridfile *gfile, int n, bson* out ) {
     bson query;
-    bson out;
+    
     bson_iterator it;
     bson_oid_t id;
+    int result;
 
     bson_init( &query );
     bson_find( &it, gfile->meta, "_id" );
@@ -552,15 +576,18 @@ bson gridfile_get_chunk( gridfile *gfile, int n ) {
     bson_append_int( &query, "n", n );
     bson_finish( &query );
 
-    assert( mongo_find_one( gfile->gfs->client,
-                            gfile->gfs->chunks_ns,
-                            &query, NULL, &out ) == MONGO_OK );
-
+    result = (mongo_find_one(gfile->gfs->client,
+                             gfile->gfs->chunks_ns,
+                             &query, NULL, out ) == MONGO_OK );
     bson_destroy( &query );
-    return out;
+    if (!result) {
+        bson empty;
+        bson_empty(&empty);
+        bson_copy(out, &empty);
+    }
 }
 
-mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ) {
+MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size ) {
     bson_iterator it;
     bson_oid_t id;
     bson gte;
@@ -613,18 +640,18 @@ gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream ) {
     const int num = gridfile_get_numchunks( gfile );
 
     for ( i=0; i<num; i++ ) {
-        chunk = gridfile_get_chunk( gfile, i );
+        gridfile_get_chunk( gfile, i, &chunk );
         bson_find( &it, &chunk, "data" );
         len = bson_iterator_bin_len( &it );
         data = bson_iterator_bin_data( &it );
-        fwrite( data , sizeof( char ), len, stream );
+        fwrite( data, sizeof( char ), len, stream );
         bson_destroy( &chunk );
     }
 
     return gridfile_get_contentlength( gfile );
 }
 
-gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ) {
+MONGO_EXPORT gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ) {
     mongo_cursor *chunks;
     bson chunk;
 
@@ -676,7 +703,7 @@ gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf ) {
     return size;
 }
 
-gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset ) {
+MONGO_EXPORT gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset ) {
     gridfs_offset length;
 
     length = gridfile_get_contentlength( gfile );
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.h
index 36595ee341..d313e1afd8 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.h
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/gridfs.h
@@ -4,7 +4,7 @@
  *
  * */
 
-/*    Copyright 2009-2011 10gen Inc.
+/*    Copyright 2009-2012 10gen Inc.
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -21,8 +21,8 @@
 
 #include "mongo.h"
 
-#ifndef GRIDFS_INCLUDED
-#define GRIDFS_INCLUDED
+#ifndef MONGO_GRIDFS_H_
+#define MONGO_GRIDFS_H_
 
 enum {DEFAULT_CHUNK_SIZE = 256 * 1024};
 
@@ -51,6 +51,12 @@ typedef struct {
     int pending_len;    /**> Length of pending_data buffer */
 } gridfile;
 
+MONGO_EXPORT gridfs* gridfs_create();
+MONGO_EXPORT void gridfs_dispose(gridfs* gfs);
+MONGO_EXPORT gridfile* gridfile_create();
+MONGO_EXPORT void gridfile_dispose(gridfile* gf);
+MONGO_EXPORT void gridfile_get_descriptor(gridfile* gf, bson* out);
+
 /**
  *  Initializes a GridFS object
  *  @param client - db connection
@@ -60,7 +66,7 @@ typedef struct {
  *
  *  @return - MONGO_OK or MONGO_ERROR.
  */
-int gridfs_init( mongo *client, const char *dbname,
+MONGO_EXPORT int gridfs_init( mongo *client, const char *dbname,
                  const char *prefix, gridfs *gfs );
 
 /**
@@ -69,7 +75,7 @@ int gridfs_init( mongo *client, const char *dbname,
  *
  * @param gfs a grid
  */
-void gridfs_destroy( gridfs *gfs );
+MONGO_EXPORT void gridfs_destroy( gridfs *gfs );
 
 /**
  *  Initializes a gridfile for writing incrementally with gridfs_write_buffer.
@@ -77,7 +83,7 @@ void gridfs_destroy( gridfs *gfs );
  *  When done, you must call gridfs_writer_done to save the file metadata.
  *
  */
-void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name,
+MONGO_EXPORT void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name,
                            const char *content_type );
 
 /**
@@ -86,7 +92,7 @@ void gridfile_writer_init( gridfile *gfile, gridfs *gfs, const char *remote_name
  *  stream to a GridFS file. When finished, be sure to call gridfs_writer_done.
  *
  */
-void gridfile_write_buffer( gridfile *gfile, const char *data,
+MONGO_EXPORT void gridfile_write_buffer( gridfile *gfile, const char *data,
                             gridfs_offset length );
 
 /**
@@ -96,7 +102,7 @@ void gridfile_write_buffer( gridfile *gfile, const char *data,
  *
  *  @return - MONGO_OK or MONGO_ERROR.
  */
-int gridfile_writer_done( gridfile *gfile );
+MONGO_EXPORT int gridfile_writer_done( gridfile *gfile );
 
 /**
  *  Store a buffer as a GridFS file.
@@ -108,7 +114,7 @@ int gridfile_writer_done( gridfile *gfile );
  *
  *  @return - MONGO_OK or MONGO_ERROR.
  */
-int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length,
+MONGO_EXPORT int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length,
                           const char *remotename,
                           const char *contenttype );
 
@@ -121,7 +127,7 @@ int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length,
  *
  *  @return - MONGO_OK or MONGO_ERROR.
  */
-int gridfs_store_file( gridfs *gfs, const char *filename,
+MONGO_EXPORT int gridfs_store_file( gridfs *gfs, const char *filename,
                         const char *remotename, const char *contenttype );
 
 /**
@@ -129,7 +135,7 @@ int gridfs_store_file( gridfs *gfs, const char *filename,
  *  @param gfs - the working GridFS
  *  @param filename - the filename of the file/s to be removed
  */
-void gridfs_remove_filename( gridfs *gfs, const char *filename );
+MONGO_EXPORT void gridfs_remove_filename( gridfs *gfs, const char *filename );
 
 /**
  *  Find the first file matching the provided query within the
@@ -141,7 +147,7 @@ void gridfs_remove_filename( gridfs *gfs, const char *filename );
  *
  *  @return MONGO_OK if successful, MONGO_ERROR otherwise
  */
-int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile );
+MONGO_EXPORT int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile );
 
 /**
  *  Find the first file referenced by filename within the GridFS
@@ -152,7 +158,7 @@ int gridfs_find_query( gridfs *gfs, bson *query, gridfile *gfile );
  *
  *  @return MONGO_OK or MONGO_ERROR.
  */
-int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile );
+MONGO_EXPORT int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile );
 
 /**
  *  Initializes a GridFile containing the GridFS and file bson
@@ -162,20 +168,20 @@ int gridfs_find_filename( gridfs *gfs, const char *filename, gridfile *gfile );
  *
  *  @return - MONGO_OK or MONGO_ERROR.
  */
-int gridfile_init( gridfs *gfs, bson *meta, gridfile *gfile );
+MONGO_EXPORT int gridfile_init( gridfs *gfs, bson *meta, gridfile *gfile );
 
 /**
  *  Destroys the GridFile
  *
  *  @param oGridFIle - the GridFile being destroyed
  */
-void gridfile_destroy( gridfile *gfile );
+MONGO_EXPORT void gridfile_destroy( gridfile *gfile );
 
 /**
  *  Returns whether or not the GridFile exists
  *  @param gfile - the GridFile being examined
  */
-bson_bool_t gridfile_exists( gridfile *gfile );
+MONGO_EXPORT bson_bool_t gridfile_exists( gridfile *gfile );
 
 /**
  *  Returns the filename of GridFile
@@ -183,7 +189,7 @@ bson_bool_t gridfile_exists( gridfile *gfile );
  *
  *  @return - the filename of the Gridfile
  */
-const char *gridfile_get_filename( gridfile *gfile );
+MONGO_EXPORT const char *gridfile_get_filename( gridfile *gfile );
 
 /**
  *  Returns the size of the chunks of the GridFile
@@ -191,7 +197,7 @@ const char *gridfile_get_filename( gridfile *gfile );
  *
  *  @return - the size of the chunks of the Gridfile
  */
-int gridfile_get_chunksize( gridfile *gfile );
+MONGO_EXPORT int gridfile_get_chunksize( gridfile *gfile );
 
 /**
  *  Returns the length of GridFile's data
@@ -200,7 +206,7 @@ int gridfile_get_chunksize( gridfile *gfile );
  *
  *  @return - the length of the Gridfile's data
  */
-gridfs_offset gridfile_get_contentlength( gridfile *gfile );
+MONGO_EXPORT gridfs_offset gridfile_get_contentlength( gridfile *gfile );
 
 /**
  *  Returns the MIME type of the GridFile
@@ -210,7 +216,7 @@ gridfs_offset gridfile_get_contentlength( gridfile *gfile );
  *  @return - the MIME type of the Gridfile
  *            (NULL if no type specified)
  */
-const char *gridfile_get_contenttype( gridfile *gfile );
+MONGO_EXPORT const char *gridfile_get_contenttype( gridfile *gfile );
 
 /**
  *  Returns the upload date of GridFile
@@ -219,7 +225,7 @@ const char *gridfile_get_contenttype( gridfile *gfile );
  *
  *  @return - the upload date of the Gridfile
  */
-bson_date_t gridfile_get_uploaddate( gridfile *gfile );
+MONGO_EXPORT bson_date_t gridfile_get_uploaddate( gridfile *gfile );
 
 /**
  *  Returns the MD5 of GridFile
@@ -228,7 +234,7 @@ bson_date_t gridfile_get_uploaddate( gridfile *gfile );
  *
  *  @return - the MD5 of the Gridfile
  */
-const char *gridfile_get_md5( gridfile *gfile );
+MONGO_EXPORT const char *gridfile_get_md5( gridfile *gfile );
 
 /**
  *  Returns the field in GridFile specified by name
@@ -260,7 +266,7 @@ bson_bool_t gridfile_get_boolean( gridfile *gfile,
  *  @return - the metadata of the Gridfile in a bson object
  *            (an empty bson is returned if none exists)
  */
-bson gridfile_get_metadata( gridfile *gfile );
+MONGO_EXPORT void gridfile_get_metadata( gridfile *gfile, bson* out );
 
 /**
  *  Returns the number of chunks in the GridFile
@@ -268,7 +274,7 @@ bson gridfile_get_metadata( gridfile *gfile );
  *
  *  @return - the number of chunks in the Gridfile
  */
-int gridfile_get_numchunks( gridfile *gfile );
+MONGO_EXPORT int gridfile_get_numchunks( gridfile *gfile );
 
 /**
  *  Returns chunk n of GridFile
@@ -276,7 +282,7 @@ int gridfile_get_numchunks( gridfile *gfile );
  *
  *  @return - the nth chunk of the Gridfile
  */
-bson gridfile_get_chunk( gridfile *gfile, int n );
+MONGO_EXPORT void gridfile_get_chunk( gridfile *gfile, int n, bson* out );
 
 /**
  *  Returns a mongo_cursor of *size* chunks starting with chunk *start*
@@ -287,7 +293,7 @@ bson gridfile_get_chunk( gridfile *gfile, int n );
  *
  *  @return - mongo_cursor of the chunks (must be destroyed after use)
  */
-mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size );
+MONGO_EXPORT mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size );
 
 /**
  *  Writes the GridFile to a stream
@@ -295,7 +301,7 @@ mongo_cursor *gridfile_get_chunks( gridfile *gfile, int start, int size );
  *  @param gfile - the working GridFile
  *  @param stream - the file stream to write to
  */
-gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream );
+MONGO_EXPORT gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream );
 
 /**
  *  Reads length bytes from the GridFile to a buffer
@@ -309,7 +315,7 @@ gridfs_offset gridfile_write_file( gridfile *gfile, FILE *stream );
  *
  *  @return - the number of bytes read
  */
-gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf );
+MONGO_EXPORT gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf );
 
 /**
  *  Updates the position in the file
@@ -321,6 +327,6 @@ gridfs_offset gridfile_read( gridfile *gfile, gridfs_offset size, char *buf );
  *
  *  @return - resulting offset location
  */
-gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset );
+MONGO_EXPORT gridfs_offset gridfile_seek( gridfile *gfile, gridfs_offset offset );
 
 #endif
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.c
index d1c1e3ab0b..68edd29513 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.c
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.c
@@ -309,7 +309,7 @@ mongo_md5_process(mongo_md5_state_t *pms, const mongo_md5_byte_t *data /*[64]*/)
     pms->abcd[3] += d;
 }
 
-void
+MONGO_EXPORT void
 mongo_md5_init(mongo_md5_state_t *pms)
 {
     pms->count[0] = pms->count[1] = 0;
@@ -319,7 +319,7 @@ mongo_md5_init(mongo_md5_state_t *pms)
     pms->abcd[3] = 0x10325476;
 }
 
-void
+MONGO_EXPORT void
 mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes)
 {
     const mongo_md5_byte_t *p = data;
@@ -357,7 +357,7 @@ mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbyte
 	memcpy(pms->buf, p, left);
 }
 
-void
+MONGO_EXPORT void
 mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16])
 {
     static const mongo_md5_byte_t pad[64] = {
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.h
index 540da3a584..342b6a7307 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.h
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/md5.h
@@ -47,8 +47,8 @@
   1999-05-03 lpd Original version.
  */
 
-#ifndef md5_INCLUDED
-#  define md5_INCLUDED
+#ifndef MONGO_MD5_H_
+#define MONGO_MD5_H_
 
 /*
  * This package supports both compile-time and run-time determination of CPU
@@ -59,6 +59,7 @@
  * run on either big- or little-endian CPUs, but will run slightly less
  * efficiently on either one than if ARCH_IS_BIG_ENDIAN is defined.
  */
+#include "bson.h"
 
 typedef unsigned char mongo_md5_byte_t; /* 8-bit byte */
 typedef unsigned int mongo_md5_word_t; /* 32-bit word */
@@ -75,17 +76,17 @@ extern "C"
 {
 #endif
 
-    /* Initialize the algorithm. */
-    void mongo_md5_init(mongo_md5_state_t *pms);
+/* Initialize the algorithm. */
+MONGO_EXPORT void mongo_md5_init(mongo_md5_state_t *pms);
 
-    /* Append a string to the message. */
-    void mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes);
+/* Append a string to the message. */
+MONGO_EXPORT void mongo_md5_append(mongo_md5_state_t *pms, const mongo_md5_byte_t *data, int nbytes);
 
-    /* Finish the message and return the digest. */
-    void mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]);
+/* Finish the message and return the digest. */
+MONGO_EXPORT void mongo_md5_finish(mongo_md5_state_t *pms, mongo_md5_byte_t digest[16]);
 
 #ifdef __cplusplus
 }  /* end extern "C" */
 #endif
 
-#endif /* md5_INCLUDED */
+#endif /* MONGO_MD5_H_ */
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.c
index 2090e74312..eb16392297 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.c
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.c
@@ -1,6 +1,6 @@
 /* mongo.c */
 
-/*    Copyright 2009-2011 10gen Inc.
+/*    Copyright 2009-2012 10gen Inc.
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -17,19 +17,235 @@
 
 #include "mongo.h"
 #include "md5.h"
+#include "env.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 
-#ifdef _USE_LINUX_SYSTEM
-#include "platform/linux/net.h"
-#elif defined _USE_CUSTOM_SYSTEM
-#include "platform/custom/net.h"
-#else
-#include "net.h"
-#endif
+MONGO_EXPORT mongo* mongo_create() {
+    return (mongo*)bson_malloc(sizeof(mongo));
+}
+
+
+MONGO_EXPORT void mongo_dispose(mongo* conn) {
+    free(conn);
+}
+
+MONGO_EXPORT int mongo_get_err(mongo* conn) {
+    return conn->err;
+}
+
+
+MONGO_EXPORT int mongo_is_connected(mongo* conn) {
+    return conn->connected != 0;
+}
+
+
+MONGO_EXPORT int mongo_get_op_timeout(mongo* conn) {
+    return conn->op_timeout_ms;
+}
+
+
+const char* _get_host_port(mongo_host_port* hp) {
+    static char _hp[sizeof(hp->host)+12];
+    bson_sprintf(_hp, "%s:%d", hp->host, hp->port);
+    return _hp;
+}
+
+
+MONGO_EXPORT const char* mongo_get_primary(mongo* conn) {
+    mongo* conn_ = (mongo*)conn;
+    return _get_host_port(conn_->primary);
+}
+
+
+MONGO_EXPORT int mongo_get_socket(mongo* conn) {
+    mongo* conn_ = (mongo*)conn;
+    return conn_->sock;
+}
+
+
+MONGO_EXPORT int mongo_get_host_count(mongo* conn) {
+    mongo_replset* r = conn->replset;
+    mongo_host_port* hp;
+    int count = 0;
+    if (!r) return 0;
+    for (hp = r->hosts; hp; hp = hp->next)
+        ++count;
+    return count;
+}
+
+
+MONGO_EXPORT const char* mongo_get_host(mongo* conn, int i) {
+    mongo_replset* r = conn->replset;
+    mongo_host_port* hp;
+    int count = 0;
+    if (!r) return 0;
+    for (hp = r->hosts; hp; hp = hp->next) {
+        if (count == i)
+            return _get_host_port(hp);
+        ++count;
+    }
+    return 0;
+}
+
+
+MONGO_EXPORT mongo_cursor* mongo_cursor_create() {
+    return (mongo_cursor*)bson_malloc(sizeof(mongo_cursor));
+}
+
+
+MONGO_EXPORT void mongo_cursor_dispose(mongo_cursor* cursor) {
+    free(cursor);
+}
+
+
+MONGO_EXPORT int  mongo_get_server_err(mongo* conn) {
+    return conn->lasterrcode;
+}
+
+
+MONGO_EXPORT const char*  mongo_get_server_err_string(mongo* conn) {
+    return conn->lasterrstr;
+}
+
+MONGO_EXPORT void __mongo_set_error( mongo *conn, mongo_error_t err, const char *str,
+                               int errcode ) {
+    int errstr_size, str_size;
+
+    conn->err = err;
+    conn->errcode = errcode;
+
+    if( str ) {
+        str_size = strlen( str ) + 1;
+        errstr_size = str_size > MONGO_ERR_LEN ? MONGO_ERR_LEN : str_size;
+        memcpy( conn->errstr, str, errstr_size );
+        conn->errstr[errstr_size] = '\0';
+    }
+}
+
+MONGO_EXPORT void mongo_clear_errors( mongo *conn ) {
+    conn->err = 0;
+    conn->errcode = 0;
+    conn->lasterrcode = 0;
+    memset( conn->errstr, 0, MONGO_ERR_LEN );
+    memset( conn->lasterrstr, 0, MONGO_ERR_LEN );
+}
+
+MONGO_EXPORT int mongo_validate_ns( mongo *conn, const char *ns ) {
+    char *last = NULL;
+    char *current = NULL;
+    const char *db_name = ns;
+    char *collection_name = NULL;
+    char errmsg[64];
+    int ns_len = 0;
+
+    /* If the first character is a '.', fail. */
+    if( *ns == '.' ) {
+        __mongo_set_error( conn, MONGO_NS_INVALID, "ns cannot start with a '.'.", 0 );
+        return MONGO_ERROR;
+    }
+
+    /* Find the division between database and collection names. */
+    for( current = (char *)ns; *current != '\0'; current++ ) {
+        if( *current == '.' ) {
+            current++;
+            break;
+        }
+    }
+
+    /* Fail because the ns doesn't contain a '.'
+     * or the collection part starts with a dot. */
+    if( *current == '\0' || *current == '.' ) {
+        __mongo_set_error( conn, MONGO_NS_INVALID, "ns cannot start with a '.'.", 0 );
+        return MONGO_ERROR;
+    }
+
+    /* Fail if collection length is 0. */
+    if( *(current + 1) == '\0' ) {
+        __mongo_set_error( conn, MONGO_NS_INVALID, "Collection name missing.", 0 );
+        return MONGO_ERROR;
+    }
+
+
+    /* Point to the beginning of the collection name. */
+    collection_name = current;
+
+    /* Ensure that the database name is greater than one char.*/
+    if( collection_name - 1 == db_name ) {
+        __mongo_set_error( conn, MONGO_NS_INVALID, "Database name missing.", 0 );
+        return MONGO_ERROR;
+    }
+
+    /* Go back and validate the database name. */
+    for( current = (char *)db_name; *current != '.'; current++ ) {
+        switch( *current ) {
+            case ' ':
+            case '$':
+            case '/':
+            case '\\':
+                __mongo_set_error( conn, MONGO_NS_INVALID,
+                    "Database name may not contain ' ', '$', '/', or '\\'", 0 );
+                return MONGO_ERROR;
+            default:
+                break;
+        }
+
+        ns_len++;
+    }
+
+    /* Add one to the length for the '.' character. */
+    ns_len++;
+
+    /* Now validate the collection name. */
+    for( current = collection_name; *current != '\0'; current++ ) {
+
+        /* Cannot have two consecutive dots. */
+        if( last && *last == '.' && *current == '.' ) {
+                __mongo_set_error( conn, MONGO_NS_INVALID,
+                    "Collection may not contain two consecutive '.'", 0 );
+            return MONGO_ERROR;
+        }
+
+        /* Cannot contain a '$' */
+        if( *current == '$' ) {
+            __mongo_set_error( conn, MONGO_NS_INVALID,
+                "Collection may not contain '$'", 0 );
+            return MONGO_ERROR;
+        }
+
+        last = current;
+        ns_len++;
+    }
+
+    if( ns_len > 128 ) {
+        bson_sprintf( errmsg, "Namespace too long; has %d but must <= 128.",
+                      ns_len );
+        __mongo_set_error( conn, MONGO_NS_INVALID, errmsg, 0 );
+        return MONGO_ERROR;
+    }
+
+    /* Cannot end with a '.' */
+    if( *(current - 1) == '.' ) {
+        __mongo_set_error( conn, MONGO_NS_INVALID,
+            "Collection may not end with '.'", 0 );
+        return MONGO_ERROR;
+    }
+
+    return MONGO_OK;
+}
+
+static void mongo_set_last_error( mongo *conn, bson_iterator *it, bson *obj ) {
+    int result_len = bson_iterator_string_len( it );
+    const char *result_string = bson_iterator_string( it );
+    int len = result_len < MONGO_ERR_LEN ? result_len : MONGO_ERR_LEN;
+    memcpy( conn->lasterrstr, result_string, len );
+
+    if( bson_find( it, obj, "code" ) != BSON_NULL )
+        conn->lasterrcode = bson_iterator_int( it );
+}
 
 static const int ZERO = 0;
 static const int ONE = 1;
@@ -57,13 +273,13 @@ int mongo_message_send( mongo *conn, mongo_message *mm ) {
     bson_little_endian32( &head.responseTo, &mm->head.responseTo );
     bson_little_endian32( &head.op, &mm->head.op );
 
-    res = mongo_write_socket( conn, &head, sizeof( head ) );
+    res = mongo_env_write_socket( conn, &head, sizeof( head ) );
     if( res != MONGO_OK ) {
         bson_free( mm );
         return res;
     }
 
-    res = mongo_write_socket( conn, &mm->data, mm->head.len - sizeof( head ) );
+    res = mongo_env_write_socket( conn, &mm->data, mm->head.len - sizeof( head ) );
     if( res != MONGO_OK ) {
         bson_free( mm );
         return res;
@@ -80,8 +296,8 @@ int mongo_read_response( mongo *conn, mongo_reply **reply ) {
     unsigned int len;
     int res;
 
-    mongo_read_socket( conn, &head, sizeof( head ) );
-    mongo_read_socket( conn, &fields, sizeof( fields ) );
+    mongo_env_read_socket( conn, &head, sizeof( head ) );
+    mongo_env_read_socket( conn, &fields, sizeof( fields ) );
 
     bson_little_endian32( &len, &head.len );
 
@@ -100,7 +316,7 @@ int mongo_read_response( mongo *conn, mongo_reply **reply ) {
     bson_little_endian32( &out->fields.start, &fields.start );
     bson_little_endian32( &out->fields.num, &fields.num );
 
-    res = mongo_read_socket( conn, &out->objs, len-sizeof( head )-sizeof( fields ) );
+    res = mongo_env_read_socket( conn, &out->objs, len-sizeof( head )-sizeof( fields ) );
     if( res != MONGO_OK ) {
         bson_free( out );
         return res;
@@ -133,12 +349,17 @@ static int mongo_check_is_master( mongo *conn ) {
     bson out;
     bson_iterator it;
     bson_bool_t ismaster = 0;
+    int max_bson_size = MONGO_DEFAULT_MAX_BSON_SIZE;
 
     out.data = NULL;
 
     if ( mongo_simple_int_command( conn, "admin", "ismaster", 1, &out ) == MONGO_OK ) {
         if( bson_find( &it, &out, "ismaster" ) )
             ismaster = bson_iterator_bool( &it );
+        if( bson_find( &it, &out, "maxBsonObjectSize" ) ) {
+            max_bson_size = bson_iterator_int( &it ); 
+        }
+        conn->max_bson_size = max_bson_size;
     } else {
         return MONGO_ERROR;
     }
@@ -153,25 +374,25 @@ static int mongo_check_is_master( mongo *conn ) {
     }
 }
 
-void mongo_init( mongo *conn ) {
-    conn->replset = NULL;
-    conn->err = 0;
-    conn->errstr = NULL;
-    conn->lasterrcode = 0;
-    conn->lasterrstr = NULL;
-
-    conn->conn_timeout_ms = 0;
-    conn->op_timeout_ms = 0;
+MONGO_EXPORT void mongo_init_sockets( void ) {
+    mongo_env_sock_init();
 }
 
-int mongo_connect( mongo *conn , const char *host, int port ) {
+
+MONGO_EXPORT void mongo_init( mongo *conn ) {
+    memset( conn, 0, sizeof( mongo ) );
+    conn->max_bson_size = MONGO_DEFAULT_MAX_BSON_SIZE;
+}
+
+MONGO_EXPORT int mongo_connect( mongo *conn , const char *host, int port ) {
+    mongo_init( conn );
+
     conn->primary = bson_malloc( sizeof( mongo_host_port ) );
     strncpy( conn->primary->host, host, strlen( host ) + 1 );
     conn->primary->port = port;
     conn->primary->next = NULL;
 
-    mongo_init( conn );
-    if( mongo_socket_connect( conn, host, port ) != MONGO_OK )
+    if( mongo_env_socket_connect( conn, host, port ) != MONGO_OK )
         return MONGO_ERROR;
 
     if( mongo_check_is_master( conn ) != MONGO_OK )
@@ -180,7 +401,7 @@ int mongo_connect( mongo *conn , const char *host, int port ) {
         return MONGO_OK;
 }
 
-void mongo_replset_init( mongo *conn, const char *name ) {
+MONGO_EXPORT void mongo_replset_init( mongo *conn, const char *name ) {
     mongo_init( conn );
 
     conn->replset = bson_malloc( sizeof( mongo_replset ) );
@@ -222,7 +443,7 @@ static void mongo_replset_free_list( mongo_host_port **list ) {
     *list = NULL;
 }
 
-void mongo_replset_add_seed( mongo *conn, const char *host, int port ) {
+MONGO_EXPORT void mongo_replset_add_seed( mongo *conn, const char *host, int port ) {
     mongo_replset_add_node( &conn->replset->seeds, host, port );
 }
 
@@ -291,7 +512,7 @@ static void mongo_replset_check_seed( mongo *conn ) {
 
     bson_destroy( &out );
     bson_destroy( &hosts );
-    mongo_close_socket( conn->sock );
+    mongo_env_close_socket( conn->sock );
     conn->sock = 0;
     conn->connected = 0;
 
@@ -306,6 +527,7 @@ static int mongo_replset_check_host( mongo *conn ) {
     bson_iterator it;
     bson_bool_t ismaster = 0;
     const char *set_name;
+    int max_bson_size = MONGO_DEFAULT_MAX_BSON_SIZE;
 
     out.data = NULL;
 
@@ -313,6 +535,10 @@ static int mongo_replset_check_host( mongo *conn ) {
         if( bson_find( &it, &out, "ismaster" ) )
             ismaster = bson_iterator_bool( &it );
 
+        if( bson_find( &it, &out, "maxBsonObjectSize" ) )
+            max_bson_size = bson_iterator_int( &it ); 
+        conn->max_bson_size = max_bson_size;
+
         if( bson_find( &it, &out, "setName" ) ) {
             set_name = bson_iterator_string( &it );
             if( strcmp( set_name, conn->replset->name ) != 0 ) {
@@ -328,13 +554,13 @@ static int mongo_replset_check_host( mongo *conn ) {
     if( ismaster ) {
         conn->replset->primary_connected = 1;
     } else {
-        mongo_close_socket( conn->sock );
+        mongo_env_close_socket( conn->sock );
     }
 
     return MONGO_OK;
 }
 
-int mongo_replset_connect( mongo *conn ) {
+MONGO_EXPORT int mongo_replset_connect( mongo *conn ) {
 
     int res = 0;
     mongo_host_port *node;
@@ -347,15 +573,12 @@ int mongo_replset_connect( mongo *conn ) {
      */
     node = conn->replset->seeds;
     while( node != NULL ) {
-        res = mongo_socket_connect( conn, ( const char * )&node->host, node->port );
-        if( res != MONGO_OK )
-            return MONGO_ERROR;
-
-        mongo_replset_check_seed( conn );
-
-        if( conn->replset->hosts )
-            break;
-
+        res = mongo_env_socket_connect( conn, ( const char * )&node->host, node->port );
+        if( res == MONGO_OK ) {
+            mongo_replset_check_seed( conn );
+            if( conn->replset->hosts )
+                break;
+        }
         node = node->next;
     }
 
@@ -367,19 +590,22 @@ int mongo_replset_connect( mongo *conn ) {
         node = conn->replset->hosts;
 
         while( node != NULL ) {
-            res = mongo_socket_connect( conn, ( const char * )&node->host, node->port );
+            res = mongo_env_socket_connect( conn, ( const char * )&node->host, node->port );
 
             if( res == MONGO_OK ) {
                 if( mongo_replset_check_host( conn ) != MONGO_OK )
                     return MONGO_ERROR;
 
                 /* Primary found, so return. */
-                else if( conn->replset->primary_connected )
+                else if( conn->replset->primary_connected ) {
+                    strncpy( conn->primary->host, node->host, strlen( node->host ) + 1 );
+                    conn->primary->port = node->port;
                     return MONGO_OK;
+                }
 
                 /* No primary, so close the connection. */
                 else {
-                    mongo_close_socket( conn->sock );
+                    mongo_env_close_socket( conn->sock );
                     conn->sock = 0;
                     conn->connected = 0;
                 }
@@ -394,15 +620,15 @@ int mongo_replset_connect( mongo *conn ) {
     return MONGO_ERROR;
 }
 
-int mongo_set_op_timeout( mongo *conn, int millis ) {
+MONGO_EXPORT int mongo_set_op_timeout( mongo *conn, int millis ) {
     conn->op_timeout_ms = millis;
     if( conn->sock && conn->connected )
-        mongo_set_socket_op_timeout( conn, millis );
+        mongo_env_set_socket_op_timeout( conn, millis );
 
     return MONGO_OK;
 }
 
-int mongo_reconnect( mongo *conn ) {
+MONGO_EXPORT int mongo_reconnect( mongo *conn ) {
     int res;
     mongo_disconnect( conn );
 
@@ -413,10 +639,10 @@ int mongo_reconnect( mongo *conn ) {
         res = mongo_replset_connect( conn );
         return res;
     } else
-        return mongo_socket_connect( conn, conn->primary->host, conn->primary->port );
+        return mongo_env_socket_connect( conn, conn->primary->host, conn->primary->port );
 }
 
-int mongo_check_connection( mongo *conn ) {
+MONGO_EXPORT int mongo_check_connection( mongo *conn ) {
     if( ! conn->connected )
         return MONGO_ERROR;
 
@@ -426,7 +652,7 @@ int mongo_check_connection( mongo *conn ) {
         return MONGO_ERROR;
 }
 
-void mongo_disconnect( mongo *conn ) {
+MONGO_EXPORT void mongo_disconnect( mongo *conn ) {
     if( ! conn->connected )
         return;
 
@@ -436,13 +662,13 @@ void mongo_disconnect( mongo *conn ) {
         conn->replset->hosts = NULL;
     }
 
-    mongo_close_socket( conn->sock );
+    mongo_env_close_socket( conn->sock );
 
     conn->sock = 0;
     conn->connected = 0;
 }
 
-void mongo_destroy( mongo *conn ) {
+MONGO_EXPORT void mongo_destroy( mongo *conn ) {
     mongo_disconnect( conn );
 
     if( conn->replset ) {
@@ -454,17 +680,20 @@ void mongo_destroy( mongo *conn ) {
     }
 
     bson_free( conn->primary );
-    bson_free( conn->errstr );
-    bson_free( conn->lasterrstr );
 
-    conn->err = 0;
-    conn->errstr = NULL;
-    conn->lasterrcode = 0;
-    conn->lasterrstr = NULL;
+    mongo_clear_errors( conn );
 }
 
 /* Determine whether this BSON object is valid for the given operation.  */
-static int mongo_bson_valid( mongo *conn, bson *bson, int write ) {
+static int mongo_bson_valid( mongo *conn, const bson *bson, int write ) {
+    int size;
+
+    size = bson_size( bson );
+    if( size > conn->max_bson_size ) {
+        conn->err = MONGO_BSON_TOO_LARGE;
+        return MONGO_ERROR;
+    }
+
     if( ! bson->finished ) {
         conn->err = MONGO_BSON_NOT_FINISHED;
         return MONGO_ERROR;
@@ -486,20 +715,21 @@ static int mongo_bson_valid( mongo *conn, bson *bson, int write ) {
     }
 
     conn->err = 0;
-    conn->errstr = NULL;
 
     return MONGO_OK;
 }
 
 /* Determine whether this BSON object is valid for the given operation.  */
-static int mongo_cursor_bson_valid( mongo_cursor *cursor, bson *bson ) {
+static int mongo_cursor_bson_valid( mongo_cursor *cursor, const bson *bson ) {
     if( ! bson->finished ) {
-        cursor->err = MONGO_BSON_NOT_FINISHED;
+        cursor->err = MONGO_CURSOR_BSON_ERROR;
+        cursor->conn->err = MONGO_BSON_NOT_FINISHED;
         return MONGO_ERROR;
     }
 
     if( bson->err & BSON_NOT_UTF8 ) {
-        cursor->err = MONGO_BSON_INVALID;
+        cursor->err = MONGO_CURSOR_BSON_ERROR;
+        cursor->conn->err = MONGO_BSON_INVALID;
         return MONGO_ERROR;
     }
 
@@ -508,13 +738,17 @@ static int mongo_cursor_bson_valid( mongo_cursor *cursor, bson *bson ) {
 
 /* MongoDB CRUD API */
 
-int mongo_insert_batch( mongo *conn, const char *ns,
-                        bson **bsons, int count ) {
+MONGO_EXPORT int mongo_insert_batch( mongo *conn, const char *ns,
+                        const bson **bsons, int count ) {
 
-    int size =  16 + 4 + strlen( ns ) + 1;
-    int i;
     mongo_message *mm;
+    int i;
     char *data;
+    int overhead =  16 + 4 + strlen( ns ) + 1;
+    int size = overhead;
+
+    if( mongo_validate_ns( conn, ns ) != MONGO_OK )
+        return MONGO_ERROR;
 
     for( i=0; i<count; i++ ) {
         size += bson_size( bsons[i] );
@@ -522,6 +756,11 @@ int mongo_insert_batch( mongo *conn, const char *ns,
             return MONGO_ERROR;
     }
 
+    if( ( size - overhead ) > conn->max_bson_size ) {
+        conn->err = MONGO_BSON_TOO_LARGE;
+        return MONGO_ERROR;
+    }
+
     mm = mongo_message_create( size , 0 , 0 , MONGO_OP_INSERT );
 
     data = &mm->data;
@@ -535,11 +774,14 @@ int mongo_insert_batch( mongo *conn, const char *ns,
     return mongo_message_send( conn, mm );
 }
 
-int mongo_insert( mongo *conn , const char *ns , bson *bson ) {
+MONGO_EXPORT int mongo_insert( mongo *conn , const char *ns , const bson *bson ) {
 
     char *data;
     mongo_message *mm;
 
+    if( mongo_validate_ns( conn, ns ) != MONGO_OK )
+        return MONGO_ERROR;
+
     /* Make sure that BSON is valid for insert. */
     if( mongo_bson_valid( conn, bson, 1 ) != MONGO_OK ) {
         return MONGO_ERROR;
@@ -559,7 +801,7 @@ int mongo_insert( mongo *conn , const char *ns , bson *bson ) {
     return mongo_message_send( conn, mm );
 }
 
-int mongo_update( mongo *conn, const char *ns, const bson *cond,
+MONGO_EXPORT int mongo_update( mongo *conn, const char *ns, const bson *cond,
                   const bson *op, int flags ) {
 
     char *data;
@@ -590,14 +832,9 @@ int mongo_update( mongo *conn, const char *ns, const bson *cond,
     return mongo_message_send( conn, mm );
 }
 
-int mongo_remove( mongo *conn, const char *ns, const bson *cond ) {
+MONGO_EXPORT int mongo_remove( mongo *conn, const char *ns, const bson *cond ) {
     char *data;
-    mongo_message *mm = mongo_message_create( 16  /* header */
-                        + 4  /* ZERO */
-                        + strlen( ns ) + 1
-                        + 4  /* ZERO */
-                        + bson_size( cond )
-                        , 0 , 0 , MONGO_OP_DELETE );
+    mongo_message *mm;
 
     /* Make sure that the BSON is valid UTF-8.
      * TODO: decide whether to check cond as well.
@@ -606,6 +843,13 @@ int mongo_remove( mongo *conn, const char *ns, const bson *cond ) {
         return MONGO_ERROR;
     }
 
+    mm = mongo_message_create( 16  /* header */
+                              + 4  /* ZERO */
+                              + strlen( ns ) + 1
+                              + 4  /* ZERO */
+                              + bson_size( cond )
+                              , 0 , 0 , MONGO_OP_DELETE );
+
     data = &mm->data;
     data = mongo_data_append32( data, &ZERO );
     data = mongo_data_append( data, ns, strlen( ns ) + 1 );
@@ -621,6 +865,11 @@ static int mongo_cursor_op_query( mongo_cursor *cursor ) {
     bson empty;
     char *data;
     mongo_message *mm;
+    bson temp;
+    bson_iterator it;
+
+    /* Clear any errors. */
+    mongo_clear_errors( cursor->conn );
 
     /* Set up default values for query and fields, if necessary. */
     if( ! cursor->query )
@@ -662,6 +911,15 @@ static int mongo_cursor_op_query( mongo_cursor *cursor ) {
         return MONGO_ERROR;
     }
 
+    if( cursor->reply->fields.num == 1 ) {
+        bson_init_data( &temp, &cursor->reply->objs );
+        if( bson_find( &it, &temp, "$err" ) ) {
+            mongo_set_last_error( cursor->conn, &it, &temp );
+            cursor->err = MONGO_CURSOR_QUERY_FAIL;
+            return MONGO_ERROR;
+        }
+    }
+
     cursor->seen += cursor->reply->fields.num;
     cursor->flags |= MONGO_CURSOR_QUERY_SENT;
     return MONGO_OK;
@@ -719,8 +977,8 @@ static int mongo_cursor_get_more( mongo_cursor *cursor ) {
     }
 }
 
-mongo_cursor *mongo_find( mongo *conn, const char *ns, bson *query,
-                          bson *fields, int limit, int skip, int options ) {
+MONGO_EXPORT mongo_cursor *mongo_find( mongo *conn, const char *ns, const bson *query,
+                          const bson *fields, int limit, int skip, int options ) {
 
     mongo_cursor *cursor = ( mongo_cursor * )bson_malloc( sizeof( mongo_cursor ) );
     mongo_cursor_init( cursor, conn, ns );
@@ -740,13 +998,20 @@ mongo_cursor *mongo_find( mongo *conn, const char *ns, bson *query,
     }
 }
 
-int mongo_find_one( mongo *conn, const char *ns, bson *query,
-                    bson *fields, bson *out ) {
+MONGO_EXPORT int mongo_find_one( mongo *conn, const char *ns, const bson *query,
+                    const bson *fields, bson *out ) {
 
-    mongo_cursor *cursor = mongo_find( conn, ns, query, fields, 1, 0, 0 );
+    mongo_cursor cursor[1];
+    mongo_cursor_init( cursor, conn, ns );
+    mongo_cursor_set_query( cursor, query );
+    mongo_cursor_set_fields( cursor, fields );
+    mongo_cursor_set_limit( cursor, 1 );
 
-    if ( cursor && mongo_cursor_next( cursor ) == MONGO_OK ) {
-        bson_copy_basic( out, &cursor->current );
+    if ( mongo_cursor_next( cursor ) == MONGO_OK ) {
+        bson_init_size( out, bson_size( (bson *)&cursor->current ) );
+        memcpy( out->data, cursor->current.data,
+            bson_size( (bson *)&cursor->current ) );
+        out->finished = 1;
         mongo_cursor_destroy( cursor );
         return MONGO_OK;
     } else {
@@ -755,56 +1020,49 @@ int mongo_find_one( mongo *conn, const char *ns, bson *query,
     }
 }
 
-void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns ) {
+MONGO_EXPORT void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns ) {
+    memset( cursor, 0, sizeof( mongo_cursor ) );
     cursor->conn = conn;
     cursor->ns = ( const char * )bson_malloc( strlen( ns ) + 1 );
     strncpy( ( char * )cursor->ns, ns, strlen( ns ) + 1 );
     cursor->current.data = NULL;
-    cursor->reply = NULL;
-    cursor->flags = 0;
-    cursor->seen = 0;
-    cursor->err = 0;
-    cursor->options = 0;
-    cursor->query = NULL;
-    cursor->fields = NULL;
-    cursor->skip = 0;
-    cursor->limit = 0;
 }
 
-void mongo_cursor_set_query( mongo_cursor *cursor, bson *query ) {
+MONGO_EXPORT void mongo_cursor_set_query( mongo_cursor *cursor, const bson *query ) {
     cursor->query = query;
 }
 
-void mongo_cursor_set_fields( mongo_cursor *cursor, bson *fields ) {
+MONGO_EXPORT void mongo_cursor_set_fields( mongo_cursor *cursor, const bson *fields ) {
     cursor->fields = fields;
 }
 
-void mongo_cursor_set_skip( mongo_cursor *cursor, int skip ) {
+MONGO_EXPORT void mongo_cursor_set_skip( mongo_cursor *cursor, int skip ) {
     cursor->skip = skip;
 }
 
-void mongo_cursor_set_limit( mongo_cursor *cursor, int limit ) {
+MONGO_EXPORT void mongo_cursor_set_limit( mongo_cursor *cursor, int limit ) {
     cursor->limit = limit;
 }
 
-void mongo_cursor_set_options( mongo_cursor *cursor, int options ) {
+MONGO_EXPORT void mongo_cursor_set_options( mongo_cursor *cursor, int options ) {
     cursor->options = options;
 }
 
-const char *mongo_cursor_data( mongo_cursor *cursor ) {
+MONGO_EXPORT const char *mongo_cursor_data( mongo_cursor *cursor ) {
     return cursor->current.data;
 }
 
-const bson *mongo_cursor_bson( mongo_cursor *cursor ) {
+MONGO_EXPORT const bson *mongo_cursor_bson( mongo_cursor *cursor ) {
     return (const bson *)&(cursor->current);
 }
 
-int mongo_cursor_next( mongo_cursor *cursor ) {
+MONGO_EXPORT int mongo_cursor_next( mongo_cursor *cursor ) {
     char *next_object;
     char *message_end;
 
     if( ! ( cursor->flags & MONGO_CURSOR_QUERY_SENT ) )
-        mongo_cursor_op_query( cursor );
+        if( mongo_cursor_op_query( cursor ) != MONGO_OK )
+            return MONGO_ERROR;
 
     if( !cursor->reply )
         return MONGO_ERROR;
@@ -826,7 +1084,7 @@ int mongo_cursor_next( mongo_cursor *cursor ) {
 
     /* first */
     if ( cursor->current.data == NULL ) {
-        bson_init_data( &cursor->current, &cursor->reply->objs );
+        bson_init_finished_data( &cursor->current, &cursor->reply->objs );
         return MONGO_OK;
     }
 
@@ -843,15 +1101,15 @@ int mongo_cursor_next( mongo_cursor *cursor ) {
             return MONGO_ERROR;
         }
 
-        bson_init_data( &cursor->current, &cursor->reply->objs );
+        bson_init_finished_data( &cursor->current, &cursor->reply->objs );
     } else {
-        bson_init_data( &cursor->current, next_object );
+        bson_init_finished_data( &cursor->current, next_object );
     }
 
     return MONGO_OK;
 }
 
-int mongo_cursor_destroy( mongo_cursor *cursor ) {
+MONGO_EXPORT int mongo_cursor_destroy( mongo_cursor *cursor ) {
     int result = MONGO_OK;
 
     if ( !cursor ) return result;
@@ -883,7 +1141,7 @@ int mongo_cursor_destroy( mongo_cursor *cursor ) {
 
 /* MongoDB Helper Functions */
 
-int mongo_create_index( mongo *conn, const char *ns, bson *key, int options, bson *out ) {
+MONGO_EXPORT int mongo_create_index( mongo *conn, const char *ns, const bson *key, int options, bson *out ) {
     bson b;
     bson_iterator it;
     char name[255] = {'_'};
@@ -933,10 +1191,10 @@ bson_bool_t mongo_create_simple_index( mongo *conn, const char *ns, const char *
     return success;
 }
 
-int64_t mongo_count( mongo *conn, const char *db, const char *ns, bson *query ) {
+MONGO_EXPORT double mongo_count( mongo *conn, const char *db, const char *ns, const bson *query ) {
     bson cmd;
     bson out = {NULL, 0};
-    int64_t count = -1;
+    double count = -1;
 
     bson_init( &cmd );
     bson_append_string( &cmd, "count", ns );
@@ -947,7 +1205,7 @@ int64_t mongo_count( mongo *conn, const char *db, const char *ns, bson *query )
     if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) {
         bson_iterator it;
         if( bson_find( &it, &out, "n" ) )
-            count = bson_iterator_long( &it );
+            count = bson_iterator_double( &it );
         bson_destroy( &cmd );
         bson_destroy( &out );
         return count;
@@ -958,38 +1216,51 @@ int64_t mongo_count( mongo *conn, const char *db, const char *ns, bson *query )
     }
 }
 
-int mongo_run_command( mongo *conn, const char *db, bson *command,
+MONGO_EXPORT int mongo_run_command( mongo *conn, const char *db, const bson *command,
                        bson *out ) {
 
+    bson response = {NULL, 0};
     bson fields;
     int sl = strlen( db );
     char *ns = bson_malloc( sl + 5 + 1 ); /* ".$cmd" + nul */
-    int res;
+    int res, success = 0;
 
     strcpy( ns, db );
     strcpy( ns+sl, ".$cmd" );
 
-    res = mongo_find_one( conn, ns, command, bson_empty( &fields ), out );
+    res = mongo_find_one( conn, ns, command, bson_empty( &fields ), &response );
     bson_free( ns );
-    return res;
+
+    if( res != MONGO_OK )
+        return MONGO_ERROR;
+    else {
+        bson_iterator it;
+        if( bson_find( &it, &response, "ok" ) )
+            success = bson_iterator_bool( &it );
+
+        if( !success ) {
+            conn->err = MONGO_COMMAND_FAILED;
+            return MONGO_ERROR;
+        } else {
+            if( out )
+              *out = response;
+            return MONGO_OK;
+        }
+    }
 }
 
-int mongo_simple_int_command( mongo *conn, const char *db,
+MONGO_EXPORT int mongo_simple_int_command( mongo *conn, const char *db,
                               const char *cmdstr, int arg, bson *realout ) {
 
     bson out = {NULL, 0};
     bson cmd;
-    bson_bool_t success = 0;
+    int result;
 
     bson_init( &cmd );
     bson_append_int( &cmd, cmdstr, arg );
     bson_finish( &cmd );
 
-    if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) {
-        bson_iterator it;
-        if( bson_find( &it, &out, "ok" ) )
-            success = bson_iterator_bool( &it );
-    }
+    result = mongo_run_command( conn, db, &cmd, &out );
 
     bson_destroy( &cmd );
 
@@ -998,30 +1269,21 @@ int mongo_simple_int_command( mongo *conn, const char *db,
     else
         bson_destroy( &out );
 
-    if( success )
-        return MONGO_OK;
-    else {
-        conn->err = MONGO_COMMAND_FAILED;
-        return MONGO_ERROR;
-    }
+    return result;
 }
 
-int mongo_simple_str_command( mongo *conn, const char *db,
+MONGO_EXPORT int mongo_simple_str_command( mongo *conn, const char *db,
                               const char *cmdstr, const char *arg, bson *realout ) {
 
     bson out = {NULL, 0};
-    int success = 0;
+    int result;
 
     bson cmd;
     bson_init( &cmd );
     bson_append_string( &cmd, cmdstr, arg );
     bson_finish( &cmd );
 
-    if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) {
-        bson_iterator it;
-        if( bson_find( &it, &out, "ok" ) )
-            success = bson_iterator_bool( &it );
-    }
+    result = mongo_run_command( conn, db, &cmd, &out );
 
     bson_destroy( &cmd );
 
@@ -1030,21 +1292,18 @@ int mongo_simple_str_command( mongo *conn, const char *db,
     else
         bson_destroy( &out );
 
-    if( success )
-        return MONGO_OK;
-    else
-        return MONGO_ERROR;
+    return result;
 }
 
-int mongo_cmd_drop_db( mongo *conn, const char *db ) {
+MONGO_EXPORT int mongo_cmd_drop_db( mongo *conn, const char *db ) {
     return mongo_simple_int_command( conn, db, "dropDatabase", 1, NULL );
 }
 
-int mongo_cmd_drop_collection( mongo *conn, const char *db, const char *collection, bson *out ) {
+MONGO_EXPORT int mongo_cmd_drop_collection( mongo *conn, const char *db, const char *collection, bson *out ) {
     return mongo_simple_str_command( conn, db, "drop", collection, out );
 }
 
-void mongo_cmd_reset_error( mongo *conn, const char *db ) {
+MONGO_EXPORT void mongo_cmd_reset_error( mongo *conn, const char *db ) {
     mongo_simple_int_command( conn, db, "reseterror", 1, NULL );
 }
 
@@ -1055,23 +1314,13 @@ static int mongo_cmd_get_error_helper( mongo *conn, const char *db,
     bson_bool_t haserror = 0;
 
     /* Reset last error codes. */
-    conn->lasterrcode = 0;
-    bson_free( conn->lasterrstr );
-    conn->lasterrstr = NULL;
+    mongo_clear_errors( conn );
 
     /* If there's an error, store its code and string in the connection object. */
     if( mongo_simple_int_command( conn, db, cmdtype, 1, &out ) == MONGO_OK ) {
         bson_iterator it;
         haserror = ( bson_find( &it, &out, "err" ) != BSON_NULL );
-        if( haserror ) {
-            conn->lasterrstr = ( char * )bson_malloc( bson_iterator_string_len( &it ) );
-            if( conn->lasterrstr ) {
-                strcpy( conn->lasterrstr, bson_iterator_string( &it ) );
-            }
-
-            if( bson_find( &it, &out, "code" ) != BSON_NULL )
-                conn->lasterrcode = bson_iterator_int( &it );
-        }
+        if( haserror ) mongo_set_last_error( conn, &it, &out );
     }
 
     if( realout )
@@ -1085,15 +1334,15 @@ static int mongo_cmd_get_error_helper( mongo *conn, const char *db,
         return MONGO_OK;
 }
 
-int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out ) {
+MONGO_EXPORT int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out ) {
     return mongo_cmd_get_error_helper( conn, db, out, "getpreverror" );
 }
 
-int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out ) {
+MONGO_EXPORT int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out ) {
     return mongo_cmd_get_error_helper( conn, db, out, "getlasterror" );
 }
 
-bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *realout ) {
+MONGO_EXPORT bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *realout ) {
     bson out = {NULL,0};
     bson_bool_t ismaster = 0;
 
@@ -1133,7 +1382,7 @@ static void mongo_pass_digest( const char *user, const char *pass, char hex_dige
     digest2hex( digest, hex_digest );
 }
 
-int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass ) {
+MONGO_EXPORT int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass ) {
     bson user_obj;
     bson pass_obj;
     char hex_digest[33];
@@ -1164,12 +1413,12 @@ int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const cha
     return res;
 }
 
-bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass ) {
+MONGO_EXPORT bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass ) {
     bson from_db;
     bson cmd;
     bson out;
     const char *nonce;
-    bson_bool_t success = 0;
+    int result;
 
     mongo_md5_state_t st;
     mongo_md5_byte_t digest[16];
@@ -1200,18 +1449,11 @@ bson_bool_t mongo_cmd_authenticate( mongo *conn, const char *db, const char *use
     bson_finish( &cmd );
 
     bson_destroy( &from_db );
-    /*bson_init( &from_db ); */
-    if( mongo_run_command( conn, db, &cmd, &out ) == MONGO_OK ) {
-        bson_iterator it;
-        if( bson_find( &it, &out, "ok" ) )
-            success = bson_iterator_bool( &it );
-    }
+
+    result = mongo_run_command( conn, db, &cmd, &out );
 
     bson_destroy( &from_db );
     bson_destroy( &cmd );
 
-    if( success )
-        return MONGO_OK;
-    else
-        return MONGO_ERROR;
+    return result;
 }
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.h
index 6f86174101..dd4c4b4f40 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.h
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/mongo.h
@@ -3,7 +3,7 @@
  * @brief Main MongoDB Declarations
  */
 
-/*    Copyright 2009-2011 10gen Inc.
+/*    Copyright 2009-2012 10gen Inc.
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -18,22 +18,26 @@
  *    limitations under the License.
  */
 
-#ifndef _MONGO_H_
-#define _MONGO_H_
+#ifndef MONGO_H_
+#define MONGO_H_
 
 #include "bson.h"
 
 MONGO_EXTERN_C_START
 
 #define MONGO_MAJOR 0
-#define MONGO_MINOR 4
-#define MONGO_PATCH 0
+#define MONGO_MINOR 5
+#define MONGO_PATCH 2
 
 #define MONGO_OK 0
 #define MONGO_ERROR -1
 
 #define MONGO_DEFAULT_PORT 27017
 
+#define MONGO_DEFAULT_MAX_BSON_SIZE 4 * 1024 * 1024
+
+#define MONGO_ERR_LEN 128
+
 typedef enum mongo_error_t {
     MONGO_CONN_SUCCESS = 0,  /**< Connection success! */
     MONGO_CONN_NO_SOCKET,    /**< Could not create a socket. */
@@ -43,15 +47,25 @@ typedef enum mongo_error_t {
     MONGO_CONN_BAD_SET_NAME, /**< Given rs name doesn't match this replica set. */
     MONGO_CONN_NO_PRIMARY,   /**< Can't find primary in replica set. Connection closed. */
 
-    MONGO_IO_ERROR,          /**< An error occurred while reading or writing on socket. */
+    MONGO_IO_ERROR,          /**< An error occurred while reading or writing on the socket. */
+    MONGO_SOCKET_ERROR,      /**< Other socket error. */
     MONGO_READ_SIZE_ERROR,   /**< The response is not the expected length. */
     MONGO_COMMAND_FAILED,    /**< The command returned with 'ok' value of 0. */
+    MONGO_NS_INVALID,        /**< The name for the ns (database or collection) is invalid. */
+    MONGO_BSON_INVALID,      /**< BSON not valid for the specified op. */
+    MONGO_BSON_NOT_FINISHED, /**< BSON object has not been finished. */
+    MONGO_BSON_TOO_LARGE     /**< BSON object exceeds max BSON size. */
+} mongo_error_t;
+
+typedef enum mongo_cursor_error_t {
     MONGO_CURSOR_EXHAUSTED,  /**< The cursor has no more results. */
     MONGO_CURSOR_INVALID,    /**< The cursor has timed out or is not recognized. */
     MONGO_CURSOR_PENDING,    /**< Tailable cursor still alive but no data. */
-    MONGO_BSON_INVALID,      /**< BSON not valid for the specified op. */
-    MONGO_BSON_NOT_FINISHED  /**< BSON object has not been finished. */
-} mongo_error_t;
+    MONGO_CURSOR_QUERY_FAIL, /**< The server returned an '$err' object, indicating query failure.
+                                  See conn->lasterrcode and conn->lasterrstr for details. */
+    MONGO_CURSOR_BSON_ERROR  /**< Something is wrong with the BSON provided. See conn->err
+                                  for details. */
+} mongo_cursor_error_t;
 
 enum mongo_cursor_flags {
     MONGO_CURSOR_MUST_FREE = 1,      /**< mongo_cursor_destroy should free cursor. */
@@ -137,12 +151,14 @@ typedef struct mongo {
     int flags;                 /**< Flags on this connection object. */
     int conn_timeout_ms;       /**< Connection timeout in milliseconds. */
     int op_timeout_ms;         /**< Read and write timeout in milliseconds. */
+    int max_bson_size;         /**< Largest BSON object allowed on this connection. */
     bson_bool_t connected;     /**< Connection status. */
 
-    mongo_error_t err;         /**< Most recent driver error code. */
-    char *errstr;              /**< String version of most recent driver error code. */
-    int lasterrcode;           /**< getlasterror given by the server on calls. */
-    char *lasterrstr;          /**< getlasterror string generated by server. */
+    mongo_error_t err;          /**< Most recent driver error code. */
+    int errcode;                /**< Most recent errno or WSAGetLastError(). */
+    char errstr[MONGO_ERR_LEN]; /**< String version of error. */
+    int lasterrcode;            /**< getlasterror code from the server. */
+    char lasterrstr[MONGO_ERR_LEN]; /**< getlasterror string from the server. */
 } mongo;
 
 typedef struct {
@@ -152,9 +168,9 @@ typedef struct {
     int flags;         /**< Flags used internally by this drivers. */
     int seen;          /**< Number returned so far. */
     bson current;      /**< This cursor's current bson object. */
-    mongo_error_t err; /**< Errors on this cursor. */
-    bson *query;       /**< Bitfield containing cursor options. */
-    bson *fields;      /**< Bitfield containing cursor options. */
+    mongo_cursor_error_t err; /**< Errors on this cursor. */
+    const bson *query; /**< Bitfield containing cursor options. */
+    const bson *fields;/**< Bitfield containing cursor options. */
     int options;       /**< Bitfield containing cursor options. */
     int limit;         /**< Bitfield containing cursor options. */
     int skip;          /**< Bitfield containing cursor options. */
@@ -162,9 +178,44 @@ typedef struct {
 
 /* Connection API */
 
-/** Initialize a new mongo connection object. If not created
- *  with mongo_new, you must initialize each mongo
- *  object using this function.
+MONGO_EXPORT mongo* mongo_create();
+MONGO_EXPORT void mongo_dispose(mongo* conn);
+MONGO_EXPORT int mongo_get_err(mongo* conn);
+MONGO_EXPORT int mongo_is_connected(mongo* conn);
+MONGO_EXPORT int mongo_get_op_timeout(mongo* conn);
+MONGO_EXPORT const char* mongo_get_primary(mongo* conn);
+MONGO_EXPORT int mongo_get_socket(mongo* conn) ;
+MONGO_EXPORT int mongo_get_host_count(mongo* conn);
+MONGO_EXPORT const char* mongo_get_host(mongo* conn, int i);
+MONGO_EXPORT mongo_cursor* mongo_cursor_create();
+MONGO_EXPORT void mongo_cursor_dispose(mongo_cursor* cursor);
+MONGO_EXPORT int  mongo_get_server_err(mongo* conn);
+MONGO_EXPORT const char*  mongo_get_server_err_string(mongo* conn);
+
+/**
+ * Set an error this mongo connection object. Mostly for internal use.
+ *
+ * @param conn a mongo connection object.
+ * @param err a driver error code of mongo_error_t.
+ * @param errstr a string version of the error.
+ * @param errorcode Currently errno or WSAGetLastError().
+ */
+MONGO_EXPORT void __mongo_set_error( mongo *conn, mongo_error_t err,
+                                     const char *errstr, int errorcode );
+/**
+ * Clear all errors stored on this mongo connection object.
+ *
+ * @param conn a mongo connection object.
+ */
+MONGO_EXPORT void mongo_clear_errors( mongo *conn );
+
+/** Initialize sockets for Windows.
+ */
+MONGO_EXPORT void mongo_init_sockets();
+
+/**
+ * Initialize a new mongo connection object. You must initialize each mongo
+ * object using this function.
  *
  *  @note When finished, you must pass this object to
  *      mongo_destroy( ).
@@ -172,7 +223,7 @@ typedef struct {
  *  @param conn a mongo connection object allocated on the stack
  *      or heap.
  */
-void mongo_init( mongo *conn );
+MONGO_EXPORT void mongo_init( mongo *conn );
 
 /**
  * Connect to a single MongoDB server.
@@ -182,9 +233,9 @@ void mongo_init( mongo *conn );
  * @param port the port to connect to.
  *
  * @return MONGO_OK or MONGO_ERROR on failure. On failure, a constant of type
- *   mongo_conn_return_t will be set on the conn->err field.
+ *   mongo_error_t will be set on the conn->err field.
  */
-int mongo_connect( mongo *conn , const char *host, int port );
+MONGO_EXPORT int mongo_connect( mongo *conn , const char *host, int port );
 
 /**
  * Set up this connection object for connecting to a replica set.
@@ -193,7 +244,7 @@ int mongo_connect( mongo *conn , const char *host, int port );
  * @param conn a mongo object.
  * @param name the name of the replica set to connect to.
  * */
-void mongo_replset_init( mongo *conn, const char *name );
+MONGO_EXPORT void mongo_replset_init( mongo *conn, const char *name );
 
 /**
  * Add a seed node to the replica set connection object.
@@ -204,7 +255,7 @@ void mongo_replset_init( mongo *conn, const char *name );
  * @param host a numerical network address or a network hostname.
  * @param port the port to connect to.
  */
-void mongo_replset_add_seed( mongo *conn, const char *host, int port );
+MONGO_EXPORT void mongo_replset_add_seed( mongo *conn, const char *host, int port );
 
 /**
  * Utility function for converting a host-port string to a mongo_host_port.
@@ -215,6 +266,17 @@ void mongo_replset_add_seed( mongo *conn, const char *host, int port );
  */
 void mongo_parse_host( const char *host_string, mongo_host_port *host_port );
 
+/**
+ * Utility function for validation database and collection names.
+ *
+ * @param conn a mongo object.
+ *
+ * @return MONGO_OK or MONGO_ERROR on failure. On failure, a constant of type
+ *   mongo_conn_return_t will be set on the conn->err field.
+ *
+ */
+MONGO_EXPORT int mongo_validate_ns( mongo *conn, const char *ns );
+
 /**
  * Connect to a replica set.
  *
@@ -226,7 +288,7 @@ void mongo_parse_host( const char *host_string, mongo_host_port *host_port );
  * @return MONGO_OK or MONGO_ERROR on failure. On failure, a constant of type
  *   mongo_conn_return_t will be set on the conn->err field.
  */
-int mongo_replset_connect( mongo *conn );
+MONGO_EXPORT int mongo_replset_connect( mongo *conn );
 
 /** Set a timeout for operations on this connection. This
  *  is a platform-specific feature, and only work on *nix
@@ -238,7 +300,7 @@ int mongo_replset_connect( mongo *conn );
  *  @return MONGO_OK. On error, return MONGO_ERROR and
  *    set the conn->err field.
  */
-int mongo_set_op_timeout( mongo *conn, int millis );
+MONGO_EXPORT int mongo_set_op_timeout( mongo *conn, int millis );
 
 /**
  * Ensure that this connection is healthy by performing
@@ -248,7 +310,7 @@ int mongo_set_op_timeout( mongo *conn, int millis );
  *
  * @return MONGO_OK if connected; otherwise, MONGO_ERROR.
  */
-int mongo_check_connection( mongo *conn );
+MONGO_EXPORT int mongo_check_connection( mongo *conn );
 
 /**
  * Try reconnecting to the server using the existing connection settings.
@@ -261,7 +323,7 @@ int mongo_check_connection( mongo *conn );
  * @return MONGO_OK or MONGO_ERROR and
  *   set the conn->err field.
  */
-int mongo_reconnect( mongo *conn );
+MONGO_EXPORT int mongo_reconnect( mongo *conn );
 
 /**
  * Close the current connection to the server. After calling
@@ -270,7 +332,7 @@ int mongo_reconnect( mongo *conn );
  *
  * @param conn a mongo object.
  */
-void mongo_disconnect( mongo *conn );
+MONGO_EXPORT void mongo_disconnect( mongo *conn );
 
 /**
  * Close any existing connection to the server and free all allocated
@@ -280,7 +342,7 @@ void mongo_disconnect( mongo *conn );
  *
  * @param conn a mongo object.
  */
-void mongo_destroy( mongo *conn );
+MONGO_EXPORT void mongo_destroy( mongo *conn );
 
 /**
  * Insert a BSON document into a MongoDB server. This function
@@ -295,7 +357,7 @@ void mongo_destroy( mongo *conn );
  *     field is MONGO_BSON_INVALID, check the err field
  *     on the bson struct for the reason.
  */
-int mongo_insert( mongo *conn, const char *ns, bson *data );
+MONGO_EXPORT int mongo_insert( mongo *conn, const char *ns, const bson *data );
 
 /**
  * Insert a batch of BSON documents into a MongoDB server. This function
@@ -309,8 +371,8 @@ int mongo_insert( mongo *conn, const char *ns, bson *data );
  * @return MONGO_OK or MONGO_ERROR.
  *
  */
-int mongo_insert_batch( mongo *conn , const char *ns ,
-                        bson **data , int num );
+MONGO_EXPORT int mongo_insert_batch( mongo *conn , const char *ns ,
+                        const bson **data , int num );
 
 /**
  * Update a document in a MongoDB server.
@@ -324,7 +386,7 @@ int mongo_insert_batch( mongo *conn , const char *ns ,
  * @return MONGO_OK or MONGO_ERROR with error stored in conn object.
  *
  */
-int mongo_update( mongo *conn, const char *ns, const bson *cond,
+MONGO_EXPORT int mongo_update( mongo *conn, const char *ns, const bson *cond,
                   const bson *op, int flags );
 
 /**
@@ -336,7 +398,7 @@ int mongo_update( mongo *conn, const char *ns, const bson *cond,
  *
  * @return MONGO_OK or MONGO_ERROR with error stored in conn object.
  */
-int mongo_remove( mongo *conn, const char *ns, const bson *cond );
+MONGO_EXPORT int mongo_remove( mongo *conn, const char *ns, const bson *cond );
 
 /**
  * Find documents in a MongoDB server.
@@ -353,8 +415,8 @@ int mongo_remove( mongo *conn, const char *ns, const bson *cond );
  *     an error has occurred. For finer-grained error checking,
  *     use the cursor builder API instead.
  */
-mongo_cursor *mongo_find( mongo *conn, const char *ns, bson *query,
-                          bson *fields, int limit, int skip, int options );
+MONGO_EXPORT mongo_cursor *mongo_find( mongo *conn, const char *ns, const bson *query,
+                          const bson *fields, int limit, int skip, int options );
 
 /**
  * Initalize a new cursor object.
@@ -363,7 +425,7 @@ mongo_cursor *mongo_find( mongo *conn, const char *ns, bson *query,
  * @param ns the namespace, represented as the the database
  *     name and collection name separated by a dot. e.g., "test.users"
  */
-void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns );
+MONGO_EXPORT void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns );
 
 /**
  * Set the bson object specifying this cursor's query spec. If
@@ -376,7 +438,7 @@ void mongo_cursor_init( mongo_cursor *cursor, mongo *conn, const char *ns );
  *   $query, $orderby, $hint, and/or $explain. See
  *   http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol for details.
  */
-void mongo_cursor_set_query( mongo_cursor *cursor, bson *query );
+MONGO_EXPORT void mongo_cursor_set_query( mongo_cursor *cursor, const bson *query );
 
 /**
  * Set the fields to return for this cursor. If you want to return
@@ -386,7 +448,7 @@ void mongo_cursor_set_query( mongo_cursor *cursor, bson *query );
  * @param fields a bson object representing the fields to return.
  *   See http://www.mongodb.org/display/DOCS/Retrieving+a+Subset+of+Fields.
  */
-void mongo_cursor_set_fields( mongo_cursor *cursor, bson *fields );
+MONGO_EXPORT void mongo_cursor_set_fields( mongo_cursor *cursor, const bson *fields );
 
 /**
  * Set the number of documents to skip.
@@ -394,7 +456,7 @@ void mongo_cursor_set_fields( mongo_cursor *cursor, bson *fields );
  * @param cursor
  * @param skip
  */
-void mongo_cursor_set_skip( mongo_cursor *cursor, int skip );
+MONGO_EXPORT void mongo_cursor_set_skip( mongo_cursor *cursor, int skip );
 
 /**
  * Set the number of documents to return.
@@ -402,7 +464,7 @@ void mongo_cursor_set_skip( mongo_cursor *cursor, int skip );
  * @param cursor
  * @param limit
  */
-void mongo_cursor_set_limit( mongo_cursor *cursor, int limit );
+MONGO_EXPORT void mongo_cursor_set_limit( mongo_cursor *cursor, int limit );
 
 /**
  * Set any of the available query options (e.g., MONGO_TAILABLE).
@@ -411,7 +473,7 @@ void mongo_cursor_set_limit( mongo_cursor *cursor, int limit );
  * @param options a bitfield storing query options. See
  *   mongo_cursor_bitfield_t for available constants.
  */
-void mongo_cursor_set_options( mongo_cursor *cursor, int options );
+MONGO_EXPORT void mongo_cursor_set_options( mongo_cursor *cursor, int options );
 
 /**
  * Return the current BSON object data as a const char*. This is useful
@@ -419,7 +481,7 @@ void mongo_cursor_set_options( mongo_cursor *cursor, int options );
  *
  * @param cursor
  */
-const char *mongo_cursor_data( mongo_cursor *cursor );
+MONGO_EXPORT const char *mongo_cursor_data( mongo_cursor *cursor );
 
 /**
  * Return the current BSON object data as a const char*. This is useful
@@ -427,7 +489,7 @@ const char *mongo_cursor_data( mongo_cursor *cursor );
  *
  * @param cursor
  */
-const bson *mongo_cursor_bson( mongo_cursor *cursor );
+MONGO_EXPORT const bson *mongo_cursor_bson( mongo_cursor *cursor );
 
 /**
  * Iterate the cursor, returning the next item. When successful,
@@ -438,7 +500,7 @@ const bson *mongo_cursor_bson( mongo_cursor *cursor );
  * @return MONGO_OK. On error, returns MONGO_ERROR and sets
  *   cursor->err with a value of mongo_error_t.
  */
-int mongo_cursor_next( mongo_cursor *cursor );
+MONGO_EXPORT int mongo_cursor_next( mongo_cursor *cursor );
 
 /**
  * Destroy a cursor object. When finished with a cursor, you
@@ -449,7 +511,7 @@ int mongo_cursor_next( mongo_cursor *cursor );
  * @return MONGO_OK or an error code. On error, check cursor->conn->err
  *     for errors.
  */
-int mongo_cursor_destroy( mongo_cursor *cursor );
+MONGO_EXPORT int mongo_cursor_destroy( mongo_cursor *cursor );
 
 /**
  * Find a single document in a MongoDB server.
@@ -462,8 +524,8 @@ int mongo_cursor_destroy( mongo_cursor *cursor );
  *
  */
 /* out can be NULL if you don't care about results. useful for commands */
-bson_bool_t mongo_find_one( mongo *conn, const char *ns, bson *query,
-                            bson *fields, bson *out );
+MONGO_EXPORT int mongo_find_one( mongo *conn, const char *ns, const bson *query,
+                            const bson *fields, bson *out );
 
 /* MongoDB Helper Functions */
 
@@ -478,8 +540,8 @@ bson_bool_t mongo_find_one( mongo *conn, const char *ns, bson *query,
  * @return the number of matching documents. If the command fails,
  *     MONGO_ERROR is returned.
  */
-int64_t mongo_count( mongo *conn, const char *db, const char *coll,
-                     bson *query );
+MONGO_EXPORT double mongo_count( mongo *conn, const char *db, const char *coll,
+                     const bson *query );
 
 /**
  * Create a compouned index.
@@ -494,7 +556,7 @@ int64_t mongo_count( mongo *conn, const char *db, const char *coll,
  *
  * @return MONGO_OK if index is created successfully; otherwise, MONGO_ERROR.
  */
-int mongo_create_index( mongo *conn, const char *ns, bson *key, int options, bson *out );
+MONGO_EXPORT int mongo_create_index( mongo *conn, const char *ns, const bson *key, int options, bson *out );
 
 /**
  * Create an index with a single key.
@@ -521,9 +583,9 @@ bson_bool_t mongo_create_simple_index( mongo *conn, const char *ns, const char *
  * @param command the BSON command to run.
  * @param out the BSON result of the command.
  *
- * @return true if the command ran without error.
+ * @return MONGO_OK if the command ran without error.
  */
-bson_bool_t mongo_run_command( mongo *conn, const char *db, bson *command, bson *out );
+MONGO_EXPORT int mongo_run_command( mongo *conn, const char *db, const bson *command, bson *out );
 
 /**
  * Run a command that accepts a simple string key and integer value.
@@ -537,7 +599,7 @@ bson_bool_t mongo_run_command( mongo *conn, const char *db, bson *command, bson
  * @return MONGO_OK or an error code.
  *
  */
-int mongo_simple_int_command( mongo *conn, const char *db,
+MONGO_EXPORT int mongo_simple_int_command( mongo *conn, const char *db,
                               const char *cmd, int arg, bson *out );
 
 /**
@@ -552,7 +614,7 @@ int mongo_simple_int_command( mongo *conn, const char *db,
  * @return true if the command ran without error.
  *
  */
-bson_bool_t mongo_simple_str_command( mongo *conn, const char *db, const char *cmd, const char *arg, bson *out );
+MONGO_EXPORT int mongo_simple_str_command( mongo *conn, const char *db, const char *cmd, const char *arg, bson *out );
 
 /**
  * Drop a database.
@@ -562,7 +624,7 @@ bson_bool_t mongo_simple_str_command( mongo *conn, const char *db, const char *c
  *
  * @return MONGO_OK or an error code.
  */
-int mongo_cmd_drop_db( mongo *conn, const char *db );
+MONGO_EXPORT int mongo_cmd_drop_db( mongo *conn, const char *db );
 
 /**
  * Drop a collection.
@@ -574,7 +636,7 @@ int mongo_cmd_drop_db( mongo *conn, const char *db );
  *
  * @return true if the collection drop was successful.
  */
-bson_bool_t mongo_cmd_drop_collection( mongo *conn, const char *db, const char *collection, bson *out );
+MONGO_EXPORT int mongo_cmd_drop_collection( mongo *conn, const char *db, const char *collection, bson *out );
 
 /**
  * Add a database user.
@@ -586,7 +648,7 @@ bson_bool_t mongo_cmd_drop_collection( mongo *conn, const char *db, const char *
  *
  * @return MONGO_OK or MONGO_ERROR.
   */
-int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass );
+MONGO_EXPORT int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const char *pass );
 
 /**
  * Authenticate a user.
@@ -598,7 +660,7 @@ int mongo_cmd_add_user( mongo *conn, const char *db, const char *user, const cha
  *
  * @return MONGO_OK on sucess and MONGO_ERROR on failure.
  */
-int mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass );
+MONGO_EXPORT int mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const char *pass );
 
 /**
  * Check if the current server is a master.
@@ -609,7 +671,7 @@ int mongo_cmd_authenticate( mongo *conn, const char *db, const char *user, const
  * @return true if the server is a master.
  */
 /* return value is master status */
-bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *out );
+MONGO_EXPORT bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *out );
 
 /**
  * Get the error for the last command with the current connection.
@@ -621,7 +683,7 @@ bson_bool_t mongo_cmd_ismaster( mongo *conn, bson *out );
  * @return MONGO_OK if no error and MONGO_ERROR on error. On error, check the values
  *     of conn->lasterrcode and conn->lasterrstr for the error status.
  */
-int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out );
+MONGO_EXPORT int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out );
 
 /**
  * Get the most recent error with the current connection.
@@ -633,7 +695,7 @@ int mongo_cmd_get_last_error( mongo *conn, const char *db, bson *out );
  * @return MONGO_OK if no error and MONGO_ERROR on error. On error, check the values
  *     of conn->lasterrcode and conn->lasterrstr for the error status.
  */
-int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out );
+MONGO_EXPORT int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out );
 
 /**
  * Reset the error state for the connection.
@@ -641,7 +703,8 @@ int mongo_cmd_get_prev_error( mongo *conn, const char *db, bson *out );
  * @param conn a mongo object.
  * @param db the name of the database.
  */
-void mongo_cmd_reset_error( mongo *conn, const char *db );
+MONGO_EXPORT void mongo_cmd_reset_error( mongo *conn, const char *db );
+
 
 MONGO_EXTERN_C_END
 
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.c
deleted file mode 100644
index 5c8ad9ba5e..0000000000
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* net.c */
-
-/*    Copyright 2009-2011 10gen 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.
- */
-
-/* Implementation for generic version of net.h */
-#include "net.h"
-#include <string.h>
-
-int mongo_write_socket( mongo *conn, const void *buf, int len ) {
-    const char *cbuf = buf;
-    while ( len ) {
-        int sent = send( conn->sock, cbuf, len, 0 );
-        if ( sent == -1 ) {
-            conn->err = MONGO_IO_ERROR;
-            return MONGO_ERROR;
-        }
-        cbuf += sent;
-        len -= sent;
-    }
-
-    return MONGO_OK;
-}
-
-int mongo_read_socket( mongo *conn, void *buf, int len ) {
-    char *cbuf = buf;
-    while ( len ) {
-        int sent = recv( conn->sock, cbuf, len, 0 );
-        if ( sent == 0 || sent == -1 ) {
-            conn->err = MONGO_IO_ERROR;
-            return MONGO_ERROR;
-        }
-        cbuf += sent;
-        len -= sent;
-    }
-
-    return MONGO_OK;
-}
-
-/* This is a no-op in the generic implementation. */
-int mongo_set_socket_op_timeout( mongo *conn, int millis ) {
-    return MONGO_OK;
-}
-
-static int mongo_create_socket( mongo *conn ) {
-    int fd;
-
-    if( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) {
-        conn->err = MONGO_CONN_NO_SOCKET;
-        return MONGO_ERROR;
-    }
-    conn->sock = fd;
-
-    return MONGO_OK;
-}
-
-int mongo_socket_connect( mongo *conn, const char *host, int port ) {
-    struct sockaddr_in sa;
-    socklen_t addressSize;
-    int flag = 1;
-
-    if( mongo_create_socket( conn ) != MONGO_OK )
-        return MONGO_ERROR;
-
-    memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) );
-    sa.sin_family = AF_INET;
-    sa.sin_port = htons( port );
-    sa.sin_addr.s_addr = inet_addr( host );
-    addressSize = sizeof( sa );
-
-    if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) {
-        mongo_close_socket( conn->sock );
-        conn->connected = 0;
-        conn->sock = 0;
-        conn->err = MONGO_CONN_FAIL;
-        return MONGO_ERROR;
-    }
-
-    setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) );
-    if( conn->op_timeout_ms > 0 )
-        mongo_set_socket_op_timeout( conn, conn->op_timeout_ms );
-
-    conn->connected = 1;
-
-    return MONGO_OK;
-}
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.h
deleted file mode 100644
index 49190877c8..0000000000
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/net.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/** @file net.h */
-
-/*    Copyright 2009-2011 10gen 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.
- */
-
-/* Header for generic net.h */
-#ifndef _MONGO_NET_H_
-#define _MONGO_NET_H_
-
-#include "mongo.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#include <winsock.h>
-#define mongo_close_socket(sock) ( closesocket(sock) )
-typedef int socklen_t;
-#else
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <fcntl.h>
-#define mongo_close_socket(sock) ( close(sock) )
-#endif
-
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-
-#if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || _POSIX_C_SOURCE >= 1
-#define _MONGO_USE_GETADDRINFO
-#endif
-
-MONGO_EXTERN_C_START
-
-/* This is a no-op in the generic implementation. */
-int mongo_set_socket_op_timeout( mongo *conn, int millis );
-int mongo_read_socket( mongo *conn, void *buf, int len );
-int mongo_write_socket( mongo *conn, const void *buf, int len );
-int mongo_socket_connect( mongo *conn, const char *host, int port );
-
-MONGO_EXTERN_C_END
-#endif
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/numbers.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/numbers.c
index a63e3d73f9..b3032d5ee3 100644
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/numbers.c
+++ b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/numbers.c
@@ -1,4 +1,4 @@
-/*    Copyright 2009-2011 10gen Inc.
+/*    Copyright 2009-2012 10gen Inc.
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform.h
deleted file mode 100644
index 4a96af77e3..0000000000
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/** @file platform.h */
-
-/**    Copyright 2009-2011 10gen 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.
- */
-
-
-/* all platform-specific ifdefs should go here */
-
-#ifndef _PLATFORM_HACKS_H_
-#define _PLATFORM_HACKS_H_
-
-#ifdef __GNUC__
-#define MONGO_INLINE static __inline__
-#else
-#define MONGO_INLINE static
-#endif
-
-#ifdef __cplusplus
-#define MONGO_EXTERN_C_START extern "C" {
-#define MONGO_EXTERN_C_END }
-#else
-#define MONGO_EXTERN_C_START
-#define MONGO_EXTERN_C_END
-#endif
-
-
-#if defined(MONGO_HAVE_STDINT) || __STDC_VERSION__ >= 199901L
-#include <stdint.h>
-#elif defined(MONGO_HAVE_UNISTD)
-#include <unistd.h>
-#elif defined(MONGO_USE__INT64)
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-#elif defined(MONGO_USE_LONG_LONG_INT)
-typedef long long int int64_t;
-typedef unsigned long long int uint64_t;
-#else
-#error must have a 64bit int type
-#endif
-
-/* big endian is only used for OID generation. little is used everywhere else */
-#ifdef MONGO_BIG_ENDIAN
-#define bson_little_endian64(out, in) ( bson_swap_endian64(out, in) )
-#define bson_little_endian32(out, in) ( bson_swap_endian32(out, in) )
-#define bson_big_endian64(out, in) ( memcpy(out, in, 8) )
-#define bson_big_endian32(out, in) ( memcpy(out, in, 4) )
-#else
-#define bson_little_endian64(out, in) ( memcpy(out, in, 8) )
-#define bson_little_endian32(out, in) ( memcpy(out, in, 4) )
-#define bson_big_endian64(out, in) ( bson_swap_endian64(out, in) )
-#define bson_big_endian32(out, in) ( bson_swap_endian32(out, in) )
-#endif
-
-MONGO_EXTERN_C_START
-
-MONGO_INLINE void bson_swap_endian64( void *outp, const void *inp ) {
-    const char *in = ( const char * )inp;
-    char *out = ( char * )outp;
-
-    out[0] = in[7];
-    out[1] = in[6];
-    out[2] = in[5];
-    out[3] = in[4];
-    out[4] = in[3];
-    out[5] = in[2];
-    out[6] = in[1];
-    out[7] = in[0];
-
-}
-MONGO_INLINE void bson_swap_endian32( void *outp, const void *inp ) {
-    const char *in = ( const char * )inp;
-    char *out = ( char * )outp;
-
-    out[0] = in[3];
-    out[1] = in[2];
-    out[2] = in[1];
-    out[3] = in[0];
-}
-
-MONGO_EXTERN_C_END
-
-#endif
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.c b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.c
deleted file mode 100644
index b2f7c22898..0000000000
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/* net.c */
-
-/*    Copyright 2009-2011 10gen 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.
- */
-
-/* Implementation for Linux version of net.h */
-#include "net.h"
-#include <string.h>
-
-int mongo_write_socket( mongo *conn, const void *buf, int len ) {
-    const char *cbuf = buf;
-    while ( len ) {
-        int sent = send( conn->sock, cbuf, len, 0 );
-        if ( sent == -1 ) {
-            conn->err = MONGO_IO_ERROR;
-            return MONGO_ERROR;
-        }
-        cbuf += sent;
-        len -= sent;
-    }
-
-    return MONGO_OK;
-}
-
-int mongo_read_socket( mongo *conn, void *buf, int len ) {
-    char *cbuf = buf;
-    while ( len ) {
-        int sent = recv( conn->sock, cbuf, len, 0 );
-        if ( sent == 0 || sent == -1 ) {
-            conn->err = MONGO_IO_ERROR;
-            return MONGO_ERROR;
-        }
-        cbuf += sent;
-        len -= sent;
-    }
-
-    return MONGO_OK;
-}
-
-static int mongo_create_socket( mongo *conn ) {
-    int fd;
-
-    if( ( fd = socket( AF_INET, SOCK_STREAM, 0 ) ) == -1 ) {
-        conn->err = MONGO_CONN_NO_SOCKET;
-        return MONGO_ERROR;
-    }
-    conn->sock = fd;
-
-    return MONGO_OK;
-}
-
-static int mongo_set_blocking_status( mongo *conn ) {
-    int flags;
-    int blocking;
-
-    blocking = ( conn->conn_timeout_ms == 0 );
-    if( blocking )
-        return MONGO_OK;
-    else {
-        if( ( flags = fcntl( conn->sock, F_GETFL ) ) == -1 ) {
-            conn->err = MONGO_IO_ERROR;
-            mongo_close_socket( conn->sock );
-            return MONGO_ERROR;
-        }
-
-        flags |= O_NONBLOCK;
-
-        if( ( flags = fcntl( conn->sock, F_SETFL, flags ) ) == -1 ) {
-            conn->err = MONGO_IO_ERROR;
-            mongo_close_socket( conn->sock );
-            return MONGO_ERROR;
-        }
-    }
-
-    return MONGO_OK;
-}
-
-int mongo_set_socket_op_timeout( mongo *conn, int millis ) {
-    struct timeval tv;
-    tv.tv_sec = millis / 1000;
-    tv.tv_usec = ( millis % 1000 ) * 1000;
-
-    if ( setsockopt( conn->sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof( tv ) ) == -1 ) {
-        conn->err = MONGO_IO_ERROR;
-        return MONGO_ERROR;
-    }
-
-    if ( setsockopt( conn->sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof( tv ) ) == -1 ) {
-        conn->err = MONGO_IO_ERROR;
-        return MONGO_ERROR;
-    }
-
-    return MONGO_OK;
-}
-
-#ifdef _MONGO_USE_GETADDRINFO
-int mongo_socket_connect( mongo *conn, const char *host, int port ) {
-
-    struct addrinfo *addrs = NULL;
-    struct addrinfo hints;
-    int flag = 1;
-    char port_str[12];
-    int ret;
-
-    conn->sock = 0;
-    conn->connected = 0;
-
-    memset( &hints, 0, sizeof( hints ) );
-    hints.ai_family = AF_INET;
-    hints.ai_socktype = SOCK_STREAM;
-
-    sprintf( port_str, "%d", port );
-
-    if( mongo_create_socket( conn ) != MONGO_OK )
-        return MONGO_ERROR;
-
-    if( getaddrinfo( host, port_str, &hints, &addrs ) != 0 ) {
-        bson_errprintf( "getaddrinfo failed: %s", gai_strerror( ret ) );
-        conn->err = MONGO_CONN_ADDR_FAIL;
-        return MONGO_ERROR;
-    }
-
-    if ( connect( conn->sock, addrs->ai_addr, addrs->ai_addrlen ) == -1 ) {
-        mongo_close_socket( conn->sock );
-        freeaddrinfo( addrs );
-        conn->err = MONGO_CONN_FAIL;
-        return MONGO_ERROR;
-    }
-
-    setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * )&flag, sizeof( flag ) );
-    if( conn->op_timeout_ms > 0 )
-        mongo_set_socket_op_timeout( conn, conn->op_timeout_ms );
-
-    conn->connected = 1;
-    freeaddrinfo( addrs );
-
-    return MONGO_OK;
-}
-#else
-int mongo_socket_connect( mongo *conn, const char *host, int port ) {
-    struct sockaddr_in sa;
-    socklen_t addressSize;
-    int flag = 1;
-
-    if( mongo_create_socket( conn ) != MONGO_OK )
-        return MONGO_ERROR;
-
-    memset( sa.sin_zero , 0 , sizeof( sa.sin_zero ) );
-    sa.sin_family = AF_INET;
-    sa.sin_port = htons( port );
-    sa.sin_addr.s_addr = inet_addr( host );
-    addressSize = sizeof( sa );
-
-    if ( connect( conn->sock, ( struct sockaddr * )&sa, addressSize ) == -1 ) {
-        mongo_close_socket( conn->sock );
-        conn->connected = 0;
-        conn->sock = 0;
-        conn->err = MONGO_CONN_FAIL;
-        return MONGO_ERROR;
-    }
-
-    setsockopt( conn->sock, IPPROTO_TCP, TCP_NODELAY, ( char * ) &flag, sizeof( flag ) );
-
-    if( conn->op_timeout_ms > 0 )
-        mongo_set_socket_op_timeout( conn, conn->op_timeout_ms );
-
-    conn->connected = 1;
-
-    return MONGO_OK;
-}
-#endif
diff --git a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.h b/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.h
deleted file mode 100644
index 054247c1e8..0000000000
--- a/src/mod/event_handlers/mod_cdr_mongodb/driver/src/platform/linux/net.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file net.h
- * @brief Networking.
- */
-
-/*    Copyright 2009-2011 10gen 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.
- */
-
-/* Header for Linux net.h */
-#ifndef _MONGO_NET_H_
-#define _MONGO_NET_H_
-
-#include "mongo.h"
-
-#include <arpa/inet.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <unistd.h>
-#define mongo_close_socket(sock) ( close(sock) )
-
-#if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || _POSIX_C_SOURCE >= 1
-#define _MONGO_USE_GETADDRINFO
-#endif
-
-MONGO_EXTERN_C_START
-
-int mongo_set_socket_op_timeout( mongo *conn, int millis );
-int mongo_read_socket( mongo *conn, void *buf, int len );
-int mongo_write_socket( mongo *conn, const void *buf, int len );
-int mongo_socket_connect( mongo *conn, const char *host, int port );
-
-MONGO_EXTERN_C_END
-#endif