Index: src/wp-includes/class-wp-comment-query.php
===================================================================
--- src/wp-includes/class-wp-comment-query.php	(revision 34068)
+++ src/wp-includes/class-wp-comment-query.php	(working copy)
@@ -136,6 +136,8 @@
 	 *     @type string       $order               How to order retrieved comments. Accepts 'ASC', 'DESC'.
 	 *                                             Default: 'DESC'.
 	 *     @type int          $parent              Parent ID of comment to retrieve children of. Default empty.
+	 *     @type array        $parent__in          Array of parent IDs of comments to retrieve children for. Default empty.
+	 *     @type array        $parent__not_in      Array of parent IDs of comments *not* to retrieve children for. Default empty.
 	 *     @type array        $post_author__in     Array of author IDs to retrieve comments for. Default empty.
 	 *     @type array        $post_author__not_in Array of author IDs *not* to retrieve comments for. Default empty.
 	 *     @type int          $post_ID             Currently unused.
@@ -387,7 +389,7 @@
 					$_order = $_value;
 				}
 
-				if ( ! $found_orderby_comment_ID && 'comment_ID' === $_orderby ) {
+				if ( ! $found_orderby_comment_ID && in_array( $_orderby, array( 'comment_ID', 'comment__in' ) ) ) {
 					$found_orderby_comment_ID = true;
 				}
 
@@ -397,6 +399,11 @@
 					continue;
 				}
 
+				if ( 'comment__in' === $_orderby ) {
+					$orderby_array[] = $parsed;
+					continue;
+				}
+
 				$orderby_array[] = $parsed . ' ' . $this->parse_order( $_order );
 			}
 
@@ -486,6 +493,16 @@
 			$where[] = "$wpdb->comments.comment_ID NOT IN ( " . implode( ',', wp_parse_id_list( $this->query_vars['comment__not_in'] ) ) . ' )';
 		}
 
+		// Parse comment parent IDs for an IN clause.
+		if ( ! empty( $this->query_vars['parent__in'] ) ) {
+			$where[] = 'comment_parent IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['parent__in'] ) ) . ' )';
+		}
+
+		// Parse comment parent IDs for a NOT IN clause.
+		if ( ! empty( $this->query_vars['parent__not_in'] ) ) {
+			$where[] = 'comment_parent NOT IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['parent__not_in'] ) ) . ' )';
+		}
+
 		// Parse comment post IDs for an IN clause.
 		if ( ! empty( $this->query_vars['post__in'] ) ) {
 			$where[] = 'comment_post_ID IN ( ' . implode( ',', wp_parse_id_list( $this->query_vars['post__in'] ) ) . ' )';
@@ -759,6 +776,9 @@
 			$parsed = "$wpdb->commentmeta.meta_value";
 		} elseif ( $orderby == 'meta_value_num' ) {
 			$parsed = "$wpdb->commentmeta.meta_value+0";
+		} elseif ( $orderby == 'comment__in' ) {
+			$comment__in = implode( ',', array_map( 'absint', $this->query_vars['comment__in'] ) );
+			$parsed = "FIELD( {$wpdb->comments}.comment_ID, $comment__in )";
 		} elseif ( in_array( $orderby, $allowed_keys ) ) {
 
 			if ( isset( $meta_query_clauses[ $orderby ] ) ) {
Index: src/wp-includes/comment-functions.php
===================================================================
--- src/wp-includes/comment-functions.php	(revision 34068)
+++ src/wp-includes/comment-functions.php	(working copy)
@@ -761,6 +761,9 @@
 function get_comment_pages_count( $comments = null, $per_page = null, $threaded = null ) {
 	global $wp_query;
 
+	if ( null === $comments && !empty($wp_query->comment_pages_count) )
+		return $wp_query->comment_pages_count;
+
 	if ( null === $comments && null === $per_page && null === $threaded && !empty($wp_query->max_num_comment_pages) )
 		return $wp_query->max_num_comment_pages;
 
Index: src/wp-includes/comment-template.php
===================================================================
--- src/wp-includes/comment-template.php	(revision 34069)
+++ src/wp-includes/comment-template.php	(working copy)
@@ -1117,6 +1117,49 @@
 	}
 }
 
+function wp_comments_per_page() {
+	$per_page = (int) get_query_var( 'comments_per_page' );
+	if ( 0 === $per_page ) {
+		$per_page = (int) get_option( 'comments_per_page' );
+	}
+	return $per_page;
+}
+
+function wp_comment_pages_count( $total, $top_level ) {
+	if ( ! get_option( 'page_comments' ) ) {
+		return 1;
+	}
+
+	$per_page = wp_comments_per_page();
+	if ( 0 === $per_page ) {
+		return 1;
+	}
+
+	$threaded = get_option( 'thread_comments' );
+
+	if ( $threaded ) {
+		$count = ceil( $top_level / $per_page );
+	} else {
+		$count = ceil( $total / $per_page );
+	}
+
+	return $count;
+}
+
+function wp_threaded_comment_ids( $comment_ids, $comment_args ) {
+	$threaded_ids = array();
+	$args = $comment_args;
+	unset( $args['parent'] );
+
+	do {
+		$threaded_ids = array_merge( $threaded_ids, $comment_ids );
+		$args['parent__in'] = $comment_ids;
+		$comment_ids = get_comments( $args );
+	} while ( count( $comment_ids ) );
+
+	return $threaded_ids;
+}
+
 /**
  * Load the comment template specified in $file.
  *
@@ -1186,6 +1229,7 @@
 
 	$comment_args = array(
 		'order'   => 'ASC',
+		'fields'  => 'ids',
 		'orderby' => 'comment_date_gmt',
 		'status'  => 'approve',
 		'post_id' => $post->ID,
@@ -1197,6 +1241,41 @@
 		$comment_args['include_unapproved'] = array( $comment_author_email );
 	}
 
+	$top_level = 0;
+	$threaded = get_option( 'thread_comments' );
+	if ( $threaded ) {
+		$comment_args['parent'] = 0;
+		// array of all top-level comment IDs for the post
+		$comment_ids = get_comments( $comment_args );
+		$top_level = count( $comment_ids );
+	} else {
+		// array of all comment IDs for the post
+		$comment_ids = get_comments( $comment_args );
+	}
+
+	$pages = wp_comment_pages_count( $post->comment_count, $top_level );
+	$wp_query->comment_pages_count = $pages;
+	$wp_query->comment_pages_page = 1;
+
+	if ( $pages > 1 ) {
+		$per_page = wp_comments_per_page();
+		$page = (int) get_query_var( 'cpage' );
+		if ( 0 === $page ) {
+			$page = 1;
+		}
+		$wp_query->comment_pages_page = $page;
+
+		$comment_ids = array_slice( $comment_ids, ( $page - 1 ) * $per_page, $per_page );
+		if ( $threaded ) {
+			$comment_ids = wp_threaded_comment_ids( $comment_ids, $comment_args );
+		}
+
+		$comment_args['comment__in'] = $comment_ids;
+		$comment_args['orderby'] = 'comment__in';
+		unset( $comment_args['order'] );
+	}
+
+	unset( $comment_args['parent'], $comment_args['fields'] );
 	$comments = get_comments( $comment_args );
 
 	/**
@@ -1818,6 +1897,10 @@
 	if ( null === $r['reverse_top_level'] )
 		$r['reverse_top_level'] = ( 'desc' == get_option('comment_order') );
 
+	if ( null === $comments && 1 < $wp_query->comment_pages_count ) {
+		$r['page'] = 1;
+	}
+
 	if ( empty( $r['walker'] ) ) {
 		$walker = new Walker_Comment;
 	} else {
