Index: wp-includes/update.php
===================================================================
--- wp-includes/update.php	(revision 15839)
+++ wp-includes/update.php	(working copy)
@@ -334,6 +334,22 @@
 	wp_update_themes();
 }
 
+/**
+ * Schedule core, theme, and plugin update checks.
+ *
+ * @since 3.1.0
+ */
+function wp_schedule_update_checks() {
+	if ( !wp_next_scheduled('wp_version_check') && !defined('WP_INSTALLING') )
+		wp_schedule_event(time(), 'twicedaily', 'wp_version_check');
+
+	if ( !wp_next_scheduled('wp_update_plugins') && !defined('WP_INSTALLING') )
+		wp_schedule_event(time(), 'twicedaily', 'wp_update_plugins');
+
+	if ( !wp_next_scheduled('wp_update_themes') && !defined('WP_INSTALLING') )
+		wp_schedule_event(time(), 'twicedaily', 'wp_update_themes');
+}
+
 if ( ! is_main_site() )
 	return;
 
@@ -352,13 +368,6 @@
 add_action( 'admin_init', '_maybe_update_themes' );
 add_action( 'wp_update_themes', 'wp_update_themes' );
 
-if ( !wp_next_scheduled('wp_version_check') && !defined('WP_INSTALLING') )
-	wp_schedule_event(time(), 'twicedaily', 'wp_version_check');
+add_action('init', 'wp_schedule_update_checks');
 
-if ( !wp_next_scheduled('wp_update_plugins') && !defined('WP_INSTALLING') )
-	wp_schedule_event(time(), 'twicedaily', 'wp_update_plugins');
-
-if ( !wp_next_scheduled('wp_update_themes') && !defined('WP_INSTALLING') )
-	wp_schedule_event(time(), 'twicedaily', 'wp_update_themes');
-
 ?>
Index: wp-includes/cron.php
===================================================================
--- wp-includes/cron.php	(revision 15839)
+++ wp-includes/cron.php	(working copy)
@@ -20,6 +20,8 @@
  * @param array $args Optional. Arguments to pass to the hook's callback function.
  */
 function wp_schedule_single_event( $timestamp, $hook, $args = array()) {
+	global $wp_cron_store;
+
 	// don't schedule a duplicate if there's already an identical event due in the next 10 minutes
 	$next = wp_next_scheduled($hook, $args);
 	if ( $next && $next <= $timestamp + 600 )
@@ -33,11 +35,7 @@
 	if ( ! $event )
 		return false;
 
-	$key = md5(serialize($event->args));
-
-	$crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args );
-	uksort( $crons, "strnatcasecmp" );
-	_set_cron_array( $crons );
+	$wp_cron_store->insert_event($event);
 }
 
 /**
@@ -59,6 +57,8 @@
  * @return bool|null False on failure, null when complete with scheduling event.
  */
 function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
+	global $wp_cron_store;
+
 	$crons = _get_cron_array();
 	$schedules = wp_get_schedules();
 
@@ -72,11 +72,7 @@
 	if ( ! $event )
 		return false;
 
-	$key = md5(serialize($event->args));
-
-	$crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args, 'interval' => $event->interval );
-	uksort( $crons, "strnatcasecmp" );
-	_set_cron_array( $crons );
+	$wp_cron_store->insert_event($event);
 }
 
 /**
@@ -91,17 +87,20 @@
  * @return bool|null False on failure. Null when event is rescheduled.
  */
 function wp_reschedule_event( $timestamp, $recurrence, $hook, $args = array()) {
-	$crons = _get_cron_array();
-	$schedules = wp_get_schedules();
-	$key = md5(serialize($args));
+	global $wp_cron_store;
+
 	$interval = 0;
 
 	// First we try to get it from the schedule
-	if ( 0 == $interval )
+	if ( isset($schedules[$recurrence]) )
 		$interval = $schedules[$recurrence]['interval'];
 	// Now we try to get it from the saved interval in case the schedule disappears
-	if ( 0 == $interval )
-		$interval = $crons[$timestamp][$hook][$key]['interval'];
+	if ( 0 == $interval ) {
+		$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'args' => $args );
+		$event = $wp_cron_store->get_event( $event );
+		if ( $event )
+			$interval = $event->interval;
+	}
 	// Now we assume something is wrong and fail to schedule
 	if ( 0 == $interval )
 		return false;
@@ -132,14 +131,10 @@
  * as those used when originally scheduling the event.
  */
 function wp_unschedule_event( $timestamp, $hook, $args = array() ) {
-	$crons = _get_cron_array();
-	$key = md5(serialize($args));
-	unset( $crons[$timestamp][$hook][$key] );
-	if ( empty($crons[$timestamp][$hook]) )
-		unset( $crons[$timestamp][$hook] );
-	if ( empty($crons[$timestamp]) )
-		unset( $crons[$timestamp] );
-	_set_cron_array( $crons );
+	global $wp_cron_store;
+
+	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'args' => $args );
+	$wp_cron_store->delete_event($event);
 }
 
 /**
@@ -172,15 +167,16 @@
  * @return bool|int The UNIX timestamp of the next time the scheduled event will occur.
  */
 function wp_next_scheduled( $hook, $args = array() ) {
-	$crons = _get_cron_array();
-	$key = md5(serialize($args));
-	if ( empty($crons) )
+	global $wp_cron_store;
+
+	$event = (object) array( 'hook' => $hook, 'timestamp' => 'next', 'args' => $args );
+
+	$event = $wp_cron_store->get_event( $event );
+
+	if ( !$event )
 		return false;
-	foreach ( $crons as $timestamp => $cron ) {
-		if ( isset( $cron[$hook][$key] ) )
-			return $timestamp;
-	}
-	return false;
+
+	return $event->timestamp;
 }
 
 /**
@@ -191,6 +187,7 @@
  * @return null Cron could not be spawned, because it is not needed to run.
  */
 function spawn_cron( $local_time = 0 ) {
+	global $wp_cron_store;
 
 	if ( !$local_time )
 		$local_time = time();
@@ -220,7 +217,7 @@
 		return;
 
 	//sanity check
-	$crons = _get_cron_array();
+	$crons = $wp_cron_store->_get_cron_array();
 	if ( !is_array($crons) )
 		return;
 
@@ -260,12 +257,13 @@
  * @return null When doesn't need to run Cron.
  */
 function wp_cron() {
+	global $wp_cron_store;
 
 	// Prevent infinite loops caused by lack of wp-cron.php
 	if ( strpos($_SERVER['REQUEST_URI'], '/wp-cron.php') !== false || ( defined('DISABLE_WP_CRON') && DISABLE_WP_CRON ) )
 		return;
 
-	if ( false === $crons = _get_cron_array() )
+	if ( false === $crons = $wp_cron_store->_get_cron_array() )
 		return;
 
 	$local_time = time();
@@ -334,82 +332,129 @@
  * @return string|bool False, if no schedule. Schedule on success.
  */
 function wp_get_schedule($hook, $args = array()) {
-	$crons = _get_cron_array();
-	$key = md5(serialize($args));
-	if ( empty($crons) )
+	global $wp_cron_store;
+
+	$event = (object) array( 'hook' => $hook, 'timestamp' => 'next', 'args' => $args );
+
+	$event = $wp_cron_store->get_event( $event );
+
+	if ( !$event )
 		return false;
-	foreach ( $crons as $timestamp => $cron ) {
-		if ( isset( $cron[$hook][$key] ) )
-			return $cron[$hook][$key]['schedule'];
-	}
-	return false;
+
+	return $event->schedule;
 }
 
 //
 // Private functions
 //
 
-/**
- * Retrieve cron info array option.
- *
- * @since 2.1.0
- * @access private
- *
- * @return array CRON info array.
- */
-function _get_cron_array()  {
-	$cron = get_option('cron');
-	if ( ! is_array($cron) )
-		return false;
+class WP_Cron_Store {
+	function delete_event( $event ) {
+		$crons = $this->_get_cron_array();
+		$key = md5(serialize($event->args));
+		unset( $crons[$event->timestamp][$event->hook][$key] );
+		if ( empty($crons[$event->timestamp][$event->hook]) )
+			unset( $crons[$event->timestamp][$event->hook] );
+		if ( empty($crons[$event->timestamp]) )
+			unset( $crons[$event->timestamp] );
+		$this->_set_cron_array( $crons );	
+	}
 
-	if ( !isset($cron['version']) )
-		$cron = _upgrade_cron_array($cron);
+	function get_event( $event ) {
+		$crons = $this->_get_cron_array();
+		$key = md5(serialize($event->args));
+		if ( empty($crons) )
+			return false;
+	
+		if ( empty($event->timestamp) || 'next' == $event->timestamp ) {
+			foreach ( $crons as $timestamp => $cron ) {
+				if ( isset( $cron[$event->hook][$key] ) )
+					return (object) array( 'hook' => $event->hook, 'args' => $event->args, 'timestamp' => $timestamp, 'schedule' => $cron[$event->hook][$key]['schedule'], 'interval' => $cron[$event->hook][$key]['interval']);
+			}
+			return false;
+		}
 
-	unset($cron['version']);
+		if ( isset($cron[$event->timestamp][$event->hook][$key]) )
+			return (object) array( 'hook' => $event->hook, 'args' => $event->args, 'timestamp' => $event->timestamp, 'schedule' => $cron[$event->timestamp][$event->hook][$key]['schedule'], 'interval' => $cron[$event->timestamp][$event->hook][$key]['interval']);
 
-	return $cron;
-}
-
-/**
- * Updates the CRON option with the new CRON array.
- *
- * @since 2.1.0
- * @access private
- *
- * @param array $cron Cron info array from {@link _get_cron_array()}.
- */
-function _set_cron_array($cron) {
-	$cron['version'] = 2;
-	update_option( 'cron', $cron );
-}
-
-/**
- * Upgrade a Cron info array.
- *
- * This function upgrades the Cron info array to version 2.
- *
- * @since 2.1.0
- * @access private
- *
- * @param array $cron Cron info array from {@link _get_cron_array()}.
- * @return array An upgraded Cron info array.
- */
-function _upgrade_cron_array($cron) {
-	if ( isset($cron['version']) && 2 == $cron['version'])
+		return false;
+	}
+	
+	function get_events( $args ) {
+		// @todo
+		return null;
+	}
+	
+	function insert_event( $event ) {
+		$key = md5(serialize($event->args));
+	
+		$crons[$event->timestamp][$event->hook][$key] = array( 'schedule' => $event->schedule, 'args' => $event->args, 'interval' => $event->interval );
+		uksort( $crons, "strnatcasecmp" );
+		$this->_set_cron_array( $crons );	
+	}
+	
+	/**
+	 * Retrieve cron info array option.
+	 *
+	 * @since 2.1.0
+	 * @access private
+	 *
+	 * @return array CRON info array.
+	 */
+	function _get_cron_array()  {
+		$cron = get_option('cron');
+		if ( ! is_array($cron) )
+			return false;
+	
+		if ( !isset($cron['version']) )
+			$cron = $this->_upgrade_cron_array($cron);
+	
+		unset($cron['version']);
+	
 		return $cron;
-
-	$new_cron = array();
-
-	foreach ( (array) $cron as $timestamp => $hooks) {
-		foreach ( (array) $hooks as $hook => $args ) {
-			$key = md5(serialize($args['args']));
-			$new_cron[$timestamp][$hook][$key] = $args;
+	}
+	
+	/**
+	 * Updates the CRON option with the new CRON array.
+	 *
+	 * @since 2.1.0
+	 * @access private
+	 *
+	 * @param array $cron Cron info array from {@link _get_cron_array()}.
+	 */
+	function _set_cron_array($cron) {
+		$cron['version'] = 2;
+		update_option( 'cron', $cron );
+	}
+	
+	/**
+	 * Upgrade a Cron info array.
+	 *
+	 * This function upgrades the Cron info array to version 2.
+	 *
+	 * @since 2.1.0
+	 * @access private
+	 *
+	 * @param array $cron Cron info array from {@link _get_cron_array()}.
+	 * @return array An upgraded Cron info array.
+	 */
+	function _upgrade_cron_array($cron) {
+		if ( isset($cron['version']) && 2 == $cron['version'])
+			return $cron;
+	
+		$new_cron = array();
+	
+		foreach ( (array) $cron as $timestamp => $hooks) {
+			foreach ( (array) $hooks as $hook => $args ) {
+				$key = md5(serialize($args['args']));
+				$new_cron[$timestamp][$hook][$key] = $args;
+			}
 		}
+	
+		$new_cron['version'] = 2;
+		update_option( 'cron', $new_cron );
+		return $new_cron;
 	}
-
-	$new_cron['version'] = 2;
-	update_option( 'cron', $new_cron );
-	return $new_cron;
 }
 
 // stub for checking server timer accuracy, using outside standard time sources
Index: wp-settings.php
===================================================================
--- wp-settings.php	(revision 15839)
+++ wp-settings.php	(working copy)
@@ -99,6 +99,14 @@
 // Run the installer if WordPress is not installed.
 wp_not_installed();
 
+// Load cron
+require_once( ABSPATH . WPINC . '/cron.php' );
+if ( file_exists( WP_CONTENT_DIR . '/cron.php' ) )
+	require_once( WP_CONTENT_DIR . '/cron.php' );
+
+if ( !isset( $wp_cron_store ) )
+	$wp_cron_store = new WP_Cron_Store;
+
 // Load most of WordPress.
 require( ABSPATH . WPINC . '/formatting.php' );
 require( ABSPATH . WPINC . '/capabilities.php' );
@@ -120,7 +128,6 @@
 require( ABSPATH . WPINC . '/bookmark.php' );
 require( ABSPATH . WPINC . '/bookmark-template.php' );
 require( ABSPATH . WPINC . '/kses.php' );
-require( ABSPATH . WPINC . '/cron.php' );
 require( ABSPATH . WPINC . '/deprecated.php' );
 require( ABSPATH . WPINC . '/script-loader.php' );
 require( ABSPATH . WPINC . '/taxonomy.php' );
Index: wp-cron.php
===================================================================
--- wp-cron.php	(revision 15839)
+++ wp-cron.php	(working copy)
@@ -26,7 +26,7 @@
 	require_once('./wp-load.php');
 }
 
-if ( false === $crons = _get_cron_array() )
+if ( false === $crons = $wp_cron_store->_get_cron_array() )
 	die();
 
 $keys = array_keys( $crons );
