diff --git a/mongodb_session/mongodb_session.inc b/mongodb_session/mongodb_session.inc
new file mode 100644
index 0000000..527db11
--- /dev/null
+++ b/mongodb_session/mongodb_session.inc
@@ -0,0 +1,256 @@
+<?php
+
+include_once dirname(__FILE__) . '/../mongodb.module';
+
+/**
+ * @file
+ * User session handling functions.
+ *
+ * The user-level session storage handlers:
+ * - _drupal_session_open()
+ * - _drupal_session_close()
+ * - _drupal_session_read()
+ * - _drupal_session_write()
+ * - _drupal_session_destroy()
+ * - _drupal_session_garbage_collection()
+ * are assigned by session_set_save_handler() in bootstrap.inc and are called
+ * automatically by PHP. These functions should not be called directly. Session
+ * data should instead be accessed via the $_SESSION superglobal.
+ */
+
+/**
+ * Session handler assigned by session_set_save_handler().
+ *
+ * This function is used to handle any initialization, such as file paths or
+ * database connections, that is needed before accessing session data. Drupal
+ * does not need to initialize anything in this function.
+ *
+ * This function should not be called directly.
+ *
+ * @return
+ *   This function will always return TRUE.
+ */
+function sess_open($save_path, $session_name) {return TRUE;}
+
+/**
+ * Session handler assigned by session_set_save_handler().
+ *
+ * This function is used to close the current session. Because Drupal stores
+ * session data in the database immediately on write, this function does
+ * not need to do anything.
+ *
+ * This function should not be called directly.
+ *
+ * @return
+ *   This function will always return TRUE.
+ */
+function sess_close() {return TRUE;}
+
+/**
+ * Called when an anonymous user becomes authenticated or vice-versa.
+ */
+function sess_regenerate() {
+  $old_session_id = session_id();
+
+  // We code around http://bugs.php.net/bug.php?id=32802 by destroying
+  // the session cookie by setting expiration in the past (a negative
+  // value).  This issue only arises in PHP versions before 4.4.0,
+  // regardless of the Drupal configuration.
+  // TODO: remove this when we require at least PHP 4.4.0
+  if (isset($_COOKIE[session_name()])) {
+    setcookie(session_name(), '', $_SERVER['REQUEST_TIME'] - 42000, '/');
+  }
+
+  session_regenerate_id();
+
+  mongodb_collection(variable_get('mongodb_session', 'session'))
+    ->update(array('sid' => $old_session_id), array('$set' => array('sid' => session_id())));
+}
+
+/**
+ * Counts how many users have sessions. Can count either anonymous sessions or authenticated sessions.
+ *
+ * @param int $timestamp
+ *   A Unix timestamp representing a point of time in the past.
+ *   The default is 0, which counts all existing sessions.
+ * @param boolean $anonymous
+ *   TRUE counts only anonymous users.
+ *   FALSE counts only authenticated users.
+ * @return  int
+ *   The number of users with sessions.
+ */
+function sess_count($timestamp = 0, $anonymous = true) {
+  $conditions = array(
+    'timestamp' => array('$gte' => $timestamp),
+    'uid' => $anonymous ? 0 : array('$gt' => 0)
+  );
+  return mongodb_collection(variable_get('mongodb_session', 'session'))->find($conditions)->count();  
+}
+
+/**
+ * Determine whether to save session data of the current request.
+ *
+ * This function allows the caller to temporarily disable writing of session data,
+ * should the request end while performing potentially dangerous operations, such as
+ * manipulating the global $user object.  See http://drupal.org/node/218104 for usage
+ *
+ * @param $status
+ *   Disables writing of session data when FALSE, (re-)enables writing when TRUE.
+ * @return
+ *   FALSE if writing session data has been disabled. Otherwise, TRUE.
+ */
+function session_save_session($status = NULL) {
+  static $save_session = TRUE;
+  if (isset($status)) {
+    $save_session = $status;
+  }
+  return ($save_session);
+}
+
+/**
+ * Session handler assigned by session_set_save_handler().
+ *
+ * This function will be called by PHP to retrieve the current user's
+ * session data, which is stored in the database. It also loads the
+ * current user's appropriate roles into the user object.
+ *
+ * This function should not be called directly. Session data should
+ * instead be accessed via the $_SESSION superglobal.
+ *
+ * @param $sid
+ *   Session ID.
+ * @return
+ *   Either an array of the session data, or an empty string, if no data
+ *   was found or the user is anonymous.
+ */
+function sess_read($sid) {
+  global $user;
+
+  // Write and Close handlers are called after destructing objects
+  // since PHP 5.0.5.
+  // Thus destructors can use sessions but session handler can't use objects.
+  // So we are moving session closure before destructing objects.
+  register_shutdown_function('session_write_close');
+
+  // Handle the case of first time visitors and clients that don't store
+  // cookies (eg. web crawlers).
+  if (!isset($_COOKIE[session_name()])) {
+    $user = drupal_anonymous_user();
+    return '';
+  }
+
+  // Otherwise, if the session is still active, we have a record of the client's session in the database.
+  $user = (object) mongodb_collection(variable_get('mongodb_session', 'session'))->findOne(array('sid' => $sid));
+
+  // We found the client's session record and they are an authenticated,
+  // active user.
+  if ($user && $user->uid > 0 && $user->status == 1) {
+    // This is done to unserialize the data member of $user
+    $user = drupal_unpack($user);
+
+    // Add roles element to $user
+    $user->roles = array();
+    $user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
+    $result = db_query("SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = %d", $user->uid);
+    while ($role = db_fetch_object($result)) {
+      $user->roles[$role->rid] = $role->name;
+    }
+  }
+  // We didn't find the client's record (session has expired), or they are
+  // blocked, or they are an anonymous user.
+  else {
+    $session = isset($user->session) ? $user->session : '';
+    $user = drupal_anonymous_user($session);
+  }
+
+  return $user->session;
+}
+
+/**
+ * Session handler assigned by session_set_save_handler().
+ *
+ * This function will be called by PHP to store the current user's
+ * session, which Drupal saves to the database.
+ *
+ * This function should not be called directly. Session data should
+ * instead be accessed via the $_SESSION superglobal.
+ *
+ * @param $sid
+ *   Session ID.
+ * @param $value
+ *   Serialized array of the session data.
+ * @return
+ *   This function will always return TRUE.
+ */
+function sess_write($sid, $value) {
+  global $user;
+
+  if (!session_save_session()) {
+    // We don't have anything to do if we are not allowed to save the session.
+    return;
+  }
+
+  $fields = array(
+    'uid' => $user->uid,
+    'cache' => isset($user->cache) ? (int)$user->cache : 0,
+    'hostname' => ip_address(),
+    'session' => $value,
+    'timestamp' => $_SERVER['REQUEST_TIME'],
+  );
+  $key = array('sid' => $sid);
+
+  mongodb_collection(variable_get('mongodb_session', 'session'))
+    ->update($key, $key + $fields + (array)$user, array('upsert' => TRUE));
+
+  // Last access time is updated no more frequently than once every 180 seconds.
+  // This reduces contention in the users table.
+  if ($user->uid && $_SERVER['REQUEST_TIME'] - $user->access > variable_get('session_write_interval', 180)) {
+    db_query("UPDATE {users} SET access = %d WHERE uid = %d", $_SERVER['REQUEST_TIME'], $user->uid);
+  }
+
+  return TRUE;
+}
+
+/**
+ * Session handler assigned by session_set_save_handler().
+ *
+ * Cleanup a specific session.
+ *
+ * @param string $sid
+ *   Session ID.
+ */
+function sess_destroy_sid($sid) {
+  mongodb_collection(variable_get('mongodb_session', 'session'))
+    ->remove(array('sid' => $sid));
+}
+
+/**
+ * End a specific user's session(s).
+ *
+ * @param string $uid
+ *   User ID.
+ */
+function sess_destroy_uid($uid) {
+  mongodb_collection(variable_get('mongodb_session', 'session'))
+    ->remove(array('uid' => $uid));
+}
+
+/**
+ * Session handler assigned by session_set_save_handler().
+ *
+ * Cleanup stalled sessions.
+ *
+ * @param int $lifetime
+ *   The value of session.gc_maxlifetime, passed by PHP.
+ *   Sessions not updated for more than $lifetime seconds will be removed.
+ */
+function sess_gc($lifetime) {
+  // Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough
+  // value. For example, if you want user sessions to stay in your database
+  // for three weeks before deleting them, you need to set gc_maxlifetime
+  // to '1814400'. At that value, only after a user doesn't log in after
+  // three weeks (1814400 seconds) will his/her session be removed.
+  mongodb_collection(variable_get('mongodb_session', 'session'))
+    ->remove(array('timestamp' => array('$lt' => $_SERVER['REQUEST_TIME'] - $lifetime)));
+  return TRUE;
+}
diff --git a/mongodb_session/mongodb_session.info b/mongodb_session/mongodb_session.info
new file mode 100644
index 0000000..2bed6ca
--- /dev/null
+++ b/mongodb_session/mongodb_session.info
@@ -0,0 +1,6 @@
+
+name = MongoDB Session
+description = Store session information in MongoDB 
+package = MongoDB
+core = 6.x
+dependencies[] = mongodb
diff --git a/mongodb_session/mongodb_session.module b/mongodb_session/mongodb_session.module
new file mode 100644
index 0000000..ab9fd82
--- /dev/null
+++ b/mongodb_session/mongodb_session.module
@@ -0,0 +1,16 @@
+<?php
+/**
+ * @file
+ *   MongoDB Session implementation.
+ */
+
+/**
+ * Implements hook_simpletest_alter().
+ */
+function mongodb_session_simpletest_alter(&$groups) {
+  // An alternative session handler module would not want to run the original
+  // Session https handling test because it checks the sessions table in the
+  // database.
+  unset($groups['Session']);
+}
+
