Index: wp-includes/cron.php
===================================================================
--- wp-includes/cron.php	(revision 18084)
+++ wp-includes/cron.php	(working copy)
@@ -20,24 +20,23 @@
  * @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 )
 		return;
 
-	$crons = _get_cron_array();
-	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args );
+	// Create an object and apply filters for backwards compatibility
+	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => false, 'args' => $args, 'recurrence' => false, 'interval' => false );
+
 	$event = apply_filters('schedule_event', $event);
 
 	// A plugin disallowed this event
 	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->timestamp, $event->hook, $event->args, $event->recurrence, $event->interval );
 }
 
 /**
@@ -61,24 +60,23 @@
  * @return bool|null False on failure, null when complete with scheduling event.
  */
 function wp_schedule_event( $timestamp, $recurrence, $hook, $args = array()) {
-	$crons = _get_cron_array();
+	global $wp_cron_store;
+
 	$schedules = wp_get_schedules();
 
 	if ( !isset( $schedules[$recurrence] ) )
 		return false;
 
+	// Create an object and apply filters for backwards compatibility
 	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'schedule' => $recurrence, 'args' => $args, 'interval' => $schedules[$recurrence]['interval'] );
+
 	$event = apply_filters('schedule_event', $event);
 
 	// A plugin disallowed this event
 	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->timestamp, $event->hook, $event->args, $event->schedule, $event->interval );
 }
 
 /**
@@ -93,17 +91,22 @@
  * @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 )
+	$schedules = wp_get_schedules();
+	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 = $wp_cron_store->get_event( $hook, $timestamp, $args );
+		if ( $event )
+			$interval = $event->interval;
+	}
+
 	// Now we assume something is wrong and fail to schedule
 	if ( 0 == $interval )
 		return false;
@@ -134,14 +137,9 @@
  * 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;
+
+	$wp_cron_store->complete_event( $timestamp, $hook, $args );
 }
 
 /**
@@ -174,15 +172,14 @@
  * @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 = $wp_cron_store->get_event( $hook, 'next', $args );
+
+	if ( !$event )
 		return false;
-	foreach ( $crons as $timestamp => $cron ) {
-		if ( isset( $cron[$hook][$key] ) )
-			return $timestamp;
-	}
-	return false;
+
+	return $event->timestamp;
 }
 
 /**
@@ -193,6 +190,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();
@@ -214,8 +212,8 @@
 		return;
 
 	//sanity check
-	$crons = _get_cron_array();
-	if ( !is_array($crons) )
+	$crons = $wp_cron_store->get_events();
+	if ( empty($crons) )
 		return;
 
 	$keys = array_keys( $crons );
@@ -254,12 +252,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_events() )
 		return;
 
 	$local_time = time();
@@ -328,80 +327,168 @@
  * @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 = $wp_cron_store->get_event( $hook, 'next', $args );
+
+	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) )
+class WP_Cron_Store {
+	/**
+	 * Array of pending cron jobs
+	 */
+	protected $_cron_array = array();
+
+	/**
+	 * Marks the event as completed and removes it from the current instance of
+	 * $this->_cron_array
+	 *
+	 * @since ?
+	 *
+	 * @param int $timestamp
+	 * @param string $hook
+	 * @param array $args
+	 */
+	public function complete_event( $timestamp, $hook, $args ) {
+		$crons = $this->_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] );
+		$this->_set_cron_array( $crons );
+	}
+
+	/**
+	 * Searches for a scheduled event
+	 *
+	 * @since ?
+	 *
+	 * @param string $hook
+	 * @param int $timestamp
+	 * @param array $args
+	 *
+	 * @return obj|false $event object or false if it doesn't exist
+	 */
+	public function get_event( $hook, $timestamp, $args = array() ) {
+		$crons = $this->_get_cron_array();
+		$key = md5(serialize($args));
+		if ( empty($crons) )
+			return false;
+
+		if ( empty($timestamp) || 'next' == $timestamp ) {
+			foreach ( $crons as $cron_timestamp => $cron ) {
+				if ( isset( $cron[$hook][$key] ) )
+					return (object) array( 'hook' => $hook, 'args' => $args, 'timestamp' => $cron_timestamp, 'schedule' => $cron[$hook][$key]['schedule'], 'interval' => $cron[$hook][$key]['interval']);
+			}
+			return false;
+		}
+
+		if ( isset($crons[$timestamp][$hook][$key]) )
+			return (object) array( 'hook' => $hook, 'args' => $args, 'timestamp' => $timestamp, 'schedule' => $crons[$timestamp][$hook][$key]['schedule'], 'interval' => $crons[$timestamp][$hook][$key]['interval']);
+
 		return false;
+	}
 
-	if ( !isset($cron['version']) )
-		$cron = _upgrade_cron_array($cron);
+	/**
+	 * Returns an array of all pending jobs within the next 10 minutes
+	 *
+	 * @since ?
+	 *
+	 * @param array $args Unused
+	 *
+	 * @return array
+	 */
+	public function get_events( $args = array() ) {
+		return $this->_get_cron_array();
+	}
 
-	unset($cron['version']);
+	/**
+	 * Inserts a new event
+	 *
+	 * @since ?
+	 *
+	 * @param int $timestamp
+	 * @param string $hook
+	 * @param array $args
+	 * @param null|string $recurrence
+	 * @param null|int $interval
+	 */
+	public function insert_event( $timestamp, $hook, $args, $recurrence = null, $interval = null ) {
+		$crons = $this->_get_cron_array();
+		$key = md5(serialize($args));
 
-	return $cron;
-}
+		$crons[$timestamp][$hook][$key] = array( 'schedule' => $recurrence, 'args' => $args, 'interval' => $interval );
+		uksort( $crons, "strnatcasecmp" );
+		$this->_set_cron_array( $crons );
+	}
 
-/**
- * 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 );
-}
+	/**
+	 * Retrieve cron info array option.
+	 *
+	 * @since 2.1.0
+	 *
+	 * @return array CRON info array.
+	 */
+	protected function _get_cron_array()  {
+		$crons = get_option('cron', array());
+		if ( !is_array($crons) || empty($crons) )
+			return array();
 
-/**
- * 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;
+		if ( !isset($crons['version']) )
+			$crons = $this->_upgrade_cron_array($crons);
 
-	$new_cron = array();
+		unset($crons['version']);
 
-	foreach ( (array) $cron as $timestamp => $hooks) {
-		foreach ( (array) $hooks as $hook => $args ) {
-			$key = md5(serialize($args['args']));
-			$new_cron[$timestamp][$hook][$key] = $args;
+		return $crons;
+	}
+
+	/**
+	 * Updates the CRON option with the new CRON array.
+	 *
+	 * @since 2.1.0
+	 *
+	 * @param array $crons Cron info array from {@link _get_cron_array()}.
+	 */
+	protected function _set_cron_array( $crons = array() ) {
+		$crons['version'] = 2;
+		update_option( 'cron', $crons );
+	}
+
+	/**
+	 * Upgrade a Cron info array.
+	 *
+	 * This function upgrades the Cron info array to version 2.
+	 *
+	 * @since 2.1.0
+	 *
+	 * @param array $cron Cron info array from {@link _get_cron_array()}.
+	 * @return array An upgraded Cron info array.
+	 */
+	protected function _upgrade_cron_array($crons) {
+		if ( isset($crons['version']) && 2 == $crons['version'])
+			return $crons;
+
+		$new_crons = array();
+
+		foreach ( (array) $crons as $timestamp => $hooks) {
+			foreach ( (array) $hooks as $hook => $args ) {
+				$key = md5(serialize($args['args']));
+				$new_crons[$timestamp][$hook][$key] = $args;
+			}
 		}
+
+		$new_crons['version'] = 2;
+		update_option( 'cron', $new_crons );
+		return $new_crons;
 	}
-
-	$new_cron['version'] = 2;
-	update_option( 'cron', $new_cron );
-	return $new_cron;
 }
Index: wp-settings.php
===================================================================
--- wp-settings.php	(revision 18084)
+++ wp-settings.php	(working copy)
@@ -100,6 +100,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 . '/class-wp-walker.php' );
 require( ABSPATH . WPINC . '/class-wp-ajax-response.php' );
@@ -123,7 +131,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 18084)
+++ 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_events() )
 	die();
 
 $keys = array_keys( $crons );
