Merge branch 'master' into aidanr/login_auth_work
diff --git a/bundles/org.eclipse.orion.client.git/web/git/css/git.css b/bundles/org.eclipse.orion.client.git/web/git/css/git.css
index 410aeee..6d5289e 100644
--- a/bundles/org.eclipse.orion.client.git/web/git/css/git.css
+++ b/bundles/org.eclipse.orion.client.git/web/git/css/git.css
@@ -983,6 +983,20 @@
 	-moz-osx-font-smoothing: grayscale;
 }
 
+.git-sprite-branch-active-stash{
+	font-size: 16px;
+	line-height: normal;
+	vertical-align:middle;
+	color: #333;
+	font-family: 'Orion Icon Font';	
+	padding-right:5px;
+	background: none;
+	border: none;
+	margin: 0;
+	-webkit-font-smoothing: antialiased;
+	-moz-osx-font-smoothing: grayscale;
+}
+
 .git-sprite-conflict-file{
 	font-size: 24px;
 	line-height: normal;
@@ -1048,6 +1062,18 @@
 	-moz-osx-font-smoothing: grayscale;
 }
 
+.git-sprite-stash{
+	font-size: 16px;
+	line-height: normal;
+	vertical-align:middle;
+	color: #333;
+	font-family: 'Orion Icon Font';	
+	background: none;
+	border: none;
+	margin: 0;
+	-webkit-font-smoothing: antialiased;
+	-moz-osx-font-smoothing: grayscale;
+}
 
 .git-sprite-apply-patch:before{ content:'\E017'; }
 .git-sprite-save-patch:before{ content:'\E018'; }
@@ -1081,8 +1107,11 @@
 .git-sprite-branch-active-branch:after{ content: '\E029'; }
 .git-sprite-branch-active-commit:before{ content: '\E01A'; }
 .git-sprite-branch-active-commit:after{ content: '\E045'; }
+.git-sprite-branch-active-stash:before{ content: '\E01A'; }
+.git-sprite-branch-active-stash:after{ content: '\E035'; }
 .git-sprite-undo-commit:before{ content: '\E03D'; }
 .git-sprite-view-stash:before{ content: '\E035'; }
 .git-sprite-stash-changes:before{ content: '\E03E'; }
 .git-sprite-pop-changes:before{ content: '\E03F'; }
+.git-sprite-stash:before{ content: '\E035'; }
 .git-sprite-commit:before{ content: '\E045'; }
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js b/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js
index 0184bfc..1fd6745 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js
@@ -595,7 +595,7 @@
 				}
 			},
 			visibleWhen: function(item) {
-				return item.Type === "Branch" || item.Type === "RemoteTrackingBranch"; //$NON-NLS-1$ //$NON-NLS-0$
+				return item.Type === "Branch" || (item.Type === "RemoteTrackingBranch" && item.Id); //$NON-NLS-1$ //$NON-NLS-0$
 			}
 		});
 		commandService.addCommand(checkoutBranchCommand);
@@ -682,7 +682,7 @@
 				});
 			},
 			visibleWhen: function(item) {
-				return item.Type === "RemoteTrackingBranch"; //$NON-NLS-0$
+				return item.Type === "RemoteTrackingBranch" && item.Id; //$NON-NLS-0$
 			}
 		});
 		commandService.addCommand(removeRemoteBranchCommand);
@@ -1009,7 +1009,7 @@
 			if (item.LocalBranch && item.RemoteBranch) {
 				item = item.RemoteBranch;
 			}
-			if (item.Type === "RemoteTrackingBranch") //$NON-NLS-0$
+			if (item.Type === "RemoteTrackingBranch" && item.Id) //$NON-NLS-0$
 				return true;
 			if (item.Type === "Remote") //$NON-NLS-0$
 				return true;
@@ -1133,7 +1133,7 @@
 				});
 			},
 			visibleWhen : function(item) {
-				if (item.Type === "RemoteTrackingBranch") //$NON-NLS-0$
+				if (item.Type === "RemoteTrackingBranch" && item.Id) //$NON-NLS-0$
 					return true;
 				if (item.Type === "Branch" && !item.Current) //$NON-NLS-0$
 					return true;
@@ -1191,7 +1191,7 @@
 				});
 			},
 			visibleWhen : function(item) {
-				if (item.Type === "RemoteTrackingBranch") //$NON-NLS-0$
+				if (item.Type === "RemoteTrackingBranch" && item.Id) //$NON-NLS-0$
 					return true;
 				if (item.Type === "Branch" && !item.Current) //$NON-NLS-0$
 					return true;
@@ -1272,7 +1272,7 @@
 					messages["starting the active branch again based on the latest state of '"] + item.Name + "' " +  //$NON-NLS-1$
 					messages["and applying each commit again to the updated active branch."];
 
-				return item.Type === "RemoteTrackingBranch" || (item.Type === "Branch" && !item.Current); //$NON-NLS-1$ //$NON-NLS-0$
+				return (item.Type === "RemoteTrackingBranch" && item.Id) || (item.Type === "Branch" && !item.Current); //$NON-NLS-1$ //$NON-NLS-0$
 			}
 		});
 		commandService.addCommand(rebaseCommand);
@@ -1460,7 +1460,7 @@
 				resetCallback(data, data.items.Name, "HARD", messages["GitResetIndexConfirm"]); //$NON-NLS-0$
 			},
 			visibleWhen : function(item) {
-				return item.Type === "RemoteTrackingBranch" || "Commit"; //$NON-NLS-1$ //$NON-NLS-0$
+				return (item.Type === "RemoteTrackingBranch"  && item.Id) || item.Type === "Branch" || item.Type === "Commit"; //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
 			}
 		});
 		commandService.addCommand(resetIndexCommand);
@@ -1472,7 +1472,7 @@
 			spriteClass: "gitCommandSprite", //$NON-NLS-0$
 			id : "eclipse.orion.git.undoCommit", //$NON-NLS-0$
 			callback: function(data) {
-				resetCallback(data, "HEAD^", "SOFT", messages["UndoConfirm"]);
+				resetCallback(data, "HEAD^", "SOFT", messages["UndoConfirm"]); //$NON-NLS-1$ //$NON-NLS-0$
 			},
 			visibleWhen : function(item) {
 				return item.Type === "Commit" && item.parent && item.parent.Type === "Outgoing" && item.parent.children && item.parent.children[0].Name === item.Name; //$NON-NLS-0$
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/gitRepositoryExplorer.js b/bundles/org.eclipse.orion.client.git/web/orion/git/gitRepositoryExplorer.js
index b5d57a0..241d5ea 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/gitRepositoryExplorer.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/gitRepositoryExplorer.js
@@ -292,7 +292,11 @@
 			this.statusDeferred = new Deferred().resolve(); //HACK
 			return;
 		}
-		this.statusDeferred = this.displayStatus(this.repository);
+		this.statusDeferred = this.displayStatus(this.repository).then(function() {
+			if (changes.length === 0) {
+				this.changes = [this.repository.status];
+			}
+		}.bind(this));
 	};
 
 	GitRepositoryExplorer.prototype.display = function(location, resource, processURLs) {
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/gitCommitList.js b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/gitCommitList.js
index bd21196..695a4eb 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/gitCommitList.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/gitCommitList.js
@@ -150,6 +150,7 @@
 				if (this.isNewBranch(this.targetRef)) {

 					return false;

 				}

+				return true;

 			}

 			return util.tracksRemoteBranch(this.currentBranch);

 		},

@@ -716,6 +717,9 @@
 						case "Commit": //$NON-NLS-0$ 

 							imgClass = "git-sprite-branch-active-commit"; //$NON-NLS-0$

 							break;

+						case "StashCommit": //$NON-NLS-0$ 

+							imgClass = "git-sprite-branch-active-stash"; //$NON-NLS-0$

+							break;

 						case "Branch": //$NON-NLS-0$

 						case "RemoteTrackingBranch": //$NON-NLS-0$

 						default:

@@ -809,7 +813,7 @@
 				return;

 			}

 			

-			commandService.registerCommandContribution(actionsNodeScope, "eclipse.orion.git.commit.toggleFilter", 20, null, false, new KeyBinding.KeyBinding('h', true, true)); //$NON-NLS-0$

+			commandService.registerCommandContribution(actionsNodeScope, "eclipse.orion.git.commit.toggleFilter", 20, null, false, new KeyBinding.KeyBinding('h', true, true)); //$NON-NLS-1$ //$NON-NLS-0$

 			commandService.registerCommandContribution(actionsNodeScope, "eclipse.orion.git.commit.simpleLog", 50); //$NON-NLS-0$

 			commandService.registerCommandContribution(actionsNodeScope, "eclipse.orion.git.sync", 100); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$

 

@@ -827,19 +831,16 @@
 					commandService.destroy(outgoingActionScope);

 				}

 	

-				var tracksRemoteBranch = model.tracksRemoteBranch();

-				if (tracksRemoteBranch) {

-					commandService.addCommandGroup(incomingActionScope, "eclipse.gitFetchGroup", 500, messages['fetchGroup'], null, null, null, "Fetch", null, "eclipse.orion.git.fetch"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$

-					commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.fetch", 100, "eclipse.gitFetchGroup"); //$NON-NLS-0$ //$NON-NLS-1$

-					commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.fetchForce", 200, "eclipse.gitFetchGroup"); //$NON-NLS-0$ //$NON-NLS-1$

-					

-					commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.merge", 300); //$NON-NLS-0$

-					commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.mergeSquash", 350); //$NON-NLS-1$ //$NON-NLS-0$

-					commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.rebase", 200); //$NON-NLS-0$

-					commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.resetIndex", 400); //$NON-NLS-0$

-					targetRef.GitUrl = activeBranch.RemoteLocation[0].GitUrl;

-					commandService.renderCommands(incomingActionScope, incomingActionScope, targetRef, this, "tool"); //$NON-NLS-0$

-				}

+				commandService.addCommandGroup(incomingActionScope, "eclipse.gitFetchGroup", 500, messages['fetchGroup'], null, null, null, "Fetch", null, "eclipse.orion.git.fetch"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$

+				commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.fetch", 100, "eclipse.gitFetchGroup"); //$NON-NLS-0$ //$NON-NLS-1$

+				commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.fetchForce", 200, "eclipse.gitFetchGroup"); //$NON-NLS-0$ //$NON-NLS-1$

+				

+				commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.merge", 300); //$NON-NLS-0$

+				commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.mergeSquash", 350); //$NON-NLS-1$ //$NON-NLS-0$

+				commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.rebase", 200); //$NON-NLS-0$

+				commandService.registerCommandContribution(incomingActionScope, "eclipse.orion.git.resetIndex", 400); //$NON-NLS-0$

+				targetRef.GitUrl = activeBranch.RemoteLocation[0].GitUrl;

+				commandService.renderCommands(incomingActionScope, incomingActionScope, targetRef, this, "tool"); //$NON-NLS-0$

 

 				commandService.addCommandGroup(outgoingActionScope, "eclipse.gitPushGroup", 1000, messages['pushGroup'], null, null, null, "Push", null, "eclipse.orion.git.push"); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$

 				commandService.registerCommandContribution(outgoingActionScope, "eclipse.orion.git.push", 1100, "eclipse.gitPushGroup"); //$NON-NLS-0$ //$NON-NLS-1$

diff --git a/bundles/org.eclipse.orion.client.javascript/web/javascript/contentAssist/contentAssist.js b/bundles/org.eclipse.orion.client.javascript/web/javascript/contentAssist/contentAssist.js
index 194ab5a..3151343 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/javascript/contentAssist/contentAssist.js
+++ b/bundles/org.eclipse.orion.client.javascript/web/javascript/contentAssist/contentAssist.js
@@ -841,15 +841,22 @@
 		 */
 		_getCompletionContext: function(ast, offset, contents) {
 		    var comment = Finder.findComment(offset, ast);
-		    if(comment && comment.type === 'Block') {
-		        var start  = comment.range[0];
-		        if(contents.charAt(start) === '/' && contents.charAt(start+1) === '*') {
-                    if(contents.charAt(start+2) === '*' && offset > start+2) { // must be past the second '*'
-                        return {kind:'jsdoc', node: comment};  
-                    } else if(offset > start+1) { //must be past the '*'
-    		            return {kind:'doc', node: comment};
-    		        }
+		    if(comment) {
+		        switch(comment.type) {
+		            case 'Block': {
+		                var start  = comment.range[0];
+        		        if(contents.charAt(start) === '/' && contents.charAt(start+1) === '*') {
+                            if(contents.charAt(start+2) === '*' && offset > start+2) { // must be past the second '*'
+                                return {kind:'jsdoc', node: comment};  
+                            } else if(offset > start+1) { //must be past the '*'
+                		            return {kind:'doc', node: comment};
+                		        }
+        		        }
+		            }
+		            //$FALLTHROUGH$
+		            default: return null;
 		        }
+		        
 		        return null;
 		    }
 			var parents = [];
diff --git a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/contentAssistTests.js b/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/contentAssistTests.js
index f058718..6907368 100644
--- a/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/contentAssistTests.js
+++ b/bundles/org.eclipse.orion.client.javascript/web/js-tests/javascript/contentAssistTests.js
@@ -5508,5 +5508,55 @@
 			     ['urly', 'curly', 'ESLint rule name']
 			     ]);
 		});
+		
+		/**
+		 * Tests line comments that have 
+		 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=443521
+		 * @since 7.0
+		 */
+		it("test line comment 1", function() {
+			var results = computeContentAssist("//  ", "", 4);
+			testProposals(results, []);
+		});
+		
+		/**
+		 * Tests line comments that have 
+		 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=443521
+		 * @since 7.0
+		 */
+		it("test line comment 2", function() {
+			var results = computeContentAssist("// foo ", "", 3);
+			testProposals(results, []);
+		});
+		
+		/**
+		 * Tests line comments that have 
+		 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=443521
+		 * @since 7.0
+		 */
+		it("test line comment 3", function() {
+			var results = computeContentAssist("// foo ", "", 7);
+			testProposals(results, []);
+		});
+		
+		/**
+		 * Tests line comments that have 
+		 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=443521
+		 * @since 7.0
+		 */
+		it("test line comment 4", function() {
+			var results = computeContentAssist("// cur ", "c", 4);
+			testProposals(results, []);
+		});
+		
+		/**
+		 * Tests line comments that have 
+		 * @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=443521
+		 * @since 7.0
+		 */
+		it("test line comment 5", function() {
+			var results = computeContentAssist("// es ", "es", 5);
+			testProposals(results, []);
+		});
 	});
 });
diff --git a/bundles/org.eclipse.orion.client.ui/web/css/layout.css b/bundles/org.eclipse.orion.client.ui/web/css/layout.css
index c7c4f80..135edca 100644
--- a/bundles/org.eclipse.orion.client.ui/web/css/layout.css
+++ b/bundles/org.eclipse.orion.client.ui/web/css/layout.css
@@ -250,6 +250,15 @@
 	height: 100%;

 }

 

+.generalAnimation {

+	-webkit-transition: all 0.5s ease;

+	-moz-transition: all 0.5s ease;

+	-o-transition: all 0.5s ease;

+	transition: all 0.5s ease;

+	z-index: 50;

+    overflow: auto;

+}

+

 .sidePanelLayoutAnimation {

 	-webkit-transition: width 0.5s ease;

 	-moz-transition: width 0.5s ease;

@@ -382,36 +391,77 @@
    display: none;

 }

 

+/* 

+ * NOTE: Please don't apply margin values to the splitter as the splitter.js

+ * code doen't take them into account during its layout

+ */

 .splitLayout {

 	position: absolute;

 	left: 33%;  /* override this value if you want a different proportion of the two split panes */

 	height: 100%;

 	z-index: 50;

 	width: 10px;

-	margin-right: 3px;

 	cursor: e-resize;

 	overflow: hidden;

 	visibility: hidden;  /* use visibility vs. display because we need a position in calculations */

 }

 

+/* 

+ * NOTE: Please don't apply margin values to the splitter as the splitter.js

+ * code doen't take them into account during its layout

+ */

 .splitVerticalLayout {

 	position: absolute;

 	top: 33%;  /* override this value if you want a different proportion of the two split panes */

 	width: 100%;

 	z-index: 50;

 	height: 10px;

-	margin-bottom: 3px;

 	cursor: n-resize;

 	overflow: hidden;

 	visibility: hidden;  /* use visibility vs. display because we need a position in calculations */

 }

 

+@media only screen 

+and (min-device-width : 768px) 

+and (max-device-width : 1024px)  {

+	/* 

+	 * NOTE: Please don't apply margin values to the splitter as the splitter.js

+	 * code doen't take them into account during its layout

+	 */

+	.splitLayout {

+		position: absolute;

+		left: 33%;  /* override this value if you want a different proportion of the two split panes */

+		height: 100%;

+		z-index: 50;

+		width: 20px;

+		cursor: e-resize;

+		overflow: hidden;

+		visibility: hidden;  /* use visibility vs. display because we need a position in calculations */

+	}

+	

+	/* 

+	 * NOTE: Please don't apply margin values to the splitter as the splitter.js

+	 * code doen't take them into account during its layout

+	 */

+	.splitVerticalLayout {

+		position: absolute;

+		top: 33%;  /* override this value if you want a different proportion of the two split panes */

+		width: 100%;

+		z-index: 50;

+		height: 20px;

+		cursor: n-resize;

+		overflow: hidden;

+		visibility: hidden;  /* use visibility vs. display because we need a position in calculations */

+	}

+	

+}

+

 .splitThumbLeftLayout {

 	position: absolute;

 	right: 0;

 	height: 3em;

-	width: 5px;

-	top: 49%;

+	width: 50%;

+	top: calc(50% - 1.5em);

 	cursor: pointer;

 	border-top-left-radius: 5px;

 	border-bottom-left-radius: 5px;	

@@ -421,8 +471,8 @@
 	position: absolute;

 	left: 0;

 	height: 3em;

-	width: 5px;

-	top: 49%;

+	width: 50%;

+	top: calc(50% - 1.5em);

 	cursor: pointer;

 	border-top-right-radius: 5px;

 	border-bottom-right-radius: 5px;	

@@ -432,8 +482,8 @@
 	position: absolute;

 	bottom: 0;

 	width: 3em;

-	height: 5px;

-	left: 49%;

+	height: 50%;

+	left: calc(50% - 1.5em);

 	cursor: pointer;

 	border-top-left-radius: 5px;

 	border-top-right-radius: 5px;	

@@ -443,8 +493,8 @@
 	position: absolute;

 	top: 0;

 	width: 3em;

-	height: 5px;

-	left: 49%;

+	height: 50%;

+	left: calc(50% - 1.5em);

 	cursor: pointer;

 	border-bottom-left-radius: 5px;

 	border-bottom-right-radius: 5px;	

@@ -739,4 +789,4 @@
 

 .userMenu > .dropdownMenuOpen {

 	top: 36px;

-}
\ No newline at end of file
+}
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/webui/splitter.js b/bundles/org.eclipse.orion.client.ui/web/orion/webui/splitter.js
index 0c0d795..dd0f70e 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/webui/splitter.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/webui/splitter.js
@@ -15,7 +15,6 @@
 	'orion/webui/littlelib'
 ], function(EventTarget, util, lib) {
 
-	var MIN_SIDE_NODE_WIDTH = 5; //The minimium width/height of the splitted nodes by the splitter
 	var ORIENTATION_HORIZONTAL = 1;
 	var ORIENTATION_VERTICAL = 2;
 
@@ -28,11 +27,19 @@
 	 *
 	 * <p>The relative proportions of the side and main panels are determined by the initial style of
 	 * the splitter bar in the document. The panels will pin themselves to the splitter by default.
-	 * Once the user moves the splitter, the positions are remembered.</p>
+	 * Once the user moves the splitter, the positions are remembered. If the splitter is *not* proportional
+	 * but *is* vertical then its position is stored separately from its horizontal position.</p>
+	 * 
+	 * <p>The splitter defines the CSS to position the nodes it's splitting based on which of the nodes
+	 * 'collapses' when it's 'closed'. If the left (leading) node collapses then everything is defined relative
+	 * to the left; if the trailing node collapses (closeReversely=true) then everything is relative to the right.
+	 * In either case the CSS is defined so that the non-collapsing node gets the extra space if the browser grows.
 	 *
 	 * <p>By default, a splitter is open. The client can create a closed splitter by setting a 
 	 * <code>data-initial-state</code> attribute with value <code>"closed"</code> on the 
-	 * splitter's <code>node</code> element.</p>
+	 * splitter's <code>node</code> element. Note that the user can drag a splitter 'closed' or 'open'
+	 * and the correct state is maintained (i.e. if it were open and we dragged it all the way to its closed
+	 * position then hitting the thumb would open it and vice versa.</p>
 	 *
 	 * @param {Object} options The options object which must specify the split dom node
 	 * @param {Element} options.node The node for the splitter presentation.  Required.
@@ -41,6 +48,7 @@
 	 * @param {Boolean} [options.toggle=false] Specifies that the side node should be able to toggle.
 	 * @param {Boolean} [options.vertical=false] Specifies that the nodes are stacked vertically rather than horizontal.
 	 * @param {Boolean} [options.closeReversely=false] Specifies that the splitter moves to right when nodes are stacked horizontally, or to bottom when nodes are stacked vertically.
+	 * @param {Boolean} [options.proportional=false] Specifies that the splitter is proportional so that growing the browser allocates space to both nodes.
 	 *
 	 * @borrows orion.editor.EventTarget#addEventListener as #addEventListener
 	 * @borrows orion.editor.EventTarget#removeEventListener as #removeEventListener
@@ -53,62 +61,46 @@
 	Splitter.prototype = /** @lends orion.webui.Splitter.prototype */ {
 
 		_init: function(options) {
-			this._tracking = null;
+			this.$splitter = lib.node(options.node);
+			if (!this.$splitter) { throw "no dom node for splitter found"; } //$NON-NLS-0$
+			this.$leading = lib.node(options.sidePanel);
+			if (!this.$leading) { throw "no dom node for side panel found"; } //$NON-NLS-0$
+			this.$trailing = lib.node(options.mainPanel);
+			if (!this.$trailing) { throw "no dom node for main panel found"; } //$NON-NLS-0$
+
+			this._tracking = false;
 			this._animationDelay = 501;  // longer than CSS transitions in layout.css
-			this._closeReversely = options.closeReversely;
-			this.$node = lib.node(options.node);
-			if (!this.$node) { throw "no dom node for splitter found"; } //$NON-NLS-0$
-			this.$sideNode = lib.node(options.sidePanel);
-			if (!this.$sideNode) { throw "no dom node for side panel found"; } //$NON-NLS-0$
-			this.$mainNode = lib.node(options.mainPanel);
-			if (!this.$mainNode) { throw "no dom node for main panel found"; } //$NON-NLS-0$
-			this._vertical = options.vertical || false;
+			this._collapseTrailing = options.closeReversely || false;
+			this._proportional = options.proportional || false;
 
-			var classList = this.$node.classList;
-			classList.add("split"); //$NON-NLS-0$
-			classList.add(this._vertical ? "splitVerticalLayout" : "splitLayout"); //$NON-NLS-1$ //$NON-NLS-0$
-			classList = this.$sideNode.classList;
-			classList.add("hasSplit"); //$NON-NLS-0$
-			classList.add(this._vertical ? "sidePanelVerticalLayout" : "sidePanelLayout"); //$NON-NLS-1$ //$NON-NLS-0$
-			classList = this.$mainNode.classList;
-			classList.add("hasSplit"); //$NON-NLS-0$
-			classList.add(this._vertical ? "mainPanelVerticalLayout" : "mainPanelLayout"); //$NON-NLS-1$ //$NON-NLS-0$
-
-			this._prefix = "/orion/splitter/" + (this.$node.id || document.body.id || "");  //$NON-NLS-0$
+			this._prefix = "/orion/splitter/" + (this.$splitter.id || document.body.id || "");  //$NON-NLS-0$
+			
 			if (options.toggle) {
 				this._thumb = document.createElement("div"); //$NON-NLS-0$
-				this.$node.appendChild(this._thumb);
+				this.$splitter.appendChild(this._thumb);
 				this._thumb.classList.add("splitThumb"); //$NON-NLS-0$
 				if (this._vertical) {
-					this._thumb.classList.add(this._closeReversely ? "splitVerticalThumbDownLayout" : "splitVerticalThumbUpLayout"); //$NON-NLS-1$ //$NON-NLS-0$
+					this._thumb.classList.add(this._collapseTrailing ? "splitVerticalThumbDownLayout" : "splitVerticalThumbUpLayout"); //$NON-NLS-1$ //$NON-NLS-0$
 				} else {
-					this._thumb.classList.add(this._closeReversely ? "splitThumbRightLayout" : "splitThumbLeftLayout"); //$NON-NLS-1$ //$NON-NLS-0$
+					this._thumb.classList.add(this._collapseTrailing ? "splitThumbRightLayout" : "splitThumbLeftLayout"); //$NON-NLS-1$ //$NON-NLS-0$
 				}
 			}
-			this._closeByDefault = this.$node.getAttribute("data-initial-state") === "closed"; //$NON-NLS-1$ //$NON-NLS-0$
-			if (typeof options.closeByDefault !== "undefined") { //$NON-NLS-0$
-				this._closeByDefault = options.closeByDefault; // param overrides page's initial-state
-			}
-			this._initializeFromStoredSettings();
 
-			if (this._closed) {
-				this._closed = false;        // _thumbDown will toggle it, so turn it off and then call _thumbDown.
-				this._thumbDown(true, true); // do not animate. do not persist the initial state
-			} else {
-				this._adjustToSplitPosition();
-			}
-			this.$node.style.visibility = "visible"; //$NON-NLS-0$
-			this.$mainNode.style.display = "block"; //$NON-NLS-0$
-			this.$sideNode.style.display = "block"; //$NON-NLS-0$
+			this.$splitter.classList.add("split"); //$NON-NLS-0$
+			
+			// Initialize for the currnet orientation / collapse direction
+			var orientation = options.vertical ? ORIENTATION_VERTICAL : ORIENTATION_HORIZONTAL;
+			this.setOrientation(orientation);
+			
 			if (util.isIOS || util.isAndroid) {
-				this.$node.addEventListener("touchstart", this._touchStart.bind(this), false); //$NON-NLS-0$
+				this.$splitter.addEventListener("touchstart", this._touchStart.bind(this), false); //$NON-NLS-0$
 				if (this._thumb) {
 					this._thumb.addEventListener("touchstart", this._touchStart.bind(this), false); //$NON-NLS-0$
 				}
-				this.$node.addEventListener("touchmove", this._touchMove.bind(this), false); //$NON-NLS-0$
-				this.$node.addEventListener("touchend", this._touchEnd.bind(this), false); //$NON-NLS-0$
+				this.$splitter.addEventListener("touchmove", this._touchMove.bind(this), false); //$NON-NLS-0$
+				this.$splitter.addEventListener("touchend", this._touchEnd.bind(this), false); //$NON-NLS-0$
 			} else {
-				this.$node.addEventListener("mousedown", this._mouseDown.bind(this), false); //$NON-NLS-0$
+				this.$splitter.addEventListener("mousedown", this._mouseDown.bind(this), false); //$NON-NLS-0$
 				window.addEventListener("mouseup", this._mouseUp.bind(this), false); //$NON-NLS-0$
 			}
 			window.addEventListener("resize", this._resize.bind(this), false);  //$NON-NLS-0$
@@ -127,47 +119,111 @@
 
 			this._vertical = vertical;
 
-			var classList = this.$node.classList;
-			classList.toggle("splitLayout"); //$NON-NLS-0$
-			classList.toggle("splitVerticalLayout"); //$NON-NLS-0$
-			this.$node.style.left = "";
-			this.$node.style.top = "";
+			this.$splitter.style.position = "absolute"; //$NON-NLS-0$
+			this.$trailing.style.position = "absolute"; //$NON-NLS-0$
+			this.$leading.style.position = "absolute"; //$NON-NLS-0$
+
+			// We need a different storage area for the vertical value in non-proportional layouts
+			this._offsetStorageLabel = "/offset"; //$NON-NLS-0$
+			if (this._vertical && !this._proportional) {
+				this._offsetStorageLabel = "/offsetY"; //$NON-NLS-0$
+			}
 			
-			classList = this.$sideNode.classList;
-			classList.toggle("sidePanelLayout"); //$NON-NLS-0$
-			classList.toggle("sidePanelVerticalLayout"); //$NON-NLS-0$
-			this.$sideNode.style.left = "";
-			this.$sideNode.style.top = "";
-			this.$sideNode.style.width = "";
-			this.$sideNode.style.height = "";
+			if (this._vertical) {
+				this.$splitter.classList.remove("splitLayout"); //$NON-NLS-0$
+				this.$splitter.classList.add("splitVerticalLayout"); //$NON-NLS-0$
+				
+				// Set up for vertical calculations
+				this._topLeft = "top"; //$NON-NLS-0$
+				this._bottomRight = "bottom"; //$NON-NLS-0$
+				this._widthHeight = "height"; //$NON-NLS-0$
+			} else {
+				this.$splitter.classList.remove("splitVerticalLayout"); //$NON-NLS-0$
+				this.$splitter.classList.add("splitLayout"); //$NON-NLS-0$
+
+				// Set up for vertical calculations
+				this._topLeft = "left"; //$NON-NLS-0$
+				this._bottomRight = "right"; //$NON-NLS-0$
+				this._widthHeight = "width"; //$NON-NLS-0$
+			}
+
+			// Grab the initial position *before* hacking on the layout
+			this._initializeFromStoredSettings();
 			
-			classList = this.$mainNode.classList;
-			classList.toggle("mainPanelLayout"); //$NON-NLS-0$ 
-			classList.toggle("mainPanelVerticalLayout"); //$NON-NLS-0$
-			this.$mainNode.style.left = "";
-			this.$mainNode.style.top = "";
-			this.$mainNode.style.width = "";
-			this.$mainNode.style.height = "";
+			// Set up the style constants we need
+			this._setStyleConstants();
+			
+			// 'Constants' (i.e. things we don't set to adjust for the offset)
+			if (!this._collapseTrailing) {
+				this.$splitter.style[this._bottomRight] = "auto"; //$NON-NLS-0$
+				
+				this.$leading.style[this._topLeft] = "0px"; //$NON-NLS-0$
+				this.$leading.style[this._bottomRight] = "auto"; //$NON-NLS-0$
+
+				this.$trailing.style[this._widthHeight] = "auto"; //$NON-NLS-0$
+				this.$trailing.style[this._bottomRight] = "0px"; //$NON-NLS-0$
+			} else {
+				this.$splitter.style[this._topLeft] = "auto"; //$NON-NLS-0$
+				
+				this.$leading.style[this._topLeft] = "0px"; //$NON-NLS-0$
+				this.$leading.style[this._widthHeight] = "auto"; //$NON-NLS-0$
+				
+				this.$trailing.style[this._topLeft] = "auto"; //$NON-NLS-0$
+				this.$trailing.style[this._bottomRight] = "0px"; //$NON-NLS-0$
+			}
 
 			if (this._thumb) {
-				classList = this._thumb.classList;
+				var classList = this._thumb.classList;
 				if (this._vertical) {
-					classList.remove(this._closeReversely ? "splitThumbRightLayout" : "splitThumbLeftLayout"); //$NON-NLS-1$ //$NON-NLS-0$
-					classList.add(this._closeReversely ? "splitVerticalThumbDownLayout" : "splitVerticalThumbUpLayout"); //$NON-NLS-1$ //$NON-NLS-0$
+					classList.remove(this._collapseTrailing ? "splitThumbRightLayout" : "splitThumbLeftLayout"); //$NON-NLS-1$ //$NON-NLS-0$
+					classList.add(this._collapseTrailing ? "splitVerticalThumbDownLayout" : "splitVerticalThumbUpLayout"); //$NON-NLS-1$ //$NON-NLS-0$
 				} else {
-					classList.remove(this._closeReversely ? "splitVerticalThumbDownLayout" : "splitVerticalThumbUpLayout"); //$NON-NLS-1$ //$NON-NLS-0$
-					classList.add(this._closeReversely ? "splitThumbRightLayout" : "splitThumbLeftLayout"); //$NON-NLS-1$ //$NON-NLS-0$
+					classList.remove(this._collapseTrailing ? "splitVerticalThumbDownLayout" : "splitVerticalThumbUpLayout"); //$NON-NLS-1$ //$NON-NLS-0$
+					classList.add(this._collapseTrailing ? "splitThumbRightLayout" : "splitThumbLeftLayout"); //$NON-NLS-1$ //$NON-NLS-0$
 				}
 			}
 
-			this._initializeFromStoredSettings();
 			if (this._closed) {
 				this._closed = false;        // _thumbDown will toggle it, so turn it off and then call _thumbDown.
 				this._thumbDown(true, true); // do not animate. do not persist the initial state
 			} else {
-				this._adjustToSplitPosition();
+				this._adjustToOffset();
+			}
+			
+			this._resize();
+			
+			// Finally, ensure that everything is visible
+			this.$splitter.style.visibility = "visible"; //$NON-NLS-0$
+			this.$trailing.style.display = "block"; //$NON-NLS-0$
+			this.$leading.style.display = "block"; //$NON-NLS-0$
+		},
+
+		_setStyleConstants: function() {
+			if (this._vertical) {
+				this.$splitter.style.left = ""; //$NON-NLS-0$
+				this.$splitter.style.right = ""; //$NON-NLS-0$
+				
+				// We own the width / height of both panes
+				this.$leading.style.left = "auto"; //$NON-NLS-0$
+				this.$leading.style.right = "auto"; //$NON-NLS-0$
+				this.$leading.style.width = "100%"; //$NON-NLS-0$
+				this.$trailing.style.left = "auto"; //$NON-NLS-0$
+				this.$trailing.style.right = "auto"; //$NON-NLS-0$
+				this.$trailing.style.width = "100%"; //$NON-NLS-0$
+			} else {
+				this.$splitter.style.top = ""; //$NON-NLS-0$
+				this.$splitter.style.bottom = ""; //$NON-NLS-0$
+				
+				// We own the width / height of both panes
+				this.$leading.style.top = "auto"; //$NON-NLS-0$
+				this.$leading.style.bottom = "auto"; //$NON-NLS-0$
+				this.$leading.style.height = "100%"; //$NON-NLS-0$
+				this.$trailing.style.top = "auto"; //$NON-NLS-0$
+				this.$trailing.style.bottom = "auto"; //$NON-NLS-0$
+				this.$trailing.style.height = "100%"; //$NON-NLS-0$
 			}
 		},
+		
 		/**
 		 * Toggle the open/closed state of the side panel.
 		 */
@@ -206,98 +262,79 @@
 			} else {
 				this._closed = this._closeByDefault;
 			}
+			
+			// Set the initial value for the splitter's width/height
+			this._adjustSplitterSize();
 
-			var parentRect = lib.bounds(this.$node.parentNode);
-			var rect = lib.bounds(this.$node);
-			var pos;
-			if (this._vertical) {
-				pos = localStorage.getItem(this._prefix+"/yPosition"); //$NON-NLS-0$
-				if (pos) {
-					this._splitTop = parseInt(pos, 10);
-					if(this._splitTop > (parentRect.top + parentRect.height - rect.height)){
-						this._splitTop = parentRect.top + parentRect.height / 2.0;
-					}
-				} else if (this._closeByDefault) {
-					this._initialSplit = this._getSplitPosition();
-					this._splitTop = 0;
-				}
+			var pos = localStorage.getItem(this._prefix+this._offsetStorageLabel);
+			if (pos) {
+				this._offset = parseInt(pos, 10);
 			} else {
-				pos = localStorage.getItem(this._prefix+"/xPosition"); //$NON-NLS-0$
-				if (pos) {
-					this._splitLeft = parseInt(pos, 10);
-					if(this._splitLeft > (parentRect.left + parentRect.width - rect.width)){
-						this._splitLeft = parentRect.left + parentRect.width / 2.0;
-					}
-				} else if (this._closeByDefault) {
-					this._initialSplit = this._getSplitPosition();
-					this._splitLeft = 0;
-				}
+				// Use the current splitter location
+				var rect = lib.bounds(this.$splitter);
+				this._offset = this._adjustOffset(rect[this._topLeft]);
 			}
 		},
 
-		// Gets the current splitter position from the style
-		_getSplitPosition: function() {
-			var rect = lib.bounds(this.$node);
-			var parentRect = lib.bounds(this.$node.parentNode);
-			if (this.vertical) {
-				return rect.top - parentRect.top;
+		_adjustSplitterSize: function() {
+			// Size in pixels
+			var rect = lib.bounds(this.$splitter);
+			this._spltterSize = rect[this._widthHeight];
+			
+			// Make proportional if necessary
+			if (this._proportional) {
+				var pRect = lib.bounds(this.$splitter.parentNode);
+				this._spltterSize = this._spltterSize / (pRect[this._widthHeight] / 100);
+			}			
+		},
+		
+		/*
+		 * Takes a value that represents the desired left / top position for the
+		 * splitter and adjusts based on which side collapses. It then turns the value into
+		 * a ratio if the splitter is proportional.
+		 */
+		_adjustOffset: function(newOffset) {
+			var parentRect = lib.bounds(this.$splitter.parentNode);
+			if (this._collapseTrailing) {
+				var adjustment = newOffset + this._spltterSize;
+				newOffset = parentRect[this._widthHeight] - (adjustment - parentRect[this._topLeft]);
 			} else {
-				return rect.left - parentRect.left;
+				newOffset = newOffset - parentRect[this._topLeft];
+			}
+			
+			if (this._proportional) {
+				newOffset = newOffset / (parentRect[this._widthHeight] / 100);
+			}
+			
+			return newOffset;
+		},
+
+		_adjustToOffset: function() {
+			if (this._offset < 0) {
+				this._offset = 0;
+			}
+			
+			var suffix = this._proportional ? "%" : "px"; //$NON-NLS-1$ //$NON-NLS-0$
+			
+			if (!this._collapseTrailing) {
+				this.$splitter.style[this._topLeft] = this._offset + suffix;
+				this.$leading.style[this._widthHeight] = this._offset + suffix;
+				this.$trailing.style[this._topLeft] = (this._offset + this._spltterSize) + suffix;
+			} else {
+				this.$splitter.style[this._bottomRight] = this._offset + suffix;
+				this.$leading.style[this._bottomRight] = (this._offset + this._spltterSize) + suffix;
+				this.$trailing.style[this._widthHeight] = this._offset + suffix;
 			}
 		},
 
-		_adjustToSplitPosition: function(updateStorage) {
-			var rect = lib.bounds(this.$node);
-			var parentRect = lib.bounds(this.$node.parentNode);
-			if (this._vertical) {
-				this._splitHeight = rect.height;
-				if (updateStorage || !this._splitTop){
-					this._splitTop = rect.top;
-					localStorage.setItem(this._prefix+"/yPosition", this._splitTop);  //$NON-NLS-1$ //$NON-NLS-0$
-				}
-				var top = this._splitTop;
-				top = this._splitTop - parentRect.top;
-				this.$sideNode.style.height = top + "px"; //$NON-NLS-0$
-				this.$sideNode.style.display = "block"; //$NON-NLS-0$
-				this.$node.style.top = top + "px"; //$NON-NLS-0$
-				this._resize();
-			} else {
-				this._splitWidth = rect.width;
-				if (updateStorage || !this._splitLeft){
-					this._splitLeft = rect.left;
-					localStorage.setItem(this._prefix+"/xPosition", this._splitLeft);  //$NON-NLS-1$ //$NON-NLS-0$
-				}
-				var left = this._splitLeft;
-				left = this._splitLeft - parentRect.left;
-				this.$sideNode.style.width = left + "px"; //$NON-NLS-0$
-				this.$sideNode.style.display = "block"; //$NON-NLS-0$
-				this.$node.style.left = left + "px"; //$NON-NLS-0$
-				this._resize();
+		_resize: function() {
+			if (this._proportional) {
+				this._adjustSplitterSize();
+				this._adjustToOffset();
 			}
-		},
-
-		_resize: function(animationDelay, left, top) {
-			animationDelay = animationDelay || 0;
-			var parentRect = lib.bounds(this.$node.parentNode);
-			var rect = lib.bounds(this.$node);
-			if (this._vertical) {
-				if (top === undefined) {
-					top = rect.top - parentRect.top;
-				}
-				top += rect.height;
-				this.$mainNode.style.top = top + "px"; //$NON-NLS-0$
-			} else {
-				if (left === undefined) {
-					left = rect.left - parentRect.left;
-				}
-				left += rect.width;
-				this.$mainNode.style.left = left + "px"; //$NON-NLS-0$
-			}
-			var self = this;
-			window.setTimeout(function() {
-				self._notifyResizeListeners(self.$mainNode);
-				self._notifyResizeListeners(self.$sideNode);
-			}, animationDelay);
+			
+			this._notifyResizeListeners(self.$trailing);
+			this._notifyResizeListeners(self.$leading);
 		},
 
 		_notifyResizeListeners: function(node) {
@@ -312,99 +349,82 @@
 			if (!noAnimation) {
 				this._addAnimation();
 			}
-			var top = this._splitTop, left = this._splitLeft;
+
 			if (this._closed) {
+				var pos = localStorage.getItem(this._prefix+this._offsetStorageLabel);
+				this._offset = pos ? parseInt(pos, 10) : 350;
 				this._closed = false;
-				// Expanding: restore initial size from style if present
-				if (!this._splitLeft && !this._splitTop && typeof this._initialSplit === "number") { //$NON-NLS-0$
-					top = left = this._initialSplit;
-				}
 			} else {
+				localStorage.setItem(this._prefix+this._offsetStorageLabel, this._offset);
+				this._offset = 0;
 				this._closed = true;
-				if(!this._closeReversely) {
-					top = left = 0;
-				} else {
-					var parentRect = lib.bounds(this.$node.parentNode);
-					var rect = lib.bounds(this.$node);
-					if(this._vertical){
-						top = parentRect.height - rect.height;
-					} else {
-						left = parentRect.width - rect.width;
-					}					
-				}
 			}
-			if (this._vertical) {
-				this.$sideNode.style.height = top+"px"; //$NON-NLS-0$
-				this.$node.style.top = top+"px"; //$NON-NLS-0$
-			} else {
-				this.$sideNode.style.width = left+"px"; //$NON-NLS-0$
-				this.$node.style.left = left+"px"; //$NON-NLS-0$
-			}
-			this._resize(this._animationDelay, left, top);
+
+			this._adjustToOffset();
+
 			if (!noAnimation) {
 				this._removeAnimation();
 			}
 			if (!noUpdateStorage) {
 				localStorage.setItem(this._prefix+"/toggleState", this._closed ? "closed" : null);  //$NON-NLS-1$  //$NON-NLS-0$
 			}
-			var self = this;
-			window.setTimeout(function() {
-				self._notifyToggleListeners();
-			}, this._animationDelay);
 		},
 
 		_removeAnimation: function() {
 			// in a timeout to ensure the animations are complete.
 			var self = this;
 			window.setTimeout(function() {
-				self.$sideNode.classList.remove(self._vertical ? "sidePanelVerticalLayoutAnimation" : "sidePanelLayoutAnimation"); //$NON-NLS-1$ //$NON-NLS-0$
-				self.$mainNode.classList.remove(self._vertical ? "mainPanelVerticalLayoutAnimation" : "mainPanelLayoutAnimation"); //$NON-NLS-1$ //$NON-NLS-0$
-				self.$node.classList.remove(self._vertical ? "splitVerticalLayoutAnimation" : "splitLayoutAnimation"); //$NON-NLS-1$ //$NON-NLS-0$
+				self.$leading.classList.remove("generalAnimation"); //$NON-NLS-0$
+				self.$trailing.classList.remove("generalAnimation"); //$NON-NLS-0$
+				self.$splitter.classList.remove("generalAnimation"); //$NON-NLS-0$
+				
+				self._resize();
 			}, this._animationDelay);
 		},
 
 		_addAnimation: function() {
-			this.$sideNode.classList.add(this._vertical ? "sidePanelVerticalLayoutAnimation" : "sidePanelLayoutAnimation"); //$NON-NLS-1$ //$NON-NLS-0$
-			this.$mainNode.classList.add(this._vertical ? "mainPanelVerticalLayoutAnimation" : "mainPanelLayoutAnimation"); //$NON-NLS-1$ //$NON-NLS-0$
-			this.$node.classList.add(this._vertical ? "splitVerticalLayoutAnimation" : "splitLayoutAnimation"); //$NON-NLS-1$ //$NON-NLS-0$
+			this.$leading.classList.add("generalAnimation"); //$NON-NLS-0$
+			this.$trailing.classList.add("generalAnimation"); //$NON-NLS-0$
+			this.$splitter.classList.add("generalAnimation"); //$NON-NLS-0$
 		},
 		
 		_down: function() {
-			this.$node.classList.add("splitTracking"); //$NON-NLS-0$
-			this.$mainNode.classList.add("panelTracking"); //$NON-NLS-0$
-			this.$sideNode.classList.add("panelTracking"); //$NON-NLS-0$
+			this.$splitter.classList.add("splitTracking"); //$NON-NLS-0$
+			this.$trailing.classList.add("panelTracking"); //$NON-NLS-0$
+			this.$leading.classList.add("panelTracking"); //$NON-NLS-0$
 		},
 		
 		_move: function(clientX, clientY) {
-			var parentRect = lib.bounds(this.$node.parentNode);
-			if (this._vertical) {
-				this._splitTop = clientY;
-				if(this._splitTop < parentRect.top + MIN_SIDE_NODE_WIDTH) {//If the top side of the splitted node is shorter than the min size
-					this._splitTop = parentRect.top + MIN_SIDE_NODE_WIDTH;
-				} else if(this._splitTop > parentRect.top + parentRect.height - MIN_SIDE_NODE_WIDTH) {//If the bottom side of the splitted node is shorter than the min size
-					this._splitTop = parentRect.top + parentRect.height - MIN_SIDE_NODE_WIDTH;
-				}
-				var top = this._splitTop;
-				top = this._splitTop - parentRect.top;
-				this.$node.style.top = top + "px"; //$NON-NLS-0$
+			var pos = this._vertical ? clientY : clientX;
+			
+			// Try to center the cursor on the new splitter pos
+			var rect = lib.bounds(this.$splitter);
+			var offset = rect[this._widthHeight] / 2;
+			if (this._collapseTrailing) {
+				this._offset = this._adjustOffset(pos + offset);
 			} else {
-				this._splitLeft = clientX;
-				if(this._splitLeft < parentRect.left + MIN_SIDE_NODE_WIDTH) {//If the left side of the splitted node is narrower than the min size
-					this._splitLeft = parentRect.left + MIN_SIDE_NODE_WIDTH;
-				} else if(this._splitLeft > parentRect.left + parentRect.width - MIN_SIDE_NODE_WIDTH) {//If the right side of the splitted node is narrower than the min size
-					this._splitLeft = parentRect.left + parentRect.width - MIN_SIDE_NODE_WIDTH;
-				}
-				var left = this._splitLeft;
-				left = this._splitLeft - parentRect.left;
-				this.$node.style.left = left + "px"; //$NON-NLS-0$
+				this._offset = this._adjustOffset(pos - offset);
 			}
-			this._adjustToSplitPosition(true);	
+			
+			this._adjustToOffset();	
 		},
 		
 		_up: function() {
-			this.$node.classList.remove("splitTracking"); //$NON-NLS-0$
-			this.$mainNode.classList.remove("panelTracking"); //$NON-NLS-0$
-			this.$sideNode.classList.remove("panelTracking"); //$NON-NLS-0$
+			this.$splitter.classList.remove("splitTracking"); //$NON-NLS-0$
+			this.$trailing.classList.remove("panelTracking"); //$NON-NLS-0$
+			this.$leading.classList.remove("panelTracking"); //$NON-NLS-0$
+
+			// if the user dragged the splitter closed or open capture this
+			if (this._offset > 0) {
+				// Store the current position
+				localStorage.setItem(this._prefix+this._offsetStorageLabel, this._offset);
+				this._closed = false;
+			} else {
+				this._closed = true;
+			}
+			
+			// Update the state
+			localStorage.setItem(this._prefix+"/toggleState", this._closed ? "closed" : null);  //$NON-NLS-1$  //$NON-NLS-0$
 		},
 
 		_mouseDown: function(event) {
@@ -435,6 +455,8 @@
 				this._tracking = null;
 				this._up();
 				lib.stop(event);
+				
+				this._resize();
 			}
 		},
 		
@@ -475,4 +497,4 @@
 		ORIENTATION_HORIZONTAL: ORIENTATION_HORIZONTAL,
 		ORIENTATION_VERTICAL: ORIENTATION_VERTICAL
 	};
-});
\ No newline at end of file
+});
diff --git a/doc/org.eclipse.orion.doc.isv/WikiDoc/Orion/Documentation/Developer_Guide/Architecture/Server-architecture.html b/doc/org.eclipse.orion.doc.isv/WikiDoc/Orion/Documentation/Developer_Guide/Architecture/Server-architecture.html
index 4e772b2..b5fecb3 100644
--- a/doc/org.eclipse.orion.doc.isv/WikiDoc/Orion/Documentation/Developer_Guide/Architecture/Server-architecture.html
+++ b/doc/org.eclipse.orion.doc.isv/WikiDoc/Orion/Documentation/Developer_Guide/Architecture/Server-architecture.html
@@ -47,8 +47,6 @@
 			<dd>Defines servlets for the core Orion services: file, workspace, preferences</dd>
 			<dt>org.eclipse.orion.server.search</dt>
 			<dd>Search servlet implementation using Apache Solr/Lucene</dd>
-			<dt>org.eclipse.orion.server.configurator</dt>
-			<dd>Defines an application, and configures the server (registers servlets and static content, specifies authentication and authorization settings)</dd>
 			<dt>org.eclipse.orion.server.authentication.*</dt>
 			<dd>Bundles providing various kinds of authentication support.</dd>
 		</dl>