Merge branch 'master' of ssh://git.eclipse.org/gitroot/orion/org.eclipse.orion.client
diff --git a/bundles/org.eclipse.orion.client.core/web/console/consolePage.css b/bundles/org.eclipse.orion.client.core/web/console/consolePage.css
index 8a24044..e005a3c 100644
--- a/bundles/org.eclipse.orion.client.core/web/console/consolePage.css
+++ b/bundles/org.eclipse.orion.client.core/web/console/consolePage.css
@@ -1,3 +1,4 @@
+@import "../org.dojotoolkit/dijit/themes/claro/claro.css";

 @import "../css/layout.css";

 @import "../css/ide.css";

 @import "../orion/widgets/Console.css";

diff --git a/bundles/org.eclipse.orion.client.core/web/css/ide.css b/bundles/org.eclipse.orion.client.core/web/css/ide.css
index 7076f18..aa795cc 100644
--- a/bundles/org.eclipse.orion.client.core/web/css/ide.css
+++ b/bundles/org.eclipse.orion.client.core/web/css/ide.css
@@ -465,6 +465,39 @@
 	z-index:100;
 }
 
+.inputCompletionContainer {
+	color: black;
+	display: block;
+	border:  1px solid #666;
+	background: white;
+	max-height: 300px;
+	max-width: 300px;
+	min-width: 150px;
+	position: absolute;
+	overflow-y: auto;
+	overflow-x: hidden;
+	padding: 2px;
+	z-index:200;
+}
+
+.inputCompletionUL {
+	list-style : none;
+	margin: 0;
+	padding: 0;
+}
+
+.inputCompletionLISelected {
+	background : #ffeecc;/*#0080ff;*/
+}
+
+.inputCompletionLICategory {
+	font-weight: bold;
+}
+
+.inputCompletionLINormal {
+	background : white;
+}
+
 .keyAssistFloat h2 {
 	color: white;
 }
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/Storage.js b/bundles/org.eclipse.orion.client.core/web/orion/Storage.js
new file mode 100644
index 0000000..212c96f
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.core/web/orion/Storage.js
@@ -0,0 +1,103 @@
+/*******************************************************************************

+ * @license

+ * Copyright (c) 2012 IBM Corporation and others.

+ * All rights reserved. This program and the accompanying materials are made 

+ * available under the terms of the Eclipse Public License v1.0 

+ * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 

+ * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). 

+ *

+ * Contributors:

+ *     IBM Corporation - initial API and implementation

+ *******************************************************************************/

+/*global define console */

+

+define(["orion/EventTarget"], function(EventTarget) {

+	function StorageEvent(key, oldValue, newValue, storageArea, timeStamp) {

+		return {

+			type: "storage",

+			key: key,

+			oldValue: oldValue || null,

+			newValue: newValue || null,

+			url : "",

+			storageArea: storageArea,

+			timeStamp: timeStamp || new Date().getTime()

+		};

+	}

+

+	// Should use an ES6 proxy for getter/setter/deleter -- someday

+	function Storage(obj, prefix) {

+		var _eventTarget = new EventTarget();

+		var _keys;

+		

+		this.addEventListener = _eventTarget.addEventListener.bind(_eventTarget);

+		this.removeEventListener = _eventTarget.removeEventListener.bind(_eventTarget);

+

+		function _getKeys() {

+			if (!_keys) {

+				_keys = Object.keys(obj);

+				if (prefix) {

+					_keys = _keys.filter(function(key) {

+						return key.indexOf(prefix) === 0;

+					});

+				}

+			}

+			return _keys;

+		}

+		

+		this.key = function(index) {

+			return _getKeys()[index];

+		};

+		

+		this.getItem = function(key) {

+			key = prefix ? prefix + key : key;

+			var value = obj[key];

+			_eventTarget.dispatchEvent({type: "_getItem", key: key, storage: obj});

+			return value;

+		};

+		

+		this.setItem = function(key, value) {

+			key = prefix ? prefix + key : key;

+			obj[key] = value;

+			_keys = null;

+			_eventTarget.dispatchEvent({type: "_setItem", key: key, value: value, storage: obj});

+		};

+		

+		this.removeItem = function(key) {

+			key = prefix ? prefix + key : key;

+			delete obj[key];

+			_keys = null;

+			_eventTarget.dispatchEvent({type: "_removeItem", key: key, storage: obj});

+		};

+		

+		this.clear = function() {

+			_getKeys().forEach(function(key) {

+				this.removeItem(key);

+			}.bind(this));

+		};

+		

+		this._update = function(key, value, timeStamp) {

+			if (prefix && key.indexOf(prefix) !== 0) {

+				return;

+			}

+			var oldValue = obj[key];

+			obj[key] = value;

+			key = key.substring(prefix.length);

+			_eventTarget.dispatchEvent(new StorageEvent(key, oldValue, value, this, timeStamp));

+		};

+		

+		this._dispatchUpdate = function(key, oldValue, newValue, timeStamp) {

+			if (prefix && key.indexOf(prefix) !== 0) {

+				return;

+			}

+			key = key.substring(prefix.length);

+			_eventTarget.dispatchEvent(new StorageEvent(key, oldValue, newValue, this, timeStamp));

+		};

+		

+		Object.defineProperty(this, "length", {

+			get : function() {

+				return _getKeys().length;

+			}

+		});

+	}

+	return Storage;

+});
\ No newline at end of file
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/commonHTMLFragments.js b/bundles/org.eclipse.orion.client.core/web/orion/commonHTMLFragments.js
index fe10062..91da169 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/commonHTMLFragments.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/commonHTMLFragments.js
@@ -32,9 +32,7 @@
 			'<div class="layoutRight">' + //$NON-NLS-0$
 				'<div id="globalActions" class="spacingLeft layoutLeft"></div>' + //$NON-NLS-0$
 				'<div id="relatedLinks" class="spacingLeft layoutLeft" style="padding-top:1px;"></div>' + //$NON-NLS-0$
-				'<input type="text" id="search" autocomplete="off" list= "searchCompletion" placeholder="'+messages['Search']+'" title="'+messages['Type a keyword or wild card to search in root']+'" class="layoutLeft spacingLeft searchbox" role="search">' + //$NON-NLS-2$ //$NON-NLS-0$
-				 '<datalist id="searchCompletion">' +
-				 '</datalist>' +				
+				'<input type="text" id="search" autocomplete="off" placeholder="'+messages['Search']+'" title="'+messages['Type a keyword or wild card to search in root']+'" class="layoutLeft spacingLeft searchbox" role="search">' + //$NON-NLS-2$ //$NON-NLS-0$
     			'<div id="searchOptions" class="layoutLeft" style="padding-top:1px;"></div>' + //$NON-NLS-0$
 				// '<div id="userInfo" style= "display:none;" class="layoutLeft primaryNav"></div>' + //$NON-NLS-0$
 				'<div id="userMenu" class="spacingLeft layoutLeft"></div>' + //$NON-NLS-0$
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/globalCommands.js b/bundles/org.eclipse.orion.client.core/web/orion/globalCommands.js
index 15fda9f..d88a8a4 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/globalCommands.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/globalCommands.js
@@ -13,9 +13,9 @@
 /*browser:true*/
 
 define(['i18n!orion/nls/messages', 'require', 'dojo', 'dijit', 'orion/commonHTMLFragments', 'orion/commands', 'orion/parameterCollectors', 
-	'orion/extensionCommands', 'orion/util', 'orion/textview/keyBinding', 'orion/breadcrumbs', 'orion/splitter', 'orion/favorites', 'orion/contentTypes', 'orion/URITemplate', 'orion/PageUtil', 'orion/widgets/themes/container/ThemeSheetWriter', 'orion/searchUtils',
+	'orion/extensionCommands', 'orion/util', 'orion/textview/keyBinding', 'orion/breadcrumbs', 'orion/splitter', 'orion/favorites', 'orion/contentTypes', 'orion/URITemplate', 'orion/PageUtil', 'orion/widgets/themes/container/ThemeSheetWriter', 'orion/searchUtils', 'orion/inputCompletion/inputCompletion',
 	'dojo/DeferredList', 'dijit/Menu', 'dijit/MenuItem', 'dijit/form/DropDownButton', 'orion/widgets/OpenResourceDialog', 'orion/widgets/LoginDialog', 'orion/widgets/UserMenu', 'orion/widgets/UserMenuDropDown'], 
-        function(messages, require, dojo, dijit, commonHTML, mCommands, mParameterCollectors, mExtensionCommands, mUtil, mKeyBinding, mBreadcrumbs, mSplitter, mFavorites, mContentTypes, URITemplate, PageUtil, ThemeSheetWriter, mSearchUtils){
+        function(messages, require, dojo, dijit, commonHTML, mCommands, mParameterCollectors, mExtensionCommands, mUtil, mKeyBinding, mBreadcrumbs, mSplitter, mFavorites, mContentTypes, URITemplate, PageUtil, ThemeSheetWriter, mSearchUtils, mInputCompletion){
 
 	/**
 	 * This class contains static utility methods. It is not intended to be instantiated.
@@ -795,11 +795,36 @@
 		}
 		
 		// hook up search box behavior
+		dojo.place('<div id="globalSearchCompletionParent" style="display: none" class="inputCompletionContainer" role="list" aria-atomic="true" aria-live="assertive"></div>', document.body, "last"); //$NON-NLS-1$ //$NON-NLS-0$
 		var searchField = dojo.byId("search"); //$NON-NLS-0$
+		var searchCompletion = new mInputCompletion.InputCompletion(function(callBack){
+				mSearchUtils.getMixedSearches(serviceRegistry, true, function(searches){
+					var i, fullSet = [], hasSavedSearch = false;
+					for (i in searches) {
+						if(searches[i].label){
+							if(!hasSavedSearch){
+								fullSet.push({type: "category", label: "Saved searches"});
+								hasSavedSearch = true;
+							}
+							fullSet.push({type: "proposal", label: searches[i].label, value: searches[i].name});
+						} else {
+							fullSet.push({type: "proposal", label: searches[i].name, value: searches[i].name});
+						}
+					}
+					callBack(fullSet);
+				});
+			},
+			"globalSearch", searchField, "globalSearchCompletionParent");
+		var searchCompletionSet = null;
+		var searchCompletionIndex = -1;
 		if (!searchField) {
 			throw "failed to generate HTML for banner"; //$NON-NLS-0$
 		}
+		
 		dojo.connect(searchField, "onkeypress", function(e){ //$NON-NLS-0$
+			if(searchCompletion.onKeyPressed(e)){
+				return;
+			}
 			if (e.charOrCode === dojo.keys.ENTER) {
 				if (searcher) {
 					if (searchField.value.length > 0) {
@@ -817,26 +842,13 @@
 				} else {
 					window.alert(messages["Can't search: no search service is available"]);
 				}
-			}
+			} 
 		});
-		dojo.connect(searchField, "onfocus", function(e){ //$NON-NLS-0$
-			var searchCompletion =  dojo.byId("searchCompletion");
-			dojo.empty(searchCompletion);
-			mSearchUtils.getMixedSearches(serviceRegistry, true, function(searches){
-				var i;
-				for (i in searches) {
-					var option = document.createElement('option');
-					option.value = searches[i].name;
-					if(searches[i].label){
-						option.label = searches[i].label + "(" + messages["Saved searches"] + ")";
-					}
-					searchCompletion.appendChild(option);
-				}
-			});
-		});
+		
 		mSearchUtils.getOpenSearchPref(serviceRegistry, function(openInNewTab){
 			_addSearchOptions(serviceRegistry, commandService, searcher, openInNewTab);
 		});
+		
 		// layout behavior.  Special handling for pages that use dijit for interior layout.
 		var dijitLayout = dojo.query(".dijitManagesLayout")[0]; //$NON-NLS-0$
 		var layoutWidget;
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/inputCompletion/inputCompletion.js b/bundles/org.eclipse.orion.client.core/web/orion/inputCompletion/inputCompletion.js
new file mode 100644
index 0000000..4a2fcc0
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.core/web/orion/inputCompletion/inputCompletion.js
@@ -0,0 +1,265 @@
+/*******************************************************************************
+ * @license
+ * Copyright (c) 2009, 2011 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials are made 
+ * available under the terms of the Eclipse Public License v1.0 
+ * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 
+ * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). 
+ * 
+ * Contributors: IBM Corporation - initial API and implementation
+ ******************************************************************************/
+
+define(['dojo'], function(dojo){
+
+	/**
+	 * InputCompletion is an alternative to datalist support in html5.
+	 * When binded with an html input element, it provides the input completion while user is typing in the input field.
+	 */
+	function InputCompletion(binderFunc, completionId, inputField, completionUIContainer, options) {
+		this._binderFunc = binderFunc;
+		this._completionIdPrefix = completionId + "__completion__";
+		this._inputField = inputField;
+		if (typeof(this._inputField) === "string") { //$NON-NLS-0$
+			this._inputField = document.getElementById(this._inputField);
+		}
+		this._completionUIContainer = completionUIContainer;
+		if (typeof(this._completionUIContainer) === "string") { //$NON-NLS-0$
+			this._completionUIContainer = document.getElementById(this._completionUIContainer);
+		}
+		this._proposeFromStart = options ? options.proposeFromStart : false;
+		this._dismissed = true;
+		var that = this;
+		that._mouseDown = false;
+		
+		dojo.connect(this._completionUIContainer, "onmousedown", function(e){
+			that._mouseDown = true;
+		});
+		dojo.connect(this._completionUIContainer, "onmouseup", function(e){
+			that._mouseDown = false;
+		});
+		dojo.connect(this._inputField, "onblur", function(e){
+			if(that._mouseDown){
+				window.setTimeout(function(){ //wait a few milliseconds for the input field to focus 
+					that._inputField.focus();
+				}, 200);
+			} else {
+				that._dismiss();
+			}
+		});
+		
+		dojo.connect(this._inputField, "oninput", null, function(e){ //$NON-NLS-0$
+			that.proposeOn(that._inputField.value);
+		});
+		dojo.connect(this._inputField, "onfocus", function(e){ //$NON-NLS-0$
+			if(!that._dismissed || !that._binderFunc){
+				return;
+			}
+			if(that._dismissing){
+				that._dismissing = false;
+				return;
+			}
+			that._binderFunc(function(dataList){
+				that.bind(dataList);
+				that.proposeOn(that._inputField.value);
+			});
+		});
+	}
+	
+	/**
+	 * Bind the full data list to propose on.
+	 * 
+	 * @param dataList 
+	 * 
+	 * <p>The data list is the full set of data that the input completion will filter on.</p>
+	 * 
+	 * The item of the data list must have two properties:
+	 * <ul>
+	 *   <li>type: can be either "proposal" or "category"</li>
+	 *   <li>label: the display name of the item</li>
+	 *   <li>value: the value that will be filtered on and send back to the input field</li>
+	 * </ul>
+	 */
+	InputCompletion.prototype.bind = function(dataList){
+		this._dataList = dataList;
+	};
+	
+	InputCompletion.prototype._proposeOnCategory = function(categoryName, categoryList){
+		if(categoryList.length === 0){
+			return;
+		}
+		var that = this;
+		if(categoryName){
+			var listEle = document.createElement('li');
+			listEle.className = "inputCompletionLICategory";
+ 			var liText = document.createTextNode(categoryName);
+			listEle.appendChild(liText);
+ 			this._completionUL.appendChild(listEle);
+		}
+		for(var i=0; i < categoryList.length; i++){
+			var listEle = document.createElement('li');
+			dojo.connect(listEle, "onmouseover", function(e){
+				that._selectProposal(e.currentTarget);
+			});
+			dojo.connect(listEle, "onclick", function(e){
+				that._dismiss(e.currentTarget.completionItem.value);
+			});
+			listEle.className = "inputCompletionLINormal";
+			listEle.completionItem = categoryList[i];
+ 			var liText = document.createTextNode(categoryList[i].value);
+			listEle.appendChild(liText);
+ 			this._completionUL.appendChild(listEle);
+ 			this._proposalList.push({item: categoryList[i], domNode: listEle});
+		}
+	};
+
+	InputCompletion.prototype._domNode2Index = function(domNode){
+		for(var i=0; i < this._proposalList.length; i++){
+			if(this._proposalList[i].domNode === domNode){
+				return i;
+			}
+		}
+		return -1;
+	};
+	
+	InputCompletion.prototype._highlight = function(indexOrDomNode, selected){
+		var domNode = indexOrDomNode;
+		var fromIndex = false;
+		if(!isNaN(domNode)){
+			fromIndex = true;
+			if(this._proposalList && indexOrDomNode >= 0 && indexOrDomNode < this._proposalList.length){
+				domNode = this._proposalList[indexOrDomNode].domNode;
+			} else {
+				domNode = null;
+			}
+		}
+		if(domNode){
+			domNode.className = (selected ? "inputCompletionLISelected": "inputCompletionLINormal");
+			if(selected && fromIndex){
+				if (domNode.offsetTop < this._completionUIContainer.scrollTop) {
+					domNode.scrollIntoView(true);
+				} else if ((domNode.offsetTop + domNode.offsetHeight) > (this._completionUIContainer.scrollTop + this._completionUIContainer.clientHeight)) {
+					domNode.scrollIntoView(false);
+				}
+			}
+		}
+	};
+
+	InputCompletion.prototype._selectProposal = function(indexOrDomNode){
+		var index = indexOrDomNode;
+		if(isNaN(index)){
+			index = this._domNode2Index(indexOrDomNode);
+		}
+		if(index !== this._proposalIndex){
+			this._highlight(this._proposalIndex, false);
+			this._proposalIndex = index;
+			this._highlight(this._proposalIndex, true);
+		}
+	};
+	
+	InputCompletion.prototype._dismiss = function(valueToInputField){
+		if(this._mouseDown){
+			return;
+		}
+		this._dismissed = true;
+		this._proposalList = null;
+		this._proposalIndex = -1;
+		if(valueToInputField){
+			this._inputField.value = valueToInputField;
+			this._dismissing = true;
+			this._inputField.focus();
+		}
+		var that = this;
+		window.setTimeout(function(){ //wait a few milliseconds for the proposal pane to hide 
+			that._completionUIContainer.style.display = "none";
+		}, 200);
+	};
+	
+	InputCompletion.prototype._show = function(){
+		if(this._proposalList && this._proposalList.length > 0){
+			this._completionUIContainer.style.display = "block"; //$NON-NLS-0$
+			this._completionUIContainer.style.top = this._inputField.offsetTop + this._inputField.offsetHeight + 2 + "px";
+			this._completionUIContainer.style.left = this._inputField.offsetLeft + "px";
+			this._completionUIContainer.style.width = this._inputField.offsetWidth + "px";
+			this._mouseDown = false;
+			this.dismissed = false;
+		} else {
+			this._dismissed = true;
+			this._proposalList = null;
+			this._proposalIndex = -1;
+			this._completionUIContainer.style.display = "none";
+		}
+	};
+	
+	InputCompletion.prototype._walk = function(forwad){
+		var index = this._proposalIndex + (forwad ? 1: -1);
+		if(index < -1){
+			index = this._proposalList.length -1;
+		} else if( index >= this._proposalList.length){
+			index = -1;
+		}
+		this._selectProposal(index);
+	}
+	
+	InputCompletion.prototype.onKeyPressed = function(e){
+		if (e.charOrCode === dojo.keys.ENTER) {
+			if(this._proposalList && this._proposalList.length > 0 && this._proposalIndex >= 0 && this._proposalIndex < this._proposalList.length){
+				this._dismiss(this._proposalList[this._proposalIndex].item.value);
+				return true;
+			}
+			return false;
+		} else if((e.charOrCode === dojo.keys.DOWN_ARROW || e.charOrCode === dojo.keys.UP_ARROW) && this._proposalList && this._proposalList.length > 0){
+			this._walk(e.charOrCode === dojo.keys.DOWN_ARROW);
+			return true;
+		}
+		return false;
+	};
+
+	InputCompletion.prototype.proposeOn = function(inputValue){
+		if(!this._dataList){
+			return;
+		}
+		dojo.empty(this._completionUIContainer);
+		this._completionUL = document.getElementById(this._completionIdPrefix + "UL__");//$NON-NLS-0$
+		if(!this._completionUL){
+			this._completionUL = document.createElement('ul');//$NON-NLS-0$
+			this._completionUL.id = this._completionIdPrefix + "UL__";//$NON-NLS-0$
+			this._completionUL.className = "inputCompletionUL";//$NON-NLS-0$
+		}
+		dojo.empty(this._completionUL);
+		this._completionUIContainer.appendChild(this._completionUL);
+		var searchTerm = inputValue ? inputValue.toLowerCase() : null;
+		this._proposalList = [];
+		var categoryName = "";
+		var categoryList = [];
+		for(var i=0; i < this._dataList.length; i++){
+			if(this._dataList[i].type === "category"){
+				this._proposeOnCategory(categoryName, categoryList);
+				categoryName = this._dataList[i].label;
+				categoryList = [];
+			} else {
+				var proposed = true;
+				if(searchTerm){
+					var searchOn = this._dataList[i].value.toLowerCase();
+					var pIndex = searchOn.indexOf(searchTerm);
+					if(pIndex < 0){
+						proposed = false;
+					} else if(this._proposeFromStart){
+						proposed = (pIndex === 0);
+					} 
+				}
+				if(proposed){
+					categoryList.push(this._dataList[i]);
+				}
+			}
+		}
+		this._proposeOnCategory(categoryName, categoryList);
+		this._show();
+	};
+	
+	InputCompletion.prototype.constructor = InputCompletion;
+
+	//return module exports
+	return {
+		InputCompletion: InputCompletion
+	};
+});
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/pluginregistry.js b/bundles/org.eclipse.orion.client.core/web/orion/pluginregistry.js
index 234c602..ae76144 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/pluginregistry.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/pluginregistry.js
@@ -12,7 +12,7 @@
 
 /*global define setTimeout clearTimeout addEventListener removeEventListener document console localStorage Worker*/
 
-define(["orion/Deferred", "orion/EventTarget"], function(Deferred, EventTarget){
+define(["orion/Deferred", "orion/EventTarget", "orion/Storage"], function(Deferred, EventTarget, Storage){
 
 	function _equal(obj1, obj2) {
 		var keys1 = Object.keys(obj1);
@@ -580,6 +580,9 @@
 	function PluginRegistry(serviceRegistry, configuration) {
 		configuration = configuration || {};
 		var _storage = configuration.storage || localStorage;
+		if (!_storage.getItem) {
+			_storage = new Storage(_storage);
+		}
 		var _state = "installed";
 		var _plugins = [];
 		var _channels = [];
@@ -657,10 +660,10 @@
 						break;
 					}
 				}
-				delete _storage["plugin."+plugin.getLocation()];
+				_storage.removeItem("plugin."+plugin.getLocation());
 			},
 			persist: function(url, manifest) {
-				_storage["plugin."+url] = JSON.stringify(manifest); //$NON-NLS-0$
+				_storage.setItem("plugin."+url,JSON.stringify(manifest)); //$NON-NLS-0$
 			},
 			postMessage: function(message, channel) {
 				channel.target.postMessage((channel.useStructuredClone ? message : JSON.stringify(message)), channel.url);
@@ -745,10 +748,14 @@
 				return;
 			}
 			addEventListener("message", _messageHandler, false);
-			Object.keys(_storage).forEach(function(key) {
+			var storageKeys = [];
+			for (var i = 0, length = _storage.length; i < length;i++) {
+				storageKeys.push(_storage.key(i));
+			}
+			storageKeys.forEach(function(key) {
 				if (key.indexOf("plugin.") === 0) {
 					var url = key.substring("plugin.".length);
-					var manifest = JSON.parse(_storage[key]);
+					var manifest = JSON.parse(_storage.getItem(key));
 					if (manifest.created) {
 						_plugins.push(new Plugin(url, manifest, internalRegistry));
 					}
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/preferences.js b/bundles/org.eclipse.orion.client.core/web/orion/preferences.js
index d7e938d..1dd1fa0 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/preferences.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/preferences.js
@@ -398,7 +398,6 @@
 		 * @param {String} name A slash-delimited path to the preference node to return
 		 */
 		getPreferences: function(name, optScope) {
-			
 			if (!optScope || typeof(optScope) !== "number" || optScope > 7 || optScope < 1) { //$NON-NLS-0$
 				optScope = PreferencesService.DEFAULT_SCOPE | PreferencesService.LOCAL_SCOPE | PreferencesService.USER_SCOPE;
 			}
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/serviceTracker.js b/bundles/org.eclipse.orion.client.core/web/orion/serviceTracker.js
index 22b7910..ea2adfc 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/serviceTracker.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/serviceTracker.js
@@ -16,7 +16,7 @@
 	 * @name orion.ServiceTracker
 	 * @class Simplifies the use of services within a service registry.
 	 * @description A ServiceTracker tracks matching services in the given service registry. Matching services are those
-	 * whose <code>service.names</code> property contains the given <code>serviceName</code>. The {@link #addingService} and 
+	 * whose <code>objectClass</code> property contains the given <code>serviceName</code>. The {@link #addingService} and 
 	 * {@link #removedService} methods can be overridden to customize the service objects being tracked.
 	 * @param {orion.serviceregistry.ServiceRegistry} serviceRegistry The service registry to track services of.
 	 * @param {String} serviceName The service name of services to be tracked.
@@ -44,7 +44,7 @@
 			this.removedService(serviceRef, service);
 		}
 		function isTrackable(serviceRef) {
-			return serviceRef.getProperty('service.names').indexOf(serviceName) !== -1; //$NON-NLS-0$
+			return serviceRef.getProperty('objectClass').indexOf(serviceName) !== -1; //$NON-NLS-0$
 		}
 
 		/**
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/widgets/plugin/PluginEntry.js b/bundles/org.eclipse.orion.client.core/web/orion/widgets/plugin/PluginEntry.js
index a041e7c..035e937 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/widgets/plugin/PluginEntry.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/widgets/plugin/PluginEntry.js
@@ -53,7 +53,7 @@
 		var serviceDescriptions = [];
 		plugin.getServiceReferences().forEach(function(reference) {
 			var serviceDescription = {
-				service: reference.getProperty("service.names").join(" "),
+				service: reference.getProperty("objectClass").join(" "),
 				items: []
 			};
 	
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/widgets/settings/LabeledCommand.js b/bundles/org.eclipse.orion.client.core/web/orion/widgets/settings/LabeledCommand.js
index 95c5390..6e8a2e2 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/widgets/settings/LabeledCommand.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/widgets/settings/LabeledCommand.js
@@ -14,7 +14,7 @@
 /* This SettingsContainer widget is a dojo border container with a left and right side. The left is for choosing a 

    category, the right shows the resulting HTML for that category. */

 

-define(['i18n!orion/settings/nls/messages', 'require', 'dojo', 'dijit', 'orion/util', 'orion/commands', 'orion/git/GitCredentialsStorage'], function(messages, require, dojo, dijit, mUtil, mCommands, GitCredentialsStorage) {

+define(['i18n!orion/settings/nls/messages', 'require', 'dojo', 'dijit', 'orion/util', 'orion/commands', 'orion/git/gitPreferenceStorage'], function(messages, require, dojo, dijit, mUtil, mCommands, GitPreferenceStorage) {

 

 	dojo.declare("orion.widgets.settings.LabeledCommand",[dijit._Widget, dijit._Templated],{ //$NON-NLS-0$

 		

@@ -28,14 +28,7 @@
 		destroy: function(){

 			dojo.empty(this.domNode);		

 		},

-        

-        change: function(){

-        	var gitCredentialsStorage = new GitCredentialsStorage();

-        	if(gitCredentialsStorage.isBrowserEnabled()){

-        		gitCredentialsStorage.erasePrompt(this.mylabel.innerHTML);

-        	}

-        },

-        

+                

         postCreate: function(){

             this.inherited( arguments );

             this.mylabel.innerHTML = this.fieldlabel; //$NON-NLS-0$

diff --git a/bundles/org.eclipse.orion.client.core/web/orion/widgets/settings/UserSettings.js b/bundles/org.eclipse.orion.client.core/web/orion/widgets/settings/UserSettings.js
index f6c6de6..bc6cc19 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/widgets/settings/UserSettings.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/widgets/settings/UserSettings.js
@@ -14,7 +14,7 @@
 /* This SettingsContainer widget is a dojo border container with a left and right side. The left is for choosing a 

    category, the right shows the resulting HTML for that category. */

 
-define(['i18n!orion/settings/nls/messages', 'require', 'dojo', 'dijit', 'orion/util', 'orion/commands', 'orion/section', 'orion/git/GitCredentialsStorage', 'orion/widgets/settings/LabeledTextfield', 'orion/widgets/settings/LabeledCheckbox', 'orion/widgets/settings/LabeledCommand', 'orion/widgets/settings/LabeledToggle', 'profile/UsersService', 'orion/widgets/settings/Section' ], function(messages, require, dojo, dijit, mUtil, mCommands, mSection, GitCredentialsStorage) {
+define(['i18n!orion/settings/nls/messages', 'require', 'dojo', 'dijit', 'orion/util', 'orion/commands', 'orion/section', 'orion/git/gitPreferenceStorage', 'orion/widgets/settings/LabeledTextfield', 'orion/widgets/settings/LabeledCheckbox', 'orion/widgets/settings/LabeledCommand', 'orion/widgets/settings/LabeledToggle', 'profile/UsersService', 'orion/widgets/settings/Section' ], function(messages, require, dojo, dijit, mUtil, mCommands, mSection, GitPreferenceStorage) {
 

 	dojo.declare("orion.widgets.settings.UserSettings", [dijit._Widget, dijit._Templated], { //$NON-NLS-0$

 	

@@ -59,10 +59,13 @@
 		},

 		

 		refreshGitCredentials : function(){

-			var gitCredentialsStorage = new GitCredentialsStorage();

-			if(gitCredentialsStorage.isBrowserEnabled()){

-				this.gitCredentialsFields[0].setChecked(gitCredentialsStorage.isUserEnabled());

-			}

+			var that = this;

+			var gitPreferenceStorage = new GitPreferenceStorage(this.registry);

+			gitPreferenceStorage.isEnabled().then(

+				function(isEnabled){

+					that.gitCredentialsFields[0].setChecked(isEnabled);

+				}

+			);

 		},

 		

 		postCreate: function(){

@@ -91,29 +94,6 @@
 			

 			var passwordSection = new orion.widgets.settings.Section( {sectionName:messages['Password'], container: this.sections, sections: this.passwordFields } );

 			

-			/* - linked ------------------------------------------------------ */

-			

-//			this.linkedFields = [];

-//			

-//			var toggleLabels = [ messages['Google'], messages['Yahoo'], messages['AOL'], messages['OpenId'] ];

-//			

-//			var openIds = [ 'https://www.google.com/accounts/o8/id', 'http://me.yahoo.com', 'http://openid.aol.com/', 'http://myopenid.com' ];//$NON-NLS-0$ //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$

-//			

-//			var toggleData = {toggleOnState:messages["Linked"], toggleOffState:messages["Unlinked"], toggleOnSwitch:messages['Link'], toggleOffSwitch:messages['Unlink']};

-//			

-//			for( var toggle = 0; toggle< 4; toggle++ ){

-//				toggleData.fieldlabel = toggleLabels[toggle];

-//				

-//				var toggleWidget = new orion.widgets.settings.LabeledToggle( toggleData );

-//				

-//				toggleWidget.onAction = dojo.hitch( this, 'confirmOpenId', openIds[toggle] ); //$NON-NLS-0$

-//				

-//				this.linkedFields.push( toggleWidget );

-//				

-//			}

-//			

-//			var linkedSection = new orion.widgets.settings.Section( {sectionName:messages['Linked Accounts'], container: this.sections, sections: this.linkedFields } );

-

 			/* - git --------------------------------------------------------- */

 			

 			this.gitFields = [];

@@ -154,12 +134,13 @@
 					

 					var messageService = that.registry.getService("orion.page.message");

 					

-					var gitCredentialsStorage = new GitCredentialsStorage();

-		       		if(gitCredentialsStorage.isBrowserEnabled()){

-		       			gitCredentialsStorage.erasePrompt(repository);

-		       			messageService.setProgressResult("Deleted private key for " + repository);

-		       			that.gitCredentialsFields[keyIndex+1].destroy();

-		       		}

+					var gitPreferenceStorage = new GitPreferenceStorage(that.registry);

+					gitPreferenceStorage.remove(repository).then(

+						function(){

+							messageService.setProgressResult("Deleted private key for " + repository);

+							that.gitCredentialsFields[keyIndex+1].destroy();

+						}

+					);

 				},

 				visibleWhen : function(item){

 					return true;

@@ -168,34 +149,34 @@
 			this.commandService.addCommand(erasePrivateKeyCommand);

 			this.commandService.registerCommandContribution("repositoryItemCommands", "eclipse.orion.git.erasePrivateKey", 1);

 			

-			var gitCredentialsStorage = new GitCredentialsStorage();

-			if(gitCredentialsStorage.isBrowserEnabled()){

-				var repositories = gitCredentialsStorage.getRepositories();

-				

-				for(var i=0; i<repositories.length; ++i){

-					if(!gitCredentialsStorage.getPrompt(repositories[i])){

-						var labeledCommand = new orion.widgets.settings.LabeledCommand( {keyIndex: i, fieldlabel: repositories[i], commandService: this.commandService, scopeId: "repositoryItemCommands"} );

-						this.gitCredentialsFields.push(labeledCommand);

+			var that = this;

+			var gitPreferenceStorage = new GitPreferenceStorage(this.registry);

+			gitPreferenceStorage.getRepositories().then(

+				function(repositories){

+					for(var i=0; i<repositories.length; ++i){

+						var labeledCommand = new orion.widgets.settings.LabeledCommand( {keyIndex: i, fieldlabel: repositories[i], commandService: that.commandService, scopeId: "repositoryItemCommands"} );

+						that.gitCredentialsFields.push(labeledCommand);

 					}

+					

+					gitCredentialsSection = new orion.widgets.settings.Section( {sectionName:"", container: that.gitSections, sections: that.gitCredentialsFields} );

+			

+					var updateGitCredentialsCommand = new mCommands.Command({

+						name: messages["Update"],

+						tooltip: messages["Update Git Credentials"],

+						id: "orion.updateGitCredentials", //$NON-NLS-0$

+						callback: dojo.hitch(that, function(data){

+							that.updateGitCredentials(data.items);

+						})

+					

+					});

+					

+					that.commandService.addCommand(updateGitCredentialsCommand);

+					that.commandService.registerCommandContribution('gitProfileCommands', "orion.updateGitCredentials", 2); //$NON-NLS-1$ //$NON-NLS-0$

+					

+					that.commandService.renderCommands('gitProfileCommands', dojo.byId( 'gitCommands' ), that, that, "button"); //$NON-NLS-1$ //$NON-NLS-0$		

+					

 				}

-			}

-			

-			gitCredentialsSection = new orion.widgets.settings.Section( {sectionName:"", container: this.gitSections, sections: this.gitCredentialsFields} );

-			
-			var updateGitCredentialsCommand = new mCommands.Command({

-				name: messages["Update"],

-				tooltip: messages["Update Git Credentials"],

-				id: "orion.updateGitCredentials", //$NON-NLS-0$

-				callback: dojo.hitch(this, function(data){

-					this.updateGitCredentials(data.items);

-				})

-			

-			});

-			

-			this.commandService.addCommand(updateGitCredentialsCommand);

-			this.commandService.registerCommandContribution('gitProfileCommands', "orion.updateGitCredentials", 2); //$NON-NLS-1$ //$NON-NLS-0$

-			

-			this.commandService.renderCommands('gitProfileCommands', dojo.byId( 'gitCommands' ), this, this, "button"); //$NON-NLS-1$ //$NON-NLS-0$		

+			);

 			

 			this.linkedAccountSection = new mSection.Section(this.linkedSection, {

 							id: "linkedAccountSection", //$NON-NLS-0$

@@ -298,16 +279,22 @@
 		updateGitCredentials : function(data){

 			var messageService = this.registry.getService("orion.page.message"); //$NON-NLS-0$

 			

-			// git authentication update

-			var gitCredentialsStorage = new GitCredentialsStorage();

-			if(gitCredentialsStorage.isBrowserEnabled()){

-				if( this.gitCredentialsFields[0].isChecked() ){

-					if(window.confirm(messages["Please be aware that your credentials will be stored persistently in the browser."] + '\n' + messages["Do you wish to enable the Key Storage?"])){

-						gitCredentialsStorage.userEnable();

-					} else { return; }

-				} else { gitCredentialsStorage.userDisable(); }

-				

-				messageService.setProgressResult( messages['Git Credentials successfully updated.'] );

+			// git authentication update
+			var gitPreferenceStorage = new GitPreferenceStorage(this.registry);

+			if( this.gitCredentialsFields[0].isChecked() ){

+				if(window.confirm(messages["Please be aware that your credentials will be stored persistently in the browser."] + '\n' + messages["Do you wish to enable the Key Storage?"])){

+					gitPreferenceStorage.enable().then(

+						function(){

+							messageService.setProgressResult( messages['Git Credentials successfully updated.'] );

+						}

+					);

+				} else { return; }

+			} else {

+				gitPreferenceStorage.disable().then(

+					function(){

+						messageService.setProgressResult( messages['Git Credentials successfully updated.'] );

+					}

+				);
 			}

 		},

 		

diff --git a/bundles/org.eclipse.orion.client.core/web/orion/widgets/themes/container/ThemeData.js b/bundles/org.eclipse.orion.client.core/web/orion/widgets/themes/container/ThemeData.js
index 56a2a23..204c202 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/widgets/themes/container/ThemeData.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/widgets/themes/container/ThemeData.js
@@ -191,6 +191,24 @@
 			

 			this.styles.push( blue );

 			

+			var raspberry = new StyleSet();

+			

+			raspberry.name = 'Raspberry Pi';

+			raspberry.navbar = '#679636';

+			raspberry.button = '#777777';

+			raspberry.location = '#F39E9A';

+			raspberry.selection = 'lightcoral';

+			raspberry.sidepanel = 'seashell';

+			raspberry.mainpanel = '#FDFADD';

+			raspberry.toolpanel = 'seashell';

+			raspberry.navtext = '#FBFBFB';

+			raspberry.content = 'E73E36';

+			raspberry.search = '#4c8623';

+			raspberry.breadcrumb = 'darkred';

+			raspberry.separator = '#CD2127';

+			

+			this.styles.push( raspberry );

+			

 		}

 		

 		function getStyles(){

diff --git a/bundles/org.eclipse.orion.client.core/web/orion/widgets/themes/editor/ThemeData.js b/bundles/org.eclipse.orion.client.core/web/orion/widgets/themes/editor/ThemeData.js
index 6d13b42..de23b72 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/widgets/themes/editor/ThemeData.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/widgets/themes/editor/ThemeData.js
@@ -160,6 +160,23 @@
 			

 			this.styles.push( adelante );

 			

+			var raspberry = new StyleSet();

+			

+			raspberry.name = 'Raspberry Pi';

+			raspberry.annotationRuler = 'seashell'; 

+			raspberry.background = 'seashell';

+			raspberry.comment = '#66B32F';

+			raspberry.keyword = '#E73E36';

+			raspberry.text = 'dimgray';

+			raspberry.string = 'darkorange';

+			raspberry.overviewRuler = 'seashell';

+			raspberry.lineNumberOdd = '#E73E36';

+			raspberry.lineNumberEven = '#E73E36';

+			raspberry.lineNumber = '#E73E36';

+			raspberry.currentLine = '#F5B1AE';

+			

+			this.styles.push( raspberry );

+			

 		}

 		

 		function getStyles(){

diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/asyncStyler.js b/bundles/org.eclipse.orion.client.editor/web/orion/editor/asyncStyler.js
index fe59426..00db9c9 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/asyncStyler.js
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/asyncStyler.js
@@ -21,7 +21,7 @@
 	});
 
 	function isRelevant(serviceReference) {
-		return serviceReference.getProperty("service.names").indexOf(SERVICE_NAME) !== -1 &&
+		return serviceReference.getProperty("objectClass").indexOf(SERVICE_NAME) !== -1 &&
 				serviceReference.getProperty("type") === "highlighter";
 	}
 
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/textview/textView.js b/bundles/org.eclipse.orion.client.editor/web/orion/textview/textView.js
index 6653e72..5a3488c 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/textview/textView.js
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/textview/textView.js
@@ -1673,7 +1673,8 @@
 		 * @property {Number} y The pointer location on the y axis, relative to the document the user is editing. 
 		 * @property {Number} screenX The pointer location on the x axis, relative to the screen. This is copied from the DOM contextmenu event.screenX property. 
 		 * @property {Number} screenY The pointer location on the y axis, relative to the screen. This is copied from the DOM contextmenu event.screenY property. 
-		 * @property {Boolean} defaultPrevented Determines whether the user agent context menu should be shown. It is not shown by default.
+		 * @property {Boolean} defaultPrevented Determines whether the user agent context menu should be shown. It is shown by default.
+		 * @property {Function} preventDefault If called prevents the user agent context menu from showing.
 		 */ 
 		/** 
 		 * This event is sent when the user invokes the view context menu. 
@@ -5972,7 +5973,7 @@
 				* in the scrollbar. It is possible this a bug since all other paddings are considered.
 				*/
 				scrollWidth = width;
-				if (!isIE || isIE >= 9) { width += viewPad.right; }
+				if ((!isIE || isIE >= 9) && this._maxLineWidth > clientWidth) { width += viewPad.right + viewPad.left; }
 				scrollDiv.style.width = width + "px"; //$NON-NLS-0$
 				if (this._clipScrollDiv) {
 					this._clipScrollDiv.style.width = width + "px"; //$NON-NLS-0$
diff --git a/bundles/org.eclipse.orion.client.git/web/git/nls/root/gitmessages.js b/bundles/org.eclipse.orion.client.git/web/git/nls/root/gitmessages.js
index af9e0d9..e0c328c 100644
--- a/bundles/org.eclipse.orion.client.git/web/git/nls/root/gitmessages.js
+++ b/bundles/org.eclipse.orion.client.git/web/git/nls/root/gitmessages.js
@@ -367,5 +367,14 @@
 	"Send the link to the reviewer" : "Send the link to the reviewer",

 	"Private key file (optional):" : "Private key file (optional):",

 	"Don't prompt me again:" : "Don't prompt me again:",

-	"Your private key will be saved in the browser for further use" : "Your private key will be saved in the browser for further use"
+	"Your private key will be saved in the browser for further use" : "Your private key will be saved in the browser for further use",

+	"Loading Contribution Review Request..." : "Loading Contribution Review Request...",

+	"The commit can be found in the following repositories" : "The commit can be found in the following repositories",

+	"Try to update your repositories" : "Try to update your repositories",

+	"Create new repository" : "Create new repository",

+	"Attach the remote to one of your existing repositories" : "Attach the remote to one of your existing repositories",

+	"You are reviewing contribution ${0} from ${1}" : "You are reviewing contribution ${0} from ${1}",

+	"Unfortunately the commit can not be found in your workspace. To see it try one of the following: " : "Unfortunately the commit can not be found in your workspace. To see it try one of the following: ",

+	"To review the commit you can also:" : "To review the commit you can also:",

+	"Contribution Review Request for ${0} on ${1}" : "Contribution Review Request for ${0} on ${1}"
 });
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/GitCredentialsStorage.js b/bundles/org.eclipse.orion.client.git/web/orion/git/GitCredentialsStorage.js
deleted file mode 100644
index 24bfcfa..0000000
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/GitCredentialsStorage.js
+++ /dev/null
@@ -1,243 +0,0 @@
-/*******************************************************************************

- * @license

- * Copyright (c) 2012 IBM Corporation and others.

- * All rights reserved. This program and the accompanying materials are made 

- * available under the terms of the Eclipse Public License v1.0 

- * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 

- * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). 

- *

- * Contributors: IBM Corporation - initial API and implementation

- *******************************************************************************/

- /*global define console window document navigator */

- 

- define(function(){

- 

-	/**

-	 * Local storage support class.

-	 *

-	 * @param prefix [required] Used to create a separate namespace for storage.

-	 */

-	function LocalStorage(prefix){

-		this._prefix = prefix;

-	}

-	

-	LocalStorage.prototype = {

-	

-		/**

-		 * [interface] Stores the pair (key, value)

-		 */

-		set : function(key, value){

-			var cKey = this._prefix + "." + key;

-			window.localStorage.setItem(cKey, value);

-		},

-		

-		/**

-		 * [interface] Retrieves the value for the given key.

-		 * Returns an empty string if key is not present.

-		 */

-		get : function(key){

-			var cKey = this._prefix + "." + key;

-			return (window.localStorage.getItem(cKey) === null ? "" : window.localStorage.getItem(cKey));

-		},

-		

-		/**

-		 * [interface] Erases the value for the given key.

-		 */

-		destroy : function(key){

-			var cKey = this._prefix + "." + key;

-			window.localStorage.removeItem(cKey);

-		},

-		

-		/**

-		 * [interface] Tests whether local storage is enabled or not.

-		 */

-		available : function(){

-			return (window.localStorage ? true : false);

-		},

-		

-		/**

-		 * [interface] Retrieves all saved keys without the prefix.

-		 */

-		getKeys : function(){

-			var result = [];

-			for(var i=0; i<window.localStorage.length; ++i){

-				var key = window.localStorage.key(i);

-				if(key.indexOf(this._prefix) === 0){

-					result.push(key.substring(this._prefix.length + 1, key.length));

-				}

-			}

-			

-			return result;

-		},

-		

-		/**

-		 * [interface] Clears all saved data.

-		 */

-		clear : function(){

-			var keys = this.getKeys();

-		

-			for(var i=0; i<keys.length; ++i){

-				var key = keys[i];

-				this.destroy(key);

-			}

-		}

-	};

-	

-	LocalStorage.prototype.constructor = LocalStorage;

-	

-	/**

-	 * Stores user git credentials for automatic authentication support.

-	 */

-	function GitCredentialsStorage(){

-		this._prefix = "orion.git.credentials";

-		this._browserEnabled = false;

-		

-		// detect and use underlying browser storage mechanism

-		if(this._supportsLocalStorage()){ this._store = new LocalStorage(this._prefix); this._browserEnabled = true; }

-	}

-	

-	GitCredentialsStorage.prototype = {

-		

-		/**

-		 * Detects if local storage is enabled.

-		 */

-		_supportsLocalStorage : function(){

-			var tmp = new LocalStorage();

-			return tmp.available();

-		},

-		

-		/**

-		 * Determines whether the storage feature is enabled or not.

-		 */

-		isUserEnabled : function(){

-			return (this._store.get("isUserEnabled") !== "" ? true : false);

-		},

-		

-		/**

-		 * Enables the use of credentials storage.

-		 */

-		userEnable : function(){

-			this._store.set("isUserEnabled", "true");

-		},

-		

-		/**

-		 * Disables the use of credentials storage.

-		 */

-		userDisable : function(){

-			this._store.destroy("isUserEnabled");

-		},

-		

-		/**

-		 * Informs if browser support credentials storage.

-		 */

-		isBrowserEnabled : function(){

-			return this._browserEnabled;

-		},

-				

-		/**

-		 * Informs if automatic authentication support

-		 * is enabled or not. If no brower storage mechanism

-		 * is present the support cannot be enabled and we will

-		 * have to switch to manual authentication instead.

-		 */

-		isEnabled : function(){

-			if(this._browserEnabled){ return this.isUserEnabled(); }

-			else { return false; }

-		},

-		

-		/**

-		 * Retrieves the stored private key.

-		 * Returns an empty string if no key was stored.

-		 */

-		getPrivateKey : function(repository){

-			return this._store.get(repository + "::" + "privateKey");

-		},

-		

-		/**

-		 * Stores the private key.

-		 */

-		setPrivateKey : function(repository, privateKey){

-			this._store.set(repository + "::" + "privateKey", privateKey);

-		},

-		

-		/**

-		 * Erases the private key.

-		 */

-		erasePrivateKey : function(repository){

-			this._store.destroy(repository + "::" + "privateKey");

-		},

-		

-		/**

-		 * Retrieves the stored passphrase.

-		 * Returns an empty string if no passphrase was found.

-		 */

-		getPassphrase : function(repository){

-			return this._store.get(repository + "::" + "passphrase");

-		},

-		

-		/**

-		 * Stores the passphrase.

-		 */

-		setPassphrase : function(repository, passphrase){

-			this._store.set(repository + "::" + "passphrase", passphrase);

-		},

-		

-		/**

-		 * Erases the passphrase.

-		 */

-		erasePassphrase : function(repository){

-			this._store.destroy(repository + "::" + "passphrase");

-		},

-		

-		/**

-		 * Returns whether the given repository should prompt for credentials or not.

-		 */

-		getPrompt : function(repository){

-			return (this._store.get(repository + "::" + "prompt") === "false" ? false : true);

-		},

-		

-		/**

-		 * Stores the information not to prompt for credentials.

-		 */

-		setPrompt : function(repository){

-			this._store.set(repository + "::" + "prompt", "false");

-		},

-		

-		/**

-		 * Erases the information to prompt for credentials.

-		 */

-		erasePrompt : function(repository){

-			this._store.destroy(repository + "::" + "prompt");

-		},

-		

-		/**

-		 * Clears all credentials.

-		 */

-		clearCredentials : function(){

-			this._store.clear();

-		},

-		

-		/**

-		 *	Returns repositories which have stored credentials.

-		 */

-		getRepositories : function(){

-			var keys = this._store.getKeys();

-			var result = [];

-			

-			for(var i=0; i<keys.length; ++i){

-				if(keys[i] !== "isUserEnabled"){

-					var repository = keys[i].substring(0, keys[i].indexOf("::"));

-					if(result.indexOf(repository) === -1){

-						result.push(repository);

-					}

-				}

-			}

-			

-			return result;

-		}

-	};

-	

-	GitCredentialsStorage.prototype.constructor = GitCredentialsStorage;

- 

-	return GitCredentialsStorage;

- });
\ No newline at end of file
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 c5b868d..7d59dad 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
@@ -11,11 +11,11 @@
 
 /*global alert confirm orion window widgets eclipse:true serviceRegistry define */
 /*jslint browser:true eqeqeq:false laxbreak:true */
-define(['i18n!git/nls/gitmessages', 'require', 'dojo', 'orion/commands', 'orion/util', 'orion/git/util', 'orion/compare/compareUtils', 'orion/git/GitCredentialsStorage', 'orion/git/widgets/CloneGitRepositoryDialog', 
+define(['i18n!git/nls/gitmessages', 'require', 'dojo', 'orion/commands', 'orion/util', 'orion/git/util', 'orion/compare/compareUtils', 'orion/git/gitPreferenceStorage', 'orion/git/widgets/CloneGitRepositoryDialog', 
         'orion/git/widgets/AddRemoteDialog', 'orion/git/widgets/GitCredentialsDialog', 'orion/widgets/NewItemDialog', 
         'orion/git/widgets/RemotePrompterDialog', 'orion/git/widgets/ApplyPatchDialog', 'orion/git/widgets/OpenCommitDialog', 'orion/git/widgets/ConfirmPushDialog', 'orion/git/widgets/ReviewRequestDialog', 
         'orion/git/widgets/ContentDialog', 'orion/git/widgets/CommitDialog'], 
-        function(messages, require, dojo, mCommands, mUtil, mGitUtil, mCompareUtils, GitCredentialsStorage) {
+        function(messages, require, dojo, mCommands, mUtil, mGitUtil, mCompareUtils, GitPreferenceStorage) {
 
 /**
  * @namespace The global container for eclipse APIs.
@@ -116,38 +116,40 @@
 
 	exports.handleSshAuthenticationError = function(serviceRegistry, errorData, options, func, title){
 		var repository = errorData.Url;
-		var gitCredentialsStorage = new GitCredentialsStorage();
-		var loadedPrivateKey = "", loadedPassphrase = "";
-						
-		if(gitCredentialsStorage.isEnabled() && !gitCredentialsStorage.getPrompt(repository)){
-			loadedPrivateKey = gitCredentialsStorage.getPrivateKey(repository);
-			loadedPassphrase = gitCredentialsStorage.getPassphrase(repository);
-		}
 		
-		if(loadedPrivateKey !== ""){
+		var failure = function(){
+			var credentialsDialog = new orion.git.widgets.GitCredentialsDialog({
+				title: title,
+				serviceRegistry: serviceRegistry,
+				func: func,
+				errordata: options.errordata,
+				failedOperation: options.failedOperation
+			});
+				
+			credentialsDialog.startup();
+			credentialsDialog.show();
 			if(options.failedOperation){
 				var progressService = serviceRegistry.getService("orion.page.progress"); //$NON-NLS-0$
 				dojo.hitch(progressService, progressService.removeOperation)(options.failedOperation.Location, options.failedOperation.Id);
 			}
+		};
 		
-			func({ knownHosts: options.knownHosts, gitSshUsername: "", gitSshPassword: "", gitPrivateKey: loadedPrivateKey, gitPassphrase: loadedPassphrase}); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-			return;
-		}
-	
-		var credentialsDialog = new orion.git.widgets.GitCredentialsDialog({
-			title: title,
-			serviceRegistry: serviceRegistry,
-			func: func,
-			errordata: options.errordata,
-			failedOperation: options.failedOperation
-		});
-		
-		credentialsDialog.startup();
-		credentialsDialog.show();
-		if(options.failedOperation){
-			var progressService = serviceRegistry.getService("orion.page.progress"); //$NON-NLS-0$
-			dojo.hitch(progressService, progressService.removeOperation)(options.failedOperation.Location, options.failedOperation.Id);
-		}
+		var gitPreferenceStorage = new GitPreferenceStorage(serviceRegistry);
+		gitPreferenceStorage.get(repository).then(
+			function(credentials){
+				if(credentials.gitPrivateKey !== "" || credentials.gitSshUsername !== "" || credentials.gitSshPassword !== ""){
+					if(options.failedOperation){
+						var progressService = serviceRegistry.getService("orion.page.progress"); //$NON-NLS-0$
+						dojo.hitch(progressService, progressService.removeOperation)(options.failedOperation.Location, options.failedOperation.Id);
+					}
+				
+					func({ knownHosts: options.knownHosts, gitSshUsername: credentials.gitSshUsername, gitSshPassword: credentials.gitSshPassword, gitPrivateKey: credentials.gitPrivateKey, gitPassphrase: credentials.gitPassphrase}); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+					return;
+				}
+				
+				failure();
+			}, failure
+		);
 	};
 
 	exports.getDefaultSshOptions = function(serviceRegistry, authParameters){
@@ -232,7 +234,7 @@
 
 	exports.gatherSshCredentials = function(serviceRegistry, data, title){
 		var def = new dojo.Deferred();
-		var repository = undefined;
+		var repository;
 		
 		//TODO This should be somehow unified
 		if(data.items.RemoteLocation !== undefined){ repository = data.items.RemoteLocation[0].GitUrl; }
@@ -260,56 +262,65 @@
 				var sshService = serviceRegistry.getService("orion.net.ssh"); //$NON-NLS-0$
 				sshService.addKnownHosts(errorData.Host + " " + errorData.KeyType + " " + errorData.HostKey).then( //$NON-NLS-1$ //$NON-NLS-0$
 					function(){
-						var gitCredentialsStorage = new GitCredentialsStorage();
-						var loadedPrivateKey = "", loadedPassphrase = "";
-						
-						if(gitCredentialsStorage.isEnabled() && !gitCredentialsStorage.getPrompt(repository)){
-							loadedPrivateKey = gitCredentialsStorage.getPrivateKey(repository);
-							loadedPassphrase = gitCredentialsStorage.getPassphrase(repository);
-						}
-					
-						triggerCallback({ gitSshUsername: "", gitSshPassword: "", gitPrivateKey: loadedPrivateKey, gitPassphrase: loadedPassphrase}); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+						var gitPreferenceStorage = new GitPreferenceStorage(serviceRegistry);
+						gitPreferenceStorage.get(repository).then(
+							function(credentials){
+								triggerCallback(credentials);
+							},
+							function(){
+								triggerCallback({
+									gitSshUsername: "",
+									gitSshPassword: "",
+									gitPrivateKey: "",
+									gitPassphrase: ""
+								});
+							}
+						);
 					}
-				);					
+				);
 			}
 			return def;
 		}
 		
-		var gitCredentialsStorage = new GitCredentialsStorage();
-		if(gitCredentialsStorage.isEnabled() && !gitCredentialsStorage.getPrompt(repository)){
-			var loadedPrivateKey = gitCredentialsStorage.getPrivateKey(repository);
-			var loadedPassphrase = gitCredentialsStorage.getPassphrase(repository);
-			
-			if(loadedPrivateKey !== ""){
-				triggerCallback({ gitSshUsername: "", gitSshPassword: "", gitPrivateKey: loadedPrivateKey, gitPassphrase: loadedPassphrase});
-				return def;
+		var failure = function(){
+			if (!data.parameters && !data.optionsRequested){
+				triggerCallback({gitSshUsername: "", gitSshPassword: "", gitPrivateKey: "", gitPassphrase: ""}); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+				return;
 			}
-		}
 		
-		if (!data.parameters && !data.optionsRequested){
-			triggerCallback({gitSshUsername: "", gitSshPassword: "", gitPrivateKey: "", gitPassphrase: ""}); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-			return def;
-		}
+			// try to gather creds from the slideout first
+			if (data.parameters && !data.optionsRequested) {
+				var sshUser =  data.parameters ? data.parameters.valueFor("sshuser") : ""; //$NON-NLS-0$
+				var sshPassword = data.parameters ? data.parameters.valueFor("sshpassword") : "";	 //$NON-NLS-0$
+				triggerCallback({ gitSshUsername: sshUser, gitSshPassword: sshPassword, gitPrivateKey: "", gitPassphrase: ""}); //$NON-NLS-0$
+				return;
+			}
+				
+			// use the old creds dialog
+			var credentialsDialog = new orion.git.widgets.GitCredentialsDialog({
+				title: title,
+				serviceRegistry: serviceRegistry,
+				func: triggerCallback,
+				errordata: errorData
+			});
+				
+			credentialsDialog.startup();
+			credentialsDialog.show();
+			return;
+		};
 
-		// try to gather creds from the slideout first
-		if (data.parameters && !data.optionsRequested) {
-			var sshUser =  data.parameters ? data.parameters.valueFor("sshuser") : ""; //$NON-NLS-0$
-			var sshPassword = data.parameters ? data.parameters.valueFor("sshpassword") : "";	 //$NON-NLS-0$
-			triggerCallback({ gitSshUsername: sshUser, gitSshPassword: sshPassword, gitPrivateKey: "", gitPassphrase: ""}); //$NON-NLS-0$
-			return def;
-		}
+		var gitPreferenceStorage = new GitPreferenceStorage(serviceRegistry);
+		gitPreferenceStorage.get(repository).then(
+			function(credentials){
+				if(credentials.gitPrivateKey !== "" || credentials.gitSshUsername !== "" || credentials.gitSshPassword !== ""){
+					triggerCallback(credentials);
+					return;
+				}
+				
+				failure();
+			}, failure
+		);
 		
-		// use the old creds dialog
-		var credentialsDialog = new orion.git.widgets.GitCredentialsDialog({
-			title: title,
-			serviceRegistry: serviceRegistry,
-			func: triggerCallback,
-			errordata: errorData
-		});
-		
-		credentialsDialog.startup();
-		credentialsDialog.show();
-
 		return def;
 	};
 	
@@ -325,13 +336,11 @@
 		}
 		
 		if(jsonData.HttpCode == 500 || jsonData.HttpCode == 400){
-			var repository = jsonData.JsonData.Url;
-			
-			var gitCredentialsStorage = new GitCredentialsStorage();
-			if(gitCredentialsStorage.isEnabled()){
-				gitCredentialsStorage.erasePrivateKey(repository);
-				gitCredentialsStorage.erasePassphrase(repository);
-				gitCredentialsStorage.erasePrompt(repository);
+			if(jsonData.JsonData !== undefined){
+				var repository = jsonData.JsonData.Url;
+				
+				var gitPreferenceStorage = new GitPreferenceStorage(serviceRegistry);
+				gitPreferenceStorage.remove(repository);
 			}
 		}
 		
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/gitPreferenceStorage.js b/bundles/org.eclipse.orion.client.git/web/orion/git/gitPreferenceStorage.js
new file mode 100644
index 0000000..7eedcd1
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/gitPreferenceStorage.js
@@ -0,0 +1,199 @@
+/*******************************************************************************

+ * @license

+ * Copyright (c) 2012 IBM Corporation and others.

+ * All rights reserved. This program and the accompanying materials are made 

+ * available under the terms of the Eclipse Public License v1.0 

+ * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 

+ * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). 

+ *

+ * Contributors: IBM Corporation - initial API and implementation

+ *******************************************************************************/

+ /*global define console window document navigator */

+ 

+ define(['orion/Deferred'], function(Deferred){

+ 

+	/**

+	 * Support class for using the orion preferences as a local

+	 * git credentials storage.

+	 *

+	 * @param serviceRegistry [required] Service registry

+	 */

+	function PreferenceStorage(serviceRegistry){

+		this._prefix = "/git/credentials";

+		this._preferenceService = serviceRegistry.getService("orion.core.preference");

+	}

+	

+	PreferenceStorage.prototype = {

+		/**

+		 * Saves the given git credentials for the given repository.

+		 *

+		 * @param repository [required] unique repository URL

+		 * @param userCredentials.gitSshUsername [optional] git ssh username

+		 * @param userCredentials.gitSshPassword [optional] git ssh password

+		 * @param userCredentials.gitPrivateKey [optional] git private key

+		 * @param userCredentials.gitPassphrase [optional] git passphrase

+		 */

+		put : function(repository, userCredentials){

+			var credentials = {

+				gitSshUsername : "",

+				gitSshPassword : "",

+				gitPrivateKey : "",

+				gitPassphrase : ""

+			};

+			

+			if(userCredentials !== undefined){

+				if(userCredentials.sshUsername !== undefined) { credentials.gitSshUsername = userCredentials.gitSshUsername; }

+				if(userCredentials.sshPassword !== undefined) { credentials.gitSshPassword = userCredentials.gitSshPassword; }

+				if(userCredentials.gitPrivateKey !== undefined) { credentials.gitPrivateKey = userCredentials.gitPrivateKey; }

+				if(userCredentials.gitPassphrase !== undefined) { credentials.gitPassphrase = userCredentials.gitPassphrase; }

+			}

+			

+			var d = new Deferred();

+			this._preferenceService.getPreferences(this._prefix, 2).then(

+				function(pref){

+					var settings = pref.get("settings");

+					if(settings === undefined){

+						d.reject();

+						return;

+					}

+				

+					if(settings.enabled){

+						pref.put(repository, credentials);

+						d.resolve();

+					} else { d.reject(); }

+				}

+			);

+			

+			return d;

+		},

+		

+		/**

+		 * Retrieves git credentials for the given repository.

+		 * Some credentials fields may be in form of empty strings if not present in the storage.

+		 *

+		 * @param repository [required] unique repository URL

+		 */

+		get : function(repository){

+			var credentials = {

+				gitSshUsername : "",

+				gitSshPassword : "",

+				gitPrivateKey : "",

+				gitPassphrase : ""

+			};

+			

+			var d = new Deferred();

+			this._preferenceService.getPreferences(this._prefix, 2).then(

+				function(pref){

+					var settings = pref.get("settings");

+					if(settings === undefined){

+						d.reject();

+						return;

+					}

+				

+					if(settings.enabled){

+						var userCredentials = pref.get(repository);

+						if(userCredentials !== undefined) { d.resolve(userCredentials); }

+						else { d.resolve(credentials); }

+					} else { d.reject(); }

+				}

+			);

+			

+			return d;

+		},

+		

+		/**

+		 * Determines whether the storage is enabled by the user or not.

+		 */

+		isEnabled : function(){

+			var d = new Deferred();

+			this._preferenceService.getPreferences(this._prefix, 2).then(

+				function(pref){

+					var settings = pref.get("settings");

+					if(settings === undefined){

+						d.resolve(false);

+						return;

+					}

+					

+					d.resolve(settings.enabled);

+				}

+			);

+			

+			return d;

+		},

+		

+		/**

+		 * Enables the storage for futher use.

+		 */

+		enable : function(){

+			var d = new Deferred();

+			this._preferenceService.getPreferences(this._prefix, 2).then(

+				function(pref){

+					pref.put("settings", { enabled : true });

+					d.resolve();

+				}

+			);

+			

+			return d;

+		},

+		

+		/**

+		 * Disables the storage.

+		 * Please note no credentials are erased.

+		 */

+		disable : function(){

+			var d = new Deferred();

+			this._preferenceService.getPreferences(this._prefix, 2).then(

+				function(pref){

+					pref.put("settings", { enabled : false });

+					d.resolve();

+				}

+			);

+			

+			return d;

+		},

+		

+		/**

+		 * Removes all credentials for the given repository.

+		 *

+		 * @param repository [required] unique repository URL

+		 */

+		remove : function(repository){

+			var d = new Deferred();

+			this._preferenceService.getPreferences(this._prefix, 2).then(

+				function(pref){

+					pref.remove(repository);

+					d.resolve();

+				}

+			);

+			

+			return d;

+		},

+		

+		/**

+		 * Returns all repository URLs, which have stored

+		 * credentials in the storage.

+		 */

+		getRepositories : function(){

+			var d = new Deferred();

+			this._preferenceService.getPreferences(this._prefix, 2).then(

+				function(pref){

+					var result = [];

+					var repositories = pref.keys();

+					

+					for(var i=0; i<repositories.length; ++i){

+						if(repositories[i] !== "settings"){

+							result.push(repositories[i]);

+						}

+					}

+					

+					d.resolve(result);

+				}

+			);

+			

+			return d;

+		}

+	};

+	

+	PreferenceStorage.prototype.constructor = PreferenceStorage;

+	return PreferenceStorage;

+ });
\ No newline at end of file
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/gitReviewRequestExplorer.js b/bundles/org.eclipse.orion.client.git/web/orion/git/gitReviewRequestExplorer.js
index 88efbc4..5ab62d4 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/gitReviewRequestExplorer.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/gitReviewRequestExplorer.js
@@ -47,7 +47,7 @@
 		GitReviewRequestExplorer.prototype.display = function(remote_sha){
 			this.progressService = this.registry.getService("orion.page.message"); //$NON-NLS-0$
 			this.loadingDeferred = new dojo.Deferred();
-			this.progressService.showWhile(this.loadingDeferred, "Loading Contribution Review Request ..."); //$NON-NLS-0$
+			this.progressService.showWhile(this.loadingDeferred, messages["Loading Contribution Review Request..."]); //$NON-NLS-0$
 			var that = this;
 			var params = [];
 			var n = remote_sha.lastIndexOf("_");
@@ -83,7 +83,7 @@
 					dojo.create("div", {style: "padding-top: 30px" }, dojo.byId("welcomeDiv"));
 					var titleWrapper1 = new mSection.Section(dojo.byId("commitDiv"), {
 						id: "open commit from existing repository", //$NON-NLS-0$
-						title: "The commit can be found on the following repositories", //$NON-NLS-0$
+						title: messages["The commit can be found in the following repositories"], //$NON-NLS-0$
 						slideout: true,
 						canHide: true,
 						preferenceService: that.registry.getService("orion.core.preference"),
@@ -92,7 +92,7 @@
 					
 					var titleWrapper2 = new mSection.Section(dojo.byId("fetchDiv"), {
 						id: "fetch section", //$NON-NLS-0$
-						title: "Try to update your repositories", //$NON-NLS-0$
+						title: messages["Try to update your repositories"], //$NON-NLS-0$
 						slideout: true,
 						canHide: true,
 						preferenceService: that.registry.getService("orion.core.preference"),
@@ -101,13 +101,13 @@
 					
 					var titleWrapper3 = new mSection.Section(tableNode, {
 						id: "create new clone", //$NON-NLS-0$
-						title: "Create new repository", //$NON-NLS-0$
+						title: messages["Create new repository"], //$NON-NLS-0$
 						content: '<div id="cloneNode" class="mainPadding"></list>' //$NON-NLS-0$
 					});
 					
 					var titleWrapper4 = new mSection.Section(dojo.byId("remoteDiv"), {
 						id: "add", //$NON-NLS-0$
-						title: "Attach the remote to one of existing repositories", //$NON-NLS-0$
+						title: messages["Attach the remote to one of your existing repositories"], //$NON-NLS-0$
 						slideout: true,
 						canHide: true,
 						hidden: true,
@@ -118,9 +118,10 @@
 					dojo.byId("fetchDiv").style.display = " none ";
 					dojo.byId("remoteDiv").style.display = " none ";
 					dojo.byId("moreOptionsDiv").style.display = " none ";
-					var text =  "You are trying to review contribution " + params[1] + " from " + params[2] ;
-					var text2 = "Unfortunately the commit can not be found in your workspace. To see it try one of the following: ";
-					dojo.byId("moreOptionsDiv").innerHTML = "To review the commit you can also";
+					
+					var text = dojo.string.substitute(messages["You are reviewing contribution ${0} from ${1}"], [params[1], params[2]]);
+					var text2 = messages["Unfortunately the commit can not be found in your workspace. To see it try one of the following: "];
+					dojo.byId("moreOptionsDiv").innerHTML = messages["To review the commit you can also:"];
 					dojo.create("span", {"class" : "gitSecondaryDescription", innerHTML : text, "style" : "padding : 5px, display: block", "id": "welcome"}, dojo.byId("descriptionHeader"));
 					dojo.create("span", {"class" : "gitSecondaryDescription", innerHTML : text2, "style" : "display: block", "id" : "instruction"}, dojo.byId("descriptionHeader"));
 					that.renderCloneSection(params);
@@ -198,8 +199,8 @@
 											dojo.create("div", {id : resp.Children[0].Id + "div" , "class": "stretch"},  dojo.byId(resp.Children[0].Id + "tableitem"));
 											dojo.create("div", {id : resp.Children[0].Id + "divCommands" , "class": "sectionTableItemActions" },  dojo.byId(resp.Children[0].Id + "tableitem"));
 											var link2 = dojo.create("a", {style: "padding: 0px; text-align: left; display: inline-block;  width: 150px", innerHTML: repositories[0].Name , href: repoURL },  dojo.byId(resp.Children[0].Id + "div"));
-											dojo.create("span", {"class": "gitSecondaryDescription", innerHTML: "location: " + repositories[0].Content.Path},dojo.byId(resp.Children[0].Id + "div"));
-											var link = dojo.create("a", {id : resp.Children[0].Id + "a", style: "padding: 0px; text-align: left; width: 50px", innerHTML: "Open Commit", href: commitPageURL },  dojo.byId(resp.Children[0].Id + "divCommands"));
+											dojo.create("span", {"class": "gitSecondaryDescription", innerHTML: messages["location: "] + repositories[0].Content.Path},dojo.byId(resp.Children[0].Id + "div"));
+											var link = dojo.create("a", {id : resp.Children[0].Id + "a", style: "padding: 0px; text-align: left; width: 50px", innerHTML: messages["Open Commit"], href: commitPageURL },  dojo.byId(resp.Children[0].Id + "divCommands"));
 											dojo.byId("commitDiv").style.display = " block ";
 											dojo.byId("moreOptionsDiv").style.display = " block ";
 											dojo.byId("instruction").style.display = " none ";
@@ -251,7 +252,7 @@
 											dojo.create("div", {id : resp.Children[0].Id + "div" , "class": "stretch" },  dojo.byId(resp.Children[0].Id + "tableitem"));
 											dojo.create("div", {id : resp.Children[0].Id + "divCommands" , "class": "sectionTableItemActions" },  dojo.byId(resp.Children[0].Id + "tableitem"));
 											dojo.create("a", {id : resp.Children[0].Id, style: "padding: 0px; text-align: left; display: inline-block;  width: 150px", innerHTML: resp.Children[0].Name + "    " , href: repoURL },  dojo.byId(resp.Children[0].Id + "div"));
-											dojo.create("span", {"class": "gitSecondaryDescription", innerHTML: "location: " + repositories[0].Content.Path},dojo.byId(resp.Children[0].Id + "div"));
+											dojo.create("span", {"class": "gitSecondaryDescription", innerHTML: messages["location: "] + repositories[0].Content.Path},dojo.byId(resp.Children[0].Id + "div"));
 											that.commandService.renderCommands("fetch", dojo.byId(resp.Children[0].Id + "divCommands"), remotes.Children[index], that, "tool");
 											dojo.byId("fetchDiv").style.display = " block ";
 											var style = dojo.style("commitDiv", "display");
@@ -263,7 +264,7 @@
 									dojo.create("div", {id : resp.Children[0].Id + "div" , "class": "stretch" },  dojo.byId(resp.Children[0].Id + "tableitem"));
 									dojo.create("div", {id : resp.Children[0].Id + "divCommands" , "class": "sectionTableItemActions" },  dojo.byId(resp.Children[0].Id + "tableitem"));
 									dojo.create("a", {id : resp.Children[0].Id, style: "padding: 0px; text-align: left; display: inline-block;  width: 150px", innerHTML: resp.Children[0].Name + "    " , href: repoURL },  dojo.byId(resp.Children[0].Id + "div"));
-									dojo.create("span", {"class": "gitSecondaryDescription", innerHTML: "location: " + repositories[0].Content.Path},dojo.byId(resp.Children[0].Id + "div"));
+									dojo.create("span", {"class": "gitSecondaryDescription", innerHTML: messages["location: "] + repositories[0].Content.Path},dojo.byId(resp.Children[0].Id + "div"));
 									that.commandService.renderCommands("add", dojo.byId(resp.Children[0].Id + "divCommands"), resp.Children[0], that, "tool",  url1);
 									dojo.byId("remoteDiv").style.display = " block ";
 									 for(var i=0;i<remotes.Children.length;i++){	
@@ -281,7 +282,7 @@
 		};
 		
 		GitReviewRequestExplorer.prototype.initTitleBar = function(commit, url){
-			var title = "Contribution Review Request for " + commit + " on " + url;
+			var title = dojo.string.substitute(messages["Contribution Review Request for ${0} on ${1}"], [commit, url]);
 			
 			var item = {};
 			item.Name = title;
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/GitCredentialsDialog.js b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/GitCredentialsDialog.js
index 77865cd..b7055f9 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/GitCredentialsDialog.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/GitCredentialsDialog.js
@@ -11,7 +11,7 @@
 
 /*global dojo dijit widgets FileReader define orion*/
 /*jslint browser:true*/
-define(['i18n!git/nls/gitmessages', 'dojo', 'dijit', 'dijit/Tooltip', 'orion/git/GitCredentialsStorage', 'dijit/Dialog', 'orion/widgets/_OrionDialogMixin', 'text!orion/git/widgets/templates/GitCredentialsDialog.html'], function(messages, dojo, dijit, Tooltip, GitCredentialsStorage) {
+define(['i18n!git/nls/gitmessages', 'dojo', 'dijit', 'dijit/Tooltip', 'orion/git/gitPreferenceStorage', 'dijit/Dialog', 'orion/widgets/_OrionDialogMixin', 'text!orion/git/widgets/templates/GitCredentialsDialog.html'], function(messages, dojo, dijit, Tooltip, GitPreferenceStorage) {
 
 
 /**
@@ -84,13 +84,19 @@
 			 setTimeout(function () { self.gitSshPassword.focus(); }, 400);
 		}
 		
+		var that = this;
+		
 		// display prompt checkbox only when it makes sense
-		var gitCredentialsStorage = new GitCredentialsStorage();
-		if(!gitCredentialsStorage.isEnabled()){
-			dojo.style(this.gitSavePrivateKey, "display", "none");
-			dojo.style(this.gitSavePrivateKeyLabel, "display", "none");
-			dojo.style(this.gitSavePrivateKeyInfo, "display", "none");
-		}
+		var gitPreferenceStorage = new GitPreferenceStorage(self.options.serviceRegistry);
+		gitPreferenceStorage.isEnabled().then(
+			function(isEnabled){
+				if(!isEnabled){
+					dojo.style(that.gitSavePrivateKey, "display", "none");
+					dojo.style(that.gitSavePrivateKeyLabel, "display", "none");
+					dojo.style(that.gitSavePrivateKeyInfo, "display", "none");
+				}
+			}
+		);
 		
 		dojo.connect(this.gitSshPassword, "onfocus", null, dojo.hitch(this, function(){
 			this.isSshPassword.checked = true;
@@ -155,30 +161,44 @@
 			reader.onload = (function(f){
 				return function(e){
 					loadedPrivateKey = e.target.result;
-					
-					//save key
-					var gitCredentialsStorage = new GitCredentialsStorage();
-					if(gitCredentialsStorage.isEnabled() && self.gitSavePrivateKey.checked){
-						gitCredentialsStorage.setPrivateKey(repository, loadedPrivateKey);
-						gitCredentialsStorage.setPassphrase(repository, self.gitPassphrase.value);
-						gitCredentialsStorage.setPrompt(repository);
+										
+					var gitPreferenceStorage = new GitPreferenceStorage(self.options.serviceRegistry);
+					if(self.gitSavePrivateKey.checked){
+						
+						gitPreferenceStorage.put(repository, {
+							gitPrivateKey : loadedPrivateKey,
+							gitPassphrase : self.gitPassphrase.value
+						}).then(
+							function(){
+								process(loadedPrivateKey);
+							}
+						);
+						
+					} else {
+						process(loadedPrivateKey);
 					}
-					
-					process(loadedPrivateKey);
 				};
 			}(this.privateKeyFile));
 			
 			reader.readAsText(this.privateKeyFile);
 		} else if(loadedPrivateKey){
-				//save key
-				var gitCredentialsStorage = new GitCredentialsStorage();
-				if(gitCredentialsStorage.isEnabled() && self.gitSavePrivateKey.checked){
-					gitCredentialsStorage.setPrivateKey(repository, loadedPrivateKey);
-					gitCredentialsStorage.setPassphrase(repository, self.gitPassphrase.value);
-					gitCredentialsStorage.setPrompt(repository);
-				}
+
+				//save key				
+				var gitPreferenceStorage = new GitPreferenceStorage(self.options.serviceRegistry);
+				if(self.gitSavePrivateKey.checked){
 					
-				process(loadedPrivateKey);
+					gitPreferenceStorage.put(repository, {
+						gitPrivateKey : loadedPrivateKey,
+						gitPassphrase : self.gitPassphrase.value
+					}).then(
+						function(){
+							process(loadedPrivateKey);
+						}
+					);
+					
+				} else {
+					process(loadedPrivateKey);
+				}
 		} else { process(loadedPrivateKey); }
 	}
 });