Index: src/wp-includes/class.wp-dependencies.php
===================================================================
--- src/wp-includes/class.wp-dependencies.php	(revision 36589)
+++ src/wp-includes/class.wp-dependencies.php	(working copy)
@@ -100,14 +100,12 @@
 			if ( !in_array($handle, $this->done, true) && isset($this->registered[$handle]) ) {
 				/*
 				 * Attempt to process the item. If successful,
-				 * add the handle to the done array.
-				 *
-				 * Unset the item from the to_do array.
+				 * add the handle to the done array and unset the item from the to_do array.
 				 */
-				if ( $this->do_item( $handle, $group ) )
+				if ( $this->do_item( $handle, $group ) ) {
 					$this->done[] = $handle;
-
-				unset( $this->to_do[$key] );
+					unset( $this->to_do[$key] );
+				}
 			}
 		}
 
@@ -385,7 +383,7 @@
 		$group = (int) $group;
 
 		if ( $recursion )
-			$group = min($this->group, $group);
+			$this->group = $group = min($this->group, $group);
 		else
 			$this->group = $group;
 
Index: src/wp-includes/class.wp-scripts.php
===================================================================
--- src/wp-includes/class.wp-scripts.php	(revision 36589)
+++ src/wp-includes/class.wp-scripts.php	(working copy)
@@ -20,7 +20,6 @@
 	public $base_url; // Full URL with trailing slash
 	public $content_url;
 	public $default_version;
-	public $in_footer = array();
 	public $concat = '';
 	public $concat_version = '';
 	public $do_concat = false;
@@ -117,13 +116,9 @@
 			return false;
 
 		if ( 0 === $group && $this->groups[$handle] > 0 ) {
-			$this->in_footer[] = $handle;
 			return false;
 		}
 
-		if ( false === $group && in_array($handle, $this->in_footer, true) )
-			$this->in_footer = array_diff( $this->in_footer, (array) $handle );
-
 		$obj = $this->registered[$handle];
 
 		if ( null === $obj->ver ) {
@@ -218,6 +213,33 @@
 	}
 
 	/**
+	 * Register a script.
+	 *
+	 * Registers the script if no script of that name already exists.
+	 *
+	 * @access public
+	 * @since 4.5
+	 *
+	 * @param string $handle Unique script name.
+	 * @param string $src    The script url.
+	 * @param array  $deps   Optional. An array of script handle strings on which this script depends.
+	 * @param string $ver    Optional. Version (used for cache busting).
+	 * @param mixed  $args   Optional. Custom property of the script. NOT the class property $args. Examples: 1 for in_footer.
+	 * @return bool True on success, false on failure.
+	 */
+	public function add( $handle, $src, $deps = array(), $ver = false, $args = null ) {
+		$in_footer = ( $args === 1 );
+
+		$result = parent::add( $handle, $src, $deps, $ver, $in_footer ? null : $args );
+
+		if ( $in_footer && $result ) {
+			$this->add_data( $handle, 'group', 1 );
+		}
+
+		return $result;
+	}
+
+	/**
 	 * Localizes a script, only if the script has already been added
 	 *
 	 * @param string $handle
@@ -261,10 +283,7 @@
 	 * @return bool Not already in the group or a lower group
 	 */
 	public function set_group( $handle, $recursion, $group = false ) {
-		if ( isset( $this->registered[$handle]->args ) && $this->registered[$handle]->args === 1 )
-			$grp = 1;
-		else
-			$grp = (int) $this->get_data( $handle, 'group' );
+		$grp = (int) $this->get_data( $handle, 'group' );
 
 		if ( false !== $group && $grp > $group )
 			$grp = $group;
Index: tests/phpunit/tests/dependencies/jquery.php
===================================================================
--- tests/phpunit/tests/dependencies/jquery.php	(revision 36589)
+++ tests/phpunit/tests/dependencies/jquery.php	(working copy)
@@ -81,4 +81,35 @@
 
 		unset( $GLOBALS['wp_scripts'] );
 	}
+
+	/**
+	 * Test placing of jquery in footer.
+	 * @ticket 25247
+	 */
+	function test_jquery_in_footer() {
+		$scripts = new WP_Scripts;
+		$scripts->add( 'jquery', false, array( 'jquery-core', 'jquery-migrate' ) );
+		$scripts->add( 'jquery-core', '/jquery.js', array() );
+		$scripts->add( 'jquery-migrate', "/jquery-migrate.js", array() );
+
+		$scripts->enqueue( 'jquery' );
+
+		$object = $scripts->query( 'jquery' );
+		$object->add_data( 'group', 1 );
+		foreach( $object->deps as $dep ) {
+			$scripts->add_data( $dep, 'group', 1 );
+		}
+
+		$this->expectOutputRegex( '/^(?:<script[^>]+><\/script>\\n){2}$/' );
+
+		$scripts->do_items( false, 0 );
+		// Could do $this->assertContains( 'jquery', $scripts->done );
+		$this->assertNotContains( 'jquery-core', $scripts->done, 'jquery-core should be in footer but is in head' );
+		$this->assertNotContains( 'jquery-migrate', $scripts->done, 'jquery-migrate should be in footer but is in head' );
+
+		$scripts->do_items( false, 1 );
+		$this->assertContains( 'jquery', $scripts->done );
+		$this->assertContains( 'jquery-core', $scripts->done, 'jquery-core in footer' );
+		$this->assertContains( 'jquery-migrate', $scripts->done, 'jquery-migrate in footer' );
+	}
 }
Index: tests/phpunit/tests/dependencies/scripts.php
===================================================================
--- tests/phpunit/tests/dependencies/scripts.php	(revision 36589)
+++ tests/phpunit/tests/dependencies/scripts.php	(working copy)
@@ -157,6 +157,51 @@
 	}
 
 	/**
+	 * Test mismatch of groups in dependencies outputs all scripts in right order.
+	 * @ticket 25247
+	 */
+	public function test_group_mismatch_in_deps() {
+		$scripts = new WP_Scripts;
+		$scripts->add( 'one', 'one', array(), 'v1', 1 ); 
+		$scripts->add( 'two', 'two', array( 'one' ) ); 
+		$scripts->add( 'three', 'three', array( 'two' ), 'v1', 1 ); 
+
+		$scripts->enqueue( array( 'three' ) );
+
+		$this->expectOutputRegex( '/^(?:<script[^>]+><\/script>\\n){7}$/' );
+
+		$scripts->do_items( false, 0 );
+		$this->assertContains( 'one', $scripts->done );
+		$this->assertContains( 'two', $scripts->done );
+		$this->assertNotContains( 'three', $scripts->done );
+
+		$scripts->do_items( false, 1 );
+		$this->assertContains( 'one', $scripts->done );
+		$this->assertContains( 'two', $scripts->done );
+		$this->assertContains( 'three', $scripts->done );
+
+		$scripts = new WP_Scripts;
+		$scripts->add( 'one', 'one', array(), 'v1', 1 ); 
+		$scripts->add( 'two', 'two', array( 'one' ), 'v1', 1 ); 
+		$scripts->add( 'three', 'three', array( 'one' ) ); 
+		$scripts->add( 'four', 'four', array( 'two', 'three' ), 'v1', 1 ); 
+
+		$scripts->enqueue( array( 'four' ) );
+
+		$scripts->do_items( false, 0 );
+		$this->assertContains( 'one', $scripts->done );
+		$this->assertNotContains( 'two', $scripts->done );
+		$this->assertContains( 'three', $scripts->done );
+		$this->assertNotContains( 'four', $scripts->done );
+
+		$scripts->do_items( false, 1 );
+		$this->assertContains( 'one', $scripts->done );
+		$this->assertContains( 'two', $scripts->done );
+		$this->assertContains( 'three', $scripts->done );
+		$this->assertContains( 'four', $scripts->done );
+	}
+
+	/**
 	 * Testing 'wp_register_script' return boolean success/failure value.
 	 *
 	 * @ticket 31126
@@ -199,4 +244,25 @@
 		$this->assertContains( home_url( 'bar.js' ), $footer );
 		$this->assertContains( home_url( 'baz.js' ), $footer );
 	}
+
+	/**
+	 * @ticket 35873
+	 */
+	function test_wp_register_script_with_dependencies_in_head_and_footer() {
+		wp_register_script( 'parent', home_url( 'parent.js' ), array( 'child' ), '1', true ); // in footer
+		wp_register_script( 'child', home_url( 'child.js' ), array( 'grandchild' ), '1', false ); // in head
+		wp_register_script( 'grandchild', home_url( 'grandchild.js' ), array(), '1', true ); // in footer
+
+		wp_enqueue_script( 'parent' );
+
+		$header = get_echo( 'wp_print_head_scripts' );
+		$footer = get_echo( 'wp_print_footer_scripts' );
+
+		$expected_header  = "<script type='text/javascript' src='http://example.org/grandchild.js?ver=1'></script>\n";
+		$expected_header .= "<script type='text/javascript' src='http://example.org/child.js?ver=1'></script>\n";
+		$expected_footer  = "<script type='text/javascript' src='http://example.org/parent.js?ver=1'></script>\n";
+
+		$this->assertEquals( $expected_header, $header );
+		$this->assertEquals( $expected_footer, $footer );
+	}
 }
