Index: wp-includes/cron.php
===================================================================
--- wp-includes/cron.php	(revision 15839)
+++ wp-includes/cron.php	(working copy)
@@ -33,11 +33,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_insert_event($event);
 }
 
 /**
@@ -72,11 +68,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_insert_event($event);
 }
 
 /**
@@ -97,11 +89,15 @@
 	$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_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 +128,8 @@
  * 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 );
+	$event = (object) array( 'hook' => $hook, 'timestamp' => $timestamp, 'args' => $args );
+	wp_cron_delete_event($event);
 }
 
 /**
@@ -172,15 +162,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) )
+	$event = (object) array( 'hook' => $hook, 'timestamp' => 'next', 'args' => $args );
+
+	$event = wp_cron_get_event( $event );
+
+	if ( !$event )
 		return false;
-	foreach ( $crons as $timestamp => $cron ) {
-		if ( isset( $cron[$hook][$key] ) )
-			return $timestamp;
-	}
-	return false;
+
+	return $event->timestamp;
 }
 
 /**
@@ -349,6 +338,62 @@
 // Private functions
 //
 
+function wp_cron_delete_event( $event ) {
+	if ( null !== $result = apply_filters('wp_cron_delete_event', null, $event) )
+		return $result;
+
+	$crons = _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] );
+	_set_cron_array( $crons );	
+}
+
+function wp_cron_get_event( $event ) {
+	if ( null !== $result = apply_filters('wp_cron_get_event', null, $event) )
+		return $result;
+
+	$crons = _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;
+	}
+
+	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 false;
+}
+
+function wp_cron_get_events( $args ) {
+	if ( null !== $result = apply_filters('wp_cron_get_events', null, $args) )
+		return $result;
+
+	// @todo
+	return null;
+}
+
+function wp_cron_insert_event( $event ) {
+	if ( null !== $result = apply_filters('wp_cron_insert_event', null, $event) )
+		return $result;
+
+	$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 );	
+}
+
 /**
  * Retrieve cron info array option.
  *
