Index: src/wp-admin/css/edit.css
===================================================================
--- src/wp-admin/css/edit.css	(revision 29485)
+++ src/wp-admin/css/edit.css	(working copy)
@@ -405,6 +405,19 @@
 }
 /* end editor-expand.js override */
 
+#poststuff #post-body #postbox-container-1.pinned {
+	position: fixed;
+	margin: 0;
+	top: 56px;
+	bottom: 0;
+	right: 20px;
+	transition: top 200ms;
+}
+
+#postbox-container-1 #side-sortables {
+	padding-bottom: 1px;
+}
+
 #timestampdiv select {
 	height: 21px;
 	line-height: 14px;
Index: src/wp-admin/js/editor-expand.js
===================================================================
--- src/wp-admin/js/editor-expand.js	(revision 29485)
+++ src/wp-admin/js/editor-expand.js	(working copy)
@@ -16,6 +16,10 @@
 		$textEditorClone = $( '<div id="content-textarea-clone"></div>' ),
 		$bottom = $( '#post-status-info' ),
 		$statusBar,
+		$sideSortables = $( '#side-sortables' ),
+		$postboxContainer = $('#postbox-container-1'),
+		$postBodyContent = $('#post-body-content'),
+		$postBody = $('#post-body'),
 		fullscreen = window.wp.editor && window.wp.editor.fullscreen,
 		mceEditor,
 		mceBind = function(){},
@@ -22,7 +26,13 @@
 		mceUnbind = function(){},
 		fixedTop = false,
 		fixedBottom = false,
-		scrollTimer;
+		fixedSide = false,
+		scrolledSide = false,
+		scrollTimer,
+		lastScrollPosition = 0,
+		pageYOffsetAtTop = 130,
+		textEditorClonePaddingTop = 37,
+		autoresizeMinHeight = $window.height() - 310;
 
 	$textEditorClone.insertAfter( $textEditor );
 
@@ -31,7 +41,7 @@
 		'font-size': $textEditor.css( 'font-size' ),
 		'line-height': $textEditor.css( 'line-height' ),
 		'padding': $textEditor.css( 'padding' ),
-		'padding-top': 37,
+		'padding-top': textEditorClonePaddingTop,
 		'white-space': 'pre-wrap',
 		'word-wrap': 'break-word'
 	} );
@@ -88,8 +98,8 @@
 
 		hiddenHeight = $textEditorClone.height();
 
-		if ( hiddenHeight < 300 ) {
-			hiddenHeight = 300;
+		if ( hiddenHeight < autoresizeMinHeight ) {
+			hiddenHeight = autoresizeMinHeight;
 		}
 
 		if ( hiddenHeight === textEditorHeight ) {
@@ -112,7 +122,7 @@
 		mceEditor = editor;
 
 		// Set the minimum height to the initial viewport height.
-		editor.settings.autoresize_min_height = 300;
+		editor.settings.autoresize_min_height = autoresizeMinHeight;
 
 		// Get the necessary UI elements.
 		$visualTop = $contentWrap.find( '.mce-toolbar-grp' );
@@ -218,9 +228,10 @@
 			adminBarHeight = windowWidth > 600 ? $adminBar.height() : 0,
 			resize = type !== 'scroll',
 			visual = ( mceEditor && ! mceEditor.isHidden() ),
-			buffer = 200,
+			buffer = autoresizeMinHeight + adminBarHeight,
+			postBodyTop = $postBody.offset().top,
 			$top, $editor,
-			toolsHeight, topPos, topHeight, editorPos, editorHeight, editorWidth, statusBarHeight;
+			toolsHeight, topPos, topHeight, editorPos, editorHeight, editorWidth, statusBarHeight, sideScrollTrigger;
 
 		if ( visual ) {
 			$top = $visualTop;
@@ -236,6 +247,7 @@
 		editorPos = $editor.offset().top;
 		editorHeight = $editor.outerHeight();
 		editorWidth = $editor.outerWidth();
+		borderWidth = 1;
 		statusBarHeight = visual ? $statusBar.outerHeight() : 0;
 
 		// Maybe pin the top.
@@ -256,7 +268,7 @@
 			$tools.css( {
 				position: 'fixed',
 				top: adminBarHeight,
-				width: editorWidth + 2
+				width: editorWidth + ( borderWidth * 2 )
 			} );
 		// Maybe unpin the top.
 		} else if ( fixedTop || resize ) {
@@ -287,7 +299,7 @@
 
 				$tools.css( {
 					position: 'absolute',
-					top: editorHeight - buffer + 1, // border
+					top: editorHeight - buffer + borderWidth, // border
 					width: $contentWrap.width()
 				} );
 			}
@@ -295,18 +307,18 @@
 
 		// Maybe adjust the bottom bar.
 		if ( ( ! fixedBottom || resize ) &&
-				// + 1 for the border around the .wp-editor-container.
-				( windowPos + windowHeight ) <= ( editorPos + editorHeight + bottomHeight + statusBarHeight + 1 ) ) {
+				// +[n] for the border around the .wp-editor-container.
+				( windowPos + windowHeight ) <= ( editorPos + editorHeight + bottomHeight + statusBarHeight + borderWidth ) ) {
 			fixedBottom = true;
 
 			$bottom.css( {
 				position: 'fixed',
 				bottom: 0,
-				width: editorWidth + 2,
+				width: editorWidth + ( borderWidth * 2 ),
 				borderTop: '1px solid #dedede'
 			} );
 		} else if ( ( fixedBottom || resize ) &&
-				( windowPos + windowHeight ) > ( editorPos + editorHeight + bottomHeight + statusBarHeight - 1 ) ) {
+				( windowPos + windowHeight ) > ( editorPos + editorHeight + bottomHeight + statusBarHeight - borderWidth ) ) {
 			fixedBottom = false;
 
 			$bottom.css( {
@@ -317,6 +329,41 @@
 			} );
 		}
 
+		// The sidebar is on the left and the scrolling height is large enough, pin it.
+		if ( $postboxContainer.width() < 300 && windowWidth > 600 &&
+			$document.height() > ( $sideSortables.height() + postBodyTop + 120 ) ) {
+
+			if ( ! fixedSide && ( postBodyTop - 56 ) < windowPos ) {
+				fixedSide = true;
+				$postboxContainer.addClass( 'pinned' );
+			} else if ( fixedSide ) {
+				if ( ( postBodyTop - 56 ) >= windowPos ) {
+					fixedSide = false;
+					$postboxContainer.removeClass( 'pinned' );
+				}
+			}
+
+			if ( fixedSide && windowPos > lastScrollPosition ) {
+				// Scrolling down
+				sideScrollTrigger = ( $sideSortables.height() - ( windowHeight - 56 ) );
+
+				if ( ! scrolledSide && sideScrollTrigger > 1 && windowPos > sideScrollTrigger && windowPos > $wrap.offset().top ) {
+					scrolledSide = true;
+					$postboxContainer.css( 'top', -( sideScrollTrigger - 36 ) );
+				}
+			} else if ( scrolledSide && windowPos < lastScrollPosition ) {
+				scrolledSide = false;
+				$postboxContainer.css( 'top', '' );
+			}
+
+			lastScrollPosition = windowPos;
+		} else {
+			// Unpin
+			$postboxContainer.removeClass( 'pinned' );
+			$postboxContainer.css( 'top', '' );
+			scrolledSide = fixedSide = false;
+		}
+
 		if ( resize ) {
 			$contentWrap.css( {
 				paddingTop: $tools.outerHeight()
@@ -354,7 +401,7 @@
 	function on() {
 		// Scroll to the top when triggering this from JS.
 		// Ensures toolbars are pinned properly.
-		if ( window.pageYOffset && window.pageYOffset > 130 ) {
+		if ( window.pageYOffset && window.pageYOffset > pageYOffsetAtTop ) {
 			window.scrollTo( window.pageXOffset, 0 );
 		}
 
@@ -397,7 +444,7 @@
 
 		// Scroll to the top when triggering this from JS.
 		// Ensures toolbars are reset properly.
-		if ( window.pageYOffset && window.pageYOffset > 130 ) {
+		if ( window.pageYOffset && window.pageYOffset > pageYOffsetAtTop ) {
 			window.scrollTo( window.pageXOffset, 0 );
 		}
 
