diff --git a/apps/files_external/ajax/addMountPoint.php b/apps/files_external/ajax/addMountPoint.php
index 4cd8871b310c34384f979b0390a4274919cc23b2..fed2ddfcf3d95e3597b6426b0eac3cdf0cedabfa 100644
--- a/apps/files_external/ajax/addMountPoint.php
+++ b/apps/files_external/ajax/addMountPoint.php
@@ -10,9 +10,10 @@ if ($_POST['isPersonal'] == 'true') {
 	OCP\JSON::checkAdminUser();
 	$isPersonal = false;
 }
-OC_Mount_Config::addMountPoint($_POST['mountPoint'],
+$status = OC_Mount_Config::addMountPoint($_POST['mountPoint'],
 							   $_POST['class'],
 							   $_POST['classOptions'],
 							   $_POST['mountType'],
 							   $_POST['applicable'],
-							   $isPersonal);
\ No newline at end of file
+							   $isPersonal);
+OCP\JSON::success(array('data' => array('message' => $status)));
\ No newline at end of file
diff --git a/apps/files_external/css/settings.css b/apps/files_external/css/settings.css
index ca4b1c3ba8937d6affb071e89621cf047fa227ad..94b453793b1badda59574975a89fb9da90893b4e 100644
--- a/apps/files_external/css/settings.css
+++ b/apps/files_external/css/settings.css
@@ -1,4 +1,7 @@
-.error { color: #FF3B3B; }
+td.status>span { display:inline-block; height:16px; width:16px; }
+span.success { background-image: url('../img/success.png'); background-repeat:no-repeat; }
+span.error { background-image: url('../img/error.png'); background-repeat:no-repeat; }
+span.waiting { background-image: url('../img/waiting.png'); background-repeat:no-repeat; }
 td.mountPoint, td.backend { width:10em; }
 td.remove>img { visibility:hidden; padding-top:0.8em; }
 tr:hover>td.remove>img { visibility:visible; cursor:pointer; }
diff --git a/apps/files_external/img/error.png b/apps/files_external/img/error.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8cf45e7a41e358da5d573dc48edf966b9d8d3cb
Binary files /dev/null and b/apps/files_external/img/error.png differ
diff --git a/apps/files_external/img/success.png b/apps/files_external/img/success.png
new file mode 100644
index 0000000000000000000000000000000000000000..6f7022ee7f5672b43bdf72f848a7358e4473eb60
Binary files /dev/null and b/apps/files_external/img/success.png differ
diff --git a/apps/files_external/img/waiting.png b/apps/files_external/img/waiting.png
new file mode 100644
index 0000000000000000000000000000000000000000..02a8cbff0da63ad584ae7a5c11ddefdf0bd9e24b
Binary files /dev/null and b/apps/files_external/img/waiting.png differ
diff --git a/apps/files_external/js/dropbox.js b/apps/files_external/js/dropbox.js
index cd3c957e0a8470a0631ee423b7fbac2904f58f61..957daeb4d1f9152af29b06c85273b39f4cc760da 100644
--- a/apps/files_external/js/dropbox.js
+++ b/apps/files_external/js/dropbox.js
@@ -15,6 +15,9 @@ $(document).ready(function() {
 				if (pos != -1 && window.location.search.substr(pos, $(token).val().length) == $(token).val()) {
 					var token_secret = $(this).find('.configuration [data-parameter="token_secret"]');
 					var tr = $(this);
+					var statusSpan = $(tr).find('.status span');
+					statusSpan.removeClass();
+					statusSpan.addClass('waiting');
 					$.post(OC.filePath('files_external', 'ajax', 'dropbox.php'), { step: 2, app_key: app_key, app_secret: app_secret, request_token: $(token).val(), request_token_secret: $(token_secret).val() }, function(result) {
 						if (result && result.status == 'success') {
 							$(token).val(result.access_token);
@@ -24,23 +27,40 @@ $(document).ready(function() {
 							$(tr).find('.configuration input').attr('disabled', 'disabled');
 							$(tr).find('.configuration').append('<span id="access" style="padding-left:0.5em;">'+t('files_external', 'Access granted')+'</span>');
 						} else {
-							OC.dialogs.alert(result.data.message,
-                                t('files_external', 'Error configuring Dropbox storage')
-                            );
+							OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Dropbox storage'));
 						}
 					});
 				}
-			} else if ($(this).find('.mountPoint input').val() != '' && $(config).find('[data-parameter="app_key"]').val() != '' && $(config).find('[data-parameter="app_secret"]').val() != '' && $(this).find('.dropbox').length == 0) {
-				$(this).find('.configuration').append('<a class="button dropbox">'+t('files_external', 'Grant access')+'</a>');
+			} else {
+				onDropboxInputsChange($(this));
 			}
 		}
 	});
 
-	$('#externalStorage tbody').on('keyup', 'tr input', function() {
-		var tr = $(this).parent().parent();
-		if ($(tr).hasClass('\\\\OC\\\\Files\\\\Storage\\\\Dropbox') && $(tr).find('[data-parameter="configured"]').val() != 'true') {
+	$('#externalStorage').on('paste', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Dropbox td', function() {
+		var tr = $(this).parent();
+		setTimeout(function() {
+			onDropboxInputsChange(tr);
+		}, 20);
+	});
+
+	$('#externalStorage').on('keyup', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Dropbox td', function() {
+		onDropboxInputsChange($(this).parent());
+	});
+
+	$('#externalStorage').on('change', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Dropbox .chzn-select', function() {
+		onDropboxInputsChange($(this).parent().parent());
+	});
+
+	function onDropboxInputsChange(tr) {
+		if ($(tr).find('[data-parameter="configured"]').val() != 'true') {
 			var config = $(tr).find('.configuration');
-			if ($(tr).find('.mountPoint input').val() != '' && $(config).find('[data-parameter="app_key"]').val() != '' && $(config).find('[data-parameter="app_secret"]').val() != '') {
+			if ($(tr).find('.mountPoint input').val() != ''
+				&& $(config).find('[data-parameter="app_key"]').val() != ''
+				&& $(config).find('[data-parameter="app_secret"]').val() != ''
+				&& ($(tr).find('.chzn-select').length == 0
+				|| $(tr).find('.chzn-select').val() != null))
+			{
 				if ($(tr).find('.dropbox').length == 0) {
 					$(config).append('<a class="button dropbox">'+t('files_external', 'Grant access')+'</a>');
 				} else {
@@ -50,41 +70,37 @@ $(document).ready(function() {
 				$(tr).find('.dropbox').hide();
 			}
 		}
-	});
+	}
 
-	$('.dropbox').on('click', function(event) {
+	$('#externalStorage').on('click', '.dropbox', function(event) {
 		event.preventDefault();
+		var tr = $(this).parent().parent();
 		var app_key = $(this).parent().find('[data-parameter="app_key"]').val();
 		var app_secret = $(this).parent().find('[data-parameter="app_secret"]').val();
+		var statusSpan = $(tr).find('.status span');
 		if (app_key != '' && app_secret != '') {
 			var tr = $(this).parent().parent();
 			var configured = $(this).parent().find('[data-parameter="configured"]');
 			var token = $(this).parent().find('[data-parameter="token"]');
 			var token_secret = $(this).parent().find('[data-parameter="token_secret"]');
-			$.post(OC.filePath('files_external', 'ajax', 'dropbox.php'), { step: 1, app_key: app_key, app_secret: app_secret, callback: window.location.href }, function(result) {
+			$.post(OC.filePath('files_external', 'ajax', 'dropbox.php'), { step: 1, app_key: app_key, app_secret: app_secret, callback: location.protocol + '//' + location.host + location.pathname }, function(result) {
 				if (result && result.status == 'success') {
 					$(configured).val('false');
 					$(token).val(result.data.request_token);
 					$(token_secret).val(result.data.request_token_secret);
-					if (OC.MountConfig.saveStorage(tr)) {
-						window.location = result.data.url;
-					} else {
-						OC.dialogs.alert(
-                            t('files_external', 'Fill out all required fields'),
-                            t('files_external', 'Error configuring Dropbox storage')
-                        );
-					}
+					OC.MountConfig.saveStorage(tr);
+					statusSpan.removeClass();
+					statusSpan.addClass('waiting');
+					window.location = result.data.url;
 				} else {
-					OC.dialogs.alert(result.data.message,
-                        t('files_external', 'Error configuring Dropbox storage')
-                    );
+					OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Dropbox storage'));
 				}
 			});
 		} else {
 			OC.dialogs.alert(
-                t('files_external', 'Please provide a valid Dropbox app key and secret.'),
-                t('files_external', 'Error configuring Dropbox storage')
-            );
+				t('files_external', 'Please provide a valid Dropbox app key and secret.'),
+				t('files_external', 'Error configuring Dropbox storage')
+			);
 		}
 	});
 
diff --git a/apps/files_external/js/google.js b/apps/files_external/js/google.js
index 9b7f9514f12d38b3c9d885bcf4ec269b6503efd7..7be1b338e904fb1cba80cea821d28882a465d18b 100644
--- a/apps/files_external/js/google.js
+++ b/apps/files_external/js/google.js
@@ -1,19 +1,30 @@
 $(document).ready(function() {
 
-	$('#externalStorage tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google').each(function() {
-		var configured = $(this).find('[data-parameter="configured"]');
+	$('#externalStorage tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google').each(function(index, tr) {
+		setupGoogleRow(tr);
+	});
+
+	$('#externalStorage').on('change', '#selectBackend', function() {
+		if ($(this).val() == '\\OC\\Files\\Storage\\Google') {
+			setupGoogleRow($('#externalStorage tbody>tr:last').prev('tr'));
+		}
+	});
+
+	function setupGoogleRow(tr) {
+		var configured = $(tr).find('[data-parameter="configured"]');
 		if ($(configured).val() == 'true') {
-			$(this).find('.configuration')
-                .append('<span id="access" style="padding-left:0.5em;">'+t('files_external', 'Access granted')+'</span>');
+			$(tr).find('.configuration').append('<span id="access" style="padding-left:0.5em;">'+t('files_external', 'Access granted')+'</span>');
 		} else {
-			var token = $(this).find('[data-parameter="token"]');
-			var token_secret = $(this).find('[data-parameter="token_secret"]');
+			var token = $(tr).find('[data-parameter="token"]');
+			var token_secret = $(tr).find('[data-parameter="token_secret"]');
 			var params = {};
 			window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m, key, value) {
 				params[key] = value;
 			});
 			if (params['oauth_token'] !== undefined && params['oauth_verifier'] !== undefined && decodeURIComponent(params['oauth_token']) == $(token).val()) {
-				var tr = $(this);
+				var statusSpan = $(tr).find('.status span');
+				statusSpan.removeClass();
+				statusSpan.addClass('waiting');
 				$.post(OC.filePath('files_external', 'ajax', 'google.php'), { step: 2, oauth_verifier: params['oauth_verifier'], request_token: $(token).val(), request_token_secret: $(token_secret).val() }, function(result) {
 					if (result && result.status == 'success') {
 						$(token).val(result.access_token);
@@ -22,61 +33,64 @@ $(document).ready(function() {
 						OC.MountConfig.saveStorage(tr);
 						$(tr).find('.configuration').append('<span id="access" style="padding-left:0.5em;">'+t('files_external', 'Access granted')+'</span>');
 					} else {
-						OC.dialogs.alert(result.data.message,
-                            t('files_external', 'Error configuring Google Drive storage')
-                        );
+						OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Google Drive storage'));
+						onGoogleInputsChange(tr);
 					}
 				});
-			} else if ($(this).find('.google').length == 0) {
-				$(this).find('.configuration').append('<a class="button google">'+t('files_external', 'Grant access')+'</a>');
+			} else {
+				onGoogleInputsChange(tr);
 			}
 		}
+	}
+
+	$('#externalStorage').on('paste', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google td', function() {
+		var tr = $(this).parent();
+		setTimeout(function() {
+			onGoogleInputsChange(tr);
+		}, 20);
 	});
 
-	$('#externalStorage tbody').on('change', 'tr', function() {
-		if ($(this).hasClass('\\\\OC\\\\Files\\\\Storage\\\\Google') && $(this).find('[data-parameter="configured"]').val() != 'true') {
-			if ($(this).find('.mountPoint input').val() != '') {
-				if ($(this).find('.google').length == 0) {
-					$(this).find('.configuration').append('<a class="button google">'+t('files_external', 'Grant access')+'</a>');
-				}
-			}
-		}
+	$('#externalStorage').on('keyup', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google td', function() {
+		onGoogleInputsChange($(this).parent());
 	});
 
-	$('#externalStorage tbody').on('keyup', 'tr .mountPoint input', function() {
-		var tr = $(this).parent().parent();
-		if ($(tr).hasClass('\\\\OC\\\\Files\\\\Storage\\\\Google') && $(tr).find('[data-parameter="configured"]').val() != 'true' && $(tr).find('.google').length > 0) {
-			if ($(this).val() != '') {
-				$(tr).find('.google').show();
-			} else {
+	$('#externalStorage').on('change', 'tbody tr.\\\\OC\\\\Files\\\\Storage\\\\Google .chzn-select', function() {
+		onGoogleInputsChange($(this).parent().parent());
+	});
+
+	function onGoogleInputsChange(tr) {
+		if ($(tr).find('[data-parameter="configured"]').val() != 'true') {
+			var config = $(tr).find('.configuration');
+			if ($(tr).find('.mountPoint input').val() != '' && ($(tr).find('.chzn-select').length == 0 || $(tr).find('.chzn-select').val() != null)) {
+				if ($(tr).find('.google').length == 0) {
+					$(config).append('<a class="button google">'+t('files_external', 'Grant access')+'</a>');
+				} else {
+					$(tr).find('.google').show();
+				}
+			} else if ($(tr).find('.google').length > 0) {
 				$(tr).find('.google').hide();
 			}
 		}
-	});
+	}
 
-	$('.google').on('click', function(event) {
+	$('#externalStorage').on('click', '.google', function(event) {
 		event.preventDefault();
 		var tr = $(this).parent().parent();
 		var configured = $(this).parent().find('[data-parameter="configured"]');
 		var token = $(this).parent().find('[data-parameter="token"]');
 		var token_secret = $(this).parent().find('[data-parameter="token_secret"]');
-		$.post(OC.filePath('files_external', 'ajax', 'google.php'), { step: 1, callback: window.location.href }, function(result) {
+		var statusSpan = $(tr).find('.status span');
+		$.post(OC.filePath('files_external', 'ajax', 'google.php'), { step: 1, callback: location.protocol + '//' + location.host + location.pathname }, function(result) {
 			if (result && result.status == 'success') {
 				$(configured).val('false');
 				$(token).val(result.data.request_token);
 				$(token_secret).val(result.data.request_token_secret);
-				if (OC.MountConfig.saveStorage(tr)) {
-					window.location = result.data.url;
-				} else {
-					OC.dialogs.alert(
-                        t('files_external', 'Fill out all required fields'),
-                        t('files_external', 'Error configuring Google Drive storage')
-                    );
-				}
+				OC.MountConfig.saveStorage(tr);
+				statusSpan.removeClass();
+				statusSpan.addClass('waiting');
+				window.location = result.data.url;
 			} else {
-				OC.dialogs.alert(result.data.message,
-                    t('files_external', 'Error configuring Google Drive storage')
-                );
+				OC.dialogs.alert(result.data.message, t('files_external', 'Error configuring Google Drive storage'));
 			}
 		});
 	});
diff --git a/apps/files_external/js/settings.js b/apps/files_external/js/settings.js
index 126903952704c9ae0e83908c98dca0f5e83fe126..ac408786ff6271a4088530927f2141075e495e63 100644
--- a/apps/files_external/js/settings.js
+++ b/apps/files_external/js/settings.js
@@ -4,6 +4,7 @@ OC.MountConfig={
 		if (mountPoint == '') {
 			return false;
 		}
+		var statusSpan = $(tr).find('.status span');
 		var backendClass = $(tr).find('.backend').data('class');
 		var configuration = $(tr).find('.configuration input');
 		var addMountPoint = true;
@@ -26,12 +27,20 @@ OC.MountConfig={
 				classOptions[$(input).data('parameter')] = $(input).val();
 			}
 		});
+		if ($('#externalStorage').data('admin') === true) {
+			var multiselect = $(tr).find('.chzn-select').val();
+			if (multiselect == null) {
+				return false;
+			}
+		}
 		if (addMountPoint) {
+			var status = false;
 			if ($('#externalStorage').data('admin') === true) {
 				var isPersonal = false;
-				var multiselect = $(tr).find('.chzn-select').val();
 				var oldGroups = $(tr).find('.applicable').data('applicable-groups');
 				var oldUsers = $(tr).find('.applicable').data('applicable-users');
+				var groups = [];
+				var users = [];
 				$.each(multiselect, function(index, value) {
 					var pos = value.indexOf('(group)');
 					if (pos != -1) {
@@ -40,30 +49,96 @@ OC.MountConfig={
 						if ($.inArray(applicable, oldGroups) != -1) {
 							oldGroups.splice($.inArray(applicable, oldGroups), 1);
 						}
+						groups.push(applicable);
 					} else {
 						var mountType = 'user';
 						var applicable = value;
 						if ($.inArray(applicable, oldUsers) != -1) {
 							oldUsers.splice($.inArray(applicable, oldUsers), 1);
 						}
+						users.push(applicable);
 					}
-					$.post(OC.filePath('files_external', 'ajax', 'addMountPoint.php'), { mountPoint: mountPoint, 'class': backendClass, classOptions: classOptions, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
+					$.ajax({type: 'POST',
+						url: OC.filePath('files_external', 'ajax', 'addMountPoint.php'),
+						data: {
+							mountPoint: mountPoint,
+							'class': backendClass,
+							classOptions: classOptions,
+							mountType: mountType,
+							applicable: applicable,
+							isPersonal: isPersonal
+						},
+						async: false,
+						success: function(result) {
+							statusSpan.removeClass();
+							if (result && result.status == 'success' && result.data.message) {
+								status = true;
+								statusSpan.addClass('success');
+							} else {
+								statusSpan.addClass('error');
+							}
+						}
+					});
 				});
+				$(tr).find('.applicable').data('applicable-groups', groups);
+				$(tr).find('.applicable').data('applicable-users', users);
 				var mountType = 'group';
 				$.each(oldGroups, function(index, applicable) {
-					$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
+					$.ajax({type: 'POST',
+						url: OC.filePath('files_external', 'ajax', 'removeMountPoint.php'),
+						data: {
+							mountPoint: mountPoint,
+							class: backendClass,
+							classOptions: classOptions,
+							mountType: mountType,
+							applicable: applicable,
+							isPersonal: isPersonal
+						},
+						async: false
+					});
 				});
 				var mountType = 'user';
 				$.each(oldUsers, function(index, applicable) {
-					$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
+					$.ajax({type: 'POST',
+						url: OC.filePath('files_external', 'ajax', 'removeMountPoint.php'),
+						data: {
+							mountPoint: mountPoint,
+							class: backendClass,
+							classOptions: classOptions,
+							mountType: mountType,
+							applicable: applicable,
+							isPersonal: isPersonal
+						},
+						async: false
+					});
 				});
 			} else {
 				var isPersonal = true;
 				var mountType = 'user';
 				var applicable = OC.currentUser;
-				$.post(OC.filePath('files_external', 'ajax', 'addMountPoint.php'), { mountPoint: mountPoint, 'class': backendClass, classOptions: classOptions, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
+				$.ajax({type: 'POST',
+					url: OC.filePath('files_external', 'ajax', 'addMountPoint.php'),
+					data: {
+						mountPoint: mountPoint,
+						'class': backendClass,
+						classOptions: classOptions,
+						mountType: mountType,
+						applicable: applicable,
+						isPersonal: isPersonal
+					},
+					async: false,
+					success: function(result) {
+						statusSpan.removeClass();
+						if (result && result.status == 'success' && result.data.message) {
+							status = true;
+							statusSpan.addClass('success');
+						} else {
+							statusSpan.addClass('error');
+						}
+					}
+				});
 			}
-			return true;
+			return status;
 		}
 	}
 };
@@ -71,7 +146,7 @@ OC.MountConfig={
 $(document).ready(function() {
 	$('.chzn-select').chosen();
 
-	$('#selectBackend').on('change', function() {
+	$('#externalStorage').on('change', '#selectBackend', function() {
 		var tr = $(this).parent().parent();
 		$('#externalStorage tbody').append($(tr).clone());
 		$('#externalStorage tbody tr').last().find('.mountPoint input').val('');
@@ -79,9 +154,10 @@ $(document).ready(function() {
 		var backendClass = $(this).val();
 		$(this).parent().text(selected);
 		if ($(tr).find('.mountPoint input').val() == '') {
-			$(tr).find('.mountPoint input').val(suggestMountPoint(selected.replace(/\s+/g, '')));
+			$(tr).find('.mountPoint input').val(suggestMountPoint(selected));
 		}
 		$(tr).addClass(backendClass);
+		$(tr).find('.status').append('<span class="waiting"></span>');
 		$(tr).find('.backend').data('class', backendClass);
 		var configurations = $(this).data('configurations');
 		var td = $(tr).find('td.configuration');
@@ -106,7 +182,11 @@ $(document).ready(function() {
 				return false;
 			}
 		});
-		$('.chz-select').chosen();
+		// Reset chosen
+		var chosen = $(tr).find('.applicable select');
+		chosen.parent().find('div').remove();
+		chosen.removeAttr('id').removeClass('chzn-done').css({display:'inline-block'});
+		chosen.chosen();
 		$(tr).find('td').last().attr('class', 'remove');
 		$(tr).find('td').last().removeAttr('style');
 		$(tr).removeAttr('id');
@@ -114,6 +194,11 @@ $(document).ready(function() {
 	});
 
 	function suggestMountPoint(defaultMountPoint) {
+		var pos = defaultMountPoint.indexOf('/');
+		if (pos !== -1) {
+			defaultMountPoint = defaultMountPoint.substring(0, pos);
+		}
+		defaultMountPoint = defaultMountPoint.replace(/\s+/g, '');
 		var i = 1;
 		var append = '';
 		var match = true;
@@ -135,11 +220,34 @@ $(document).ready(function() {
 		return defaultMountPoint+append;
 	}
 
-	$('#externalStorage').on('change', 'td', function() {
-		OC.MountConfig.saveStorage($(this).parent());
+	$('#externalStorage').on('paste', 'td', function() {
+		var tr = $(this).parent();
+		setTimeout(function() {
+			OC.MountConfig.saveStorage(tr);
+		}, 20);
 	});
 
-	$('td.remove>img').on('click', function() {
+	var timer;
+
+	$('#externalStorage').on('keyup', 'td input', function() {
+		clearTimeout(timer);
+		var tr = $(this).parent().parent();
+		if ($(this).val) {
+			timer = setTimeout(function() {
+				OC.MountConfig.saveStorage(tr);
+			}, 2000);
+		}
+	});
+
+	$('#externalStorage').on('change', 'td input:checkbox', function() {
+		OC.MountConfig.saveStorage($(this).parent().parent().parent());
+	});
+
+	$('#externalStorage').on('change', '.applicable .chzn-select', function() {
+		OC.MountConfig.saveStorage($(this).parent().parent());
+	});
+
+	$('#externalStorage').on('click', 'td.remove>img', function() {
 		var tr = $(this).parent().parent();
 		var mountPoint = $(tr).find('.mountPoint input').val();
 		if ( ! mountPoint) {
@@ -151,23 +259,25 @@ $(document).ready(function() {
 		if ($('#externalStorage').data('admin') === true) {
 			var isPersonal = false;
 			var multiselect = $(tr).find('.chzn-select').val();
-			$.each(multiselect, function(index, value) {
-				var pos = value.indexOf('(group)');
-				if (pos != -1) {
-					var mountType = 'group';
-					var applicable = value.substr(0, pos);
-				} else {
-					var mountType = 'user';
-					var applicable = value;
-				}
-				$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
-			});
+			if (multiselect != null) {
+				$.each(multiselect, function(index, value) {
+					var pos = value.indexOf('(group)');
+					if (pos != -1) {
+						var mountType = 'group';
+						var applicable = value.substr(0, pos);
+					} else {
+						var mountType = 'user';
+						var applicable = value;
+					}
+					$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
+				});
+			}
 		} else {
 			var mountType = 'user';
 			var applicable = OC.currentUser;
 			var isPersonal = true;
+			$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
 		}
-		$.post(OC.filePath('files_external', 'ajax', 'removeMountPoint.php'), { mountPoint: mountPoint, mountType: mountType, applicable: applicable, isPersonal: isPersonal });
 		$(tr).remove();
 	});
 
diff --git a/apps/files_external/lib/amazons3.php b/apps/files_external/lib/amazons3.php
index 37e53a3a6701886a3d270bb731c6746262674d90..7bcefd4176c94ac9da2e6a690c34a4a7b09cd98e 100644
--- a/apps/files_external/lib/amazons3.php
+++ b/apps/files_external/lib/amazons3.php
@@ -33,12 +33,16 @@ class AmazonS3 extends \OC\Files\Storage\Common {
 
 	private static $tempFiles = array();
 
-	// TODO options: storage class, encryption server side, encrypt before upload?
+	// TODO Update to new AWS SDK
 
 	public function __construct($params) {
-		$this->id = 'amazon::' . $params['key'] . md5($params['secret']);
-		$this->s3 = new \AmazonS3(array('key' => $params['key'], 'secret' => $params['secret']));
-		$this->bucket = $params['bucket'];
+		if (isset($params['key']) && isset($params['secret']) && isset($params['bucket'])) {
+			$this->id = 'amazon::' . $params['key'] . md5($params['secret']);
+			$this->s3 = new \AmazonS3(array('key' => $params['key'], 'secret' => $params['secret']));
+			$this->bucket = $params['bucket'];
+		} else {
+			throw new \Exception();
+		}
 	}
 
 	private function getObject($path) {
@@ -240,4 +244,12 @@ class AmazonS3 extends \OC\Files\Storage\Common {
 		return $response->isOK();
 	}
 
+	public function test() {
+		$test = $this->s3->get_canonical_user_id();
+		if (isset($test['id']) && $test['id'] != '') {
+			return true;
+		}
+		return false;
+	}
+
 }
diff --git a/apps/files_external/lib/config.php b/apps/files_external/lib/config.php
index 905c5d50cde133b8b5c8585431541b2bf19981c7..430269e03d9061f82bc98fa92ae6823251a33cf8 100755
--- a/apps/files_external/lib/config.php
+++ b/apps/files_external/lib/config.php
@@ -143,7 +143,9 @@ class OC_Mount_Config {
 							'class' => $mount['class'],
 							'backend' => $backends[$mount['class']]['backend'],
 							'configuration' => $mount['options'],
-							'applicable' => array('groups' => array($group), 'users' => array()));
+							'applicable' => array('groups' => array($group), 'users' => array()),
+							'status' => self::getBackendStatus($mount['class'], $mount['options'])
+						);
 					}
 				}
 			}
@@ -162,10 +164,13 @@ class OC_Mount_Config {
 						$system[$mountPoint]['applicable']['users']
 							= array_merge($system[$mountPoint]['applicable']['users'], array($user));
 					} else {
-						$system[$mountPoint] = array('class' => $mount['class'],
+						$system[$mountPoint] = array(
+							'class' => $mount['class'],
 							'backend' => $backends[$mount['class']]['backend'],
 							'configuration' => $mount['options'],
-							'applicable' => array('groups' => array(), 'users' => array($user)));
+							'applicable' => array('groups' => array(), 'users' => array($user)),
+							'status' => self::getBackendStatus($mount['class'], $mount['options'])
+						);
 					}
 				}
 			}
@@ -190,14 +195,32 @@ class OC_Mount_Config {
 					$mount['class'] = '\OC\Files\Storage\\'.substr($mount['class'], 15);
 				}
 				// Remove '/uid/files/' from mount point
-				$personal[substr($mountPoint, strlen($uid) + 8)] = array('class' => $mount['class'],
-																'backend' => $backends[$mount['class']]['backend'],
-																'configuration' => $mount['options']);
+				$personal[substr($mountPoint, strlen($uid) + 8)] = array(
+					'class' => $mount['class'],
+					'backend' => $backends[$mount['class']]['backend'],
+					'configuration' => $mount['options'],
+					'status' => self::getBackendStatus($mount['class'], $mount['options'])
+				);
 			}
 		}
 		return $personal;
 	}
 
+	private static function getBackendStatus($class, $options) {
+		foreach ($options as &$option) {
+			$option = str_replace('$user', OCP\User::getUser(), $option);
+		}
+		if (class_exists($class)) {
+			try {
+				$storage = new $class($options);
+				return $storage->test();
+			} catch (Exception $exception) {
+				return false;
+			}
+		}
+		return false;
+	}
+
 	/**
 	* Add a mount point to the filesystem
 	* @param string Mount point
@@ -238,7 +261,7 @@ class OC_Mount_Config {
 			$mountPoints[$mountType] = $mount;
 		}
 		self::writeData($isPersonal, $mountPoints);
-		return true;
+		return self::getBackendStatus($class, $classOptions);
 	}
 
 	/**
diff --git a/apps/files_external/lib/ftp.php b/apps/files_external/lib/ftp.php
index 9b6c037bb57e6c6a766466a7a61787d5e04dc6ba..8a7375ebe38730a270ba74ea1f275543e100fffd 100644
--- a/apps/files_external/lib/ftp.php
+++ b/apps/files_external/lib/ftp.php
@@ -18,26 +18,31 @@ class FTP extends \OC\Files\Storage\StreamWrapper{
 	private static $tempFiles=array();
 
 	public function __construct($params) {
-		$this->host=$params['host'];
-		$this->user=$params['user'];
-		$this->password=$params['password'];
-		if (isset($params['secure'])) {
-			if (is_string($params['secure'])) {
-				$this->secure = ($params['secure'] === 'true');
+		if (isset($params['host']) && isset($params['user']) && isset($params['password'])) {
+			$this->host=$params['host'];
+			$this->user=$params['user'];
+			$this->password=$params['password'];
+			if (isset($params['secure'])) {
+				if (is_string($params['secure'])) {
+					$this->secure = ($params['secure'] === 'true');
+				} else {
+					$this->secure = (bool)$params['secure'];
+				}
 			} else {
-				$this->secure = (bool)$params['secure'];
+				$this->secure = false;
+			}
+			$this->root=isset($params['root'])?$params['root']:'/';
+			if ( ! $this->root || $this->root[0]!='/') {
+				$this->root='/'.$this->root;
+			}
+			//create the root folder if necessary
+			if ( ! $this->is_dir('')) {
+				$this->mkdir('');
 			}
 		} else {
-			$this->secure = false;
-		}
-		$this->root=isset($params['root'])?$params['root']:'/';
-		if ( ! $this->root || $this->root[0]!='/') {
-			$this->root='/'.$this->root;
-		}
-		//create the root folder if necesary
-		if ( ! $this->is_dir('')) {
-			$this->mkdir('');
+			throw new \Exception();
 		}
+		
 	}
 
 	public function getId(){
@@ -83,7 +88,7 @@ class FTP extends \OC\Files\Storage\StreamWrapper{
 				} else {
 					$ext='';
 				}
-				$tmpFile=OCP\Files::tmpFile($ext);
+				$tmpFile=\OCP\Files::tmpFile($ext);
 				\OC\Files\Stream\Close::registerCallback($tmpFile, array($this, 'writeBack'));
 				if ($this->file_exists($path)) {
 					$this->getFile($path, $tmpFile);
diff --git a/apps/files_external/lib/google.php b/apps/files_external/lib/google.php
index f9bd4075f3eb5db0c125b38d05e970bfd9f1a2bf..ec7de3f35709dec0e879dbfd42d3e14f957a70d4 100644
--- a/apps/files_external/lib/google.php
+++ b/apps/files_external/lib/google.php
@@ -596,4 +596,11 @@ class Google extends \OC\Files\Storage\Common {
 
 	}
 
+	public function test() {
+		if ($this->free_space('')) {
+			return true;
+		}
+		return false;
+	}
+
 }
diff --git a/apps/files_external/lib/smb.php b/apps/files_external/lib/smb.php
index 62f6591d25a5dcf4b7b096f57d21aed59f1c6fd9..961efb1a50a43123a43d299296cbb30d305875c7 100644
--- a/apps/files_external/lib/smb.php
+++ b/apps/files_external/lib/smb.php
@@ -18,22 +18,26 @@ class SMB extends \OC\Files\Storage\StreamWrapper{
 	private $share;
 
 	public function __construct($params) {
-		$this->host=$params['host'];
-		$this->user=$params['user'];
-		$this->password=$params['password'];
-		$this->share=$params['share'];
-		$this->root=isset($params['root'])?$params['root']:'/';
-		if ( ! $this->root || $this->root[0]!='/') {
-			$this->root='/'.$this->root;
-		}
-		if (substr($this->root, -1, 1)!='/') {
-			$this->root.='/';
-		}
-		if ( ! $this->share || $this->share[0]!='/') {
-			$this->share='/'.$this->share;
-		}
-		if(substr($this->share, -1, 1)=='/') {
-			$this->share = substr($this->share, 0, -1);
+		if (isset($params['host']) && isset($params['user']) && isset($params['password']) && isset($params['share'])) {
+			$this->host=$params['host'];
+			$this->user=$params['user'];
+			$this->password=$params['password'];
+			$this->share=$params['share'];
+			$this->root=isset($params['root'])?$params['root']:'/';
+			if ( ! $this->root || $this->root[0]!='/') {
+				$this->root='/'.$this->root;
+			}
+			if (substr($this->root, -1, 1)!='/') {
+				$this->root.='/';
+			}
+			if ( ! $this->share || $this->share[0]!='/') {
+				$this->share='/'.$this->share;
+			}
+			if (substr($this->share, -1, 1)=='/') {
+				$this->share = substr($this->share, 0, -1);
+			}
+		} else {
+			throw new \Exception();
 		}
 	}
 
diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php
index a00316c1f844a4ea8d6b17cc0423c366cce296f0..68c4b48f17c18ae41562bc9a3f44122517bb10ac 100644
--- a/apps/files_external/lib/swift.php
+++ b/apps/files_external/lib/swift.php
@@ -264,27 +264,31 @@ class SWIFT extends \OC\Files\Storage\Common{
 	private function getSubContainerFile($container) {
 		try {
 			return $container->get_object(self::SUBCONTAINER_FILE);
-		} catch(NoSuchObjectException $e) {
+		} catch(\NoSuchObjectException $e) {
 			return $container->create_object(self::SUBCONTAINER_FILE);
 		}
 	}
 
 	public function __construct($params) {
-		$this->token=$params['token'];
-		$this->host=$params['host'];
-		$this->user=$params['user'];
-		$this->root=isset($params['root'])?$params['root']:'/';
-		if (isset($params['secure'])) {
-			if (is_string($params['secure'])) {
-				$this->secure = ($params['secure'] === 'true');
+		if (isset($params['token']) && isset($params['host']) && isset($params['user'])) {
+			$this->token=$params['token'];
+			$this->host=$params['host'];
+			$this->user=$params['user'];
+			$this->root=isset($params['root'])?$params['root']:'/';
+			if (isset($params['secure'])) {
+				if (is_string($params['secure'])) {
+					$this->secure = ($params['secure'] === 'true');
+				} else {
+					$this->secure = (bool)$params['secure'];
+				}
 			} else {
-				$this->secure = (bool)$params['secure'];
+				$this->secure = false;
+			}
+			if ( ! $this->root || $this->root[0]!='/') {
+				$this->root='/'.$this->root;
 			}
 		} else {
-			$this->secure = false;
-		}
-		if ( ! $this->root || $this->root[0]!='/') {
-			$this->root='/'.$this->root;
+			throw new \Exception();
 		}
 
 	}
diff --git a/apps/files_external/lib/webdav.php b/apps/files_external/lib/webdav.php
index ea8fe056e6cf1d89a4d894eeb16bddbf4d7c675c..3ba7c48cd5742adcabbb94bc831364ee4c2f2ae2 100644
--- a/apps/files_external/lib/webdav.php
+++ b/apps/files_external/lib/webdav.php
@@ -23,28 +23,32 @@ class DAV extends \OC\Files\Storage\Common{
 	private static $tempFiles=array();
 
 	public function __construct($params) {
-		$host = $params['host'];
-		//remove leading http[s], will be generated in createBaseUri()
-		if (substr($host, 0, 8) == "https://") $host = substr($host, 8);
-		else if (substr($host, 0, 7) == "http://") $host = substr($host, 7);
-		$this->host=$host;
-		$this->user=$params['user'];
-		$this->password=$params['password'];
-		if (isset($params['secure'])) {
-			if (is_string($params['secure'])) {
-				$this->secure = ($params['secure'] === 'true');
+		if (isset($params['host']) && isset($params['user']) && isset($params['password'])) {
+			$host = $params['host'];
+			//remove leading http[s], will be generated in createBaseUri()
+			if (substr($host, 0, 8) == "https://") $host = substr($host, 8);
+			else if (substr($host, 0, 7) == "http://") $host = substr($host, 7);
+			$this->host=$host;
+			$this->user=$params['user'];
+			$this->password=$params['password'];
+			if (isset($params['secure'])) {
+				if (is_string($params['secure'])) {
+					$this->secure = ($params['secure'] === 'true');
+				} else {
+					$this->secure = (bool)$params['secure'];
+				}
 			} else {
-				$this->secure = (bool)$params['secure'];
+				$this->secure = false;
+			}
+			$this->root=isset($params['root'])?$params['root']:'/';
+			if ( ! $this->root || $this->root[0]!='/') {
+				$this->root='/'.$this->root;
+			}
+			if (substr($this->root, -1, 1)!='/') {
+				$this->root.='/';
 			}
 		} else {
-			$this->secure = false;
-		}
-		$this->root=isset($params['root'])?$params['root']:'/';
-		if ( ! $this->root || $this->root[0]!='/') {
-			$this->root='/'.$this->root;
-		}
-		if (substr($this->root, -1, 1)!='/') {
-			$this->root.='/';
+			throw new \Exception();
 		}
 	}
 
@@ -54,11 +58,11 @@ class DAV extends \OC\Files\Storage\Common{
 		}
 		$this->ready = true;
 
-		$settings = array(
-			'baseUri' => $this->createBaseUri(),
-			'userName' => $this->user,
-			'password' => $this->password,
-		);
+			$settings = array(
+				'baseUri' => $this->createBaseUri(),
+				'userName' => $this->user,
+				'password' => $this->password,
+			);
 
 		$this->client = new \Sabre_DAV_Client($settings);
 
@@ -69,7 +73,7 @@ class DAV extends \OC\Files\Storage\Common{
 				$this->client->addTrustedCertificates($certPath);
 			}
 		}
-		//create the root folder if necesary
+		//create the root folder if necessary
 		$this->mkdir('');
 	}
 
diff --git a/apps/files_external/templates/settings.php b/apps/files_external/templates/settings.php
index 3709fd2e51d5034f0110d79631d22834fa07d68b..76d691eedb2165248796b1de780786a96bcd6dcf 100644
--- a/apps/files_external/templates/settings.php
+++ b/apps/files_external/templates/settings.php
@@ -5,8 +5,9 @@
 		<table id="externalStorage" data-admin='<?php echo json_encode($_['isAdminPage']); ?>'>
 			<thead>
 				<tr>
-					<th><?php echo $l->t('Mount point'); ?></th>
-					<th><?php echo $l->t('Backend'); ?></th>
+					<th></th>
+					<th><?php echo $l->t('Folder name'); ?></th>
+					<th><?php echo $l->t('External storage'); ?></th>
 					<th><?php echo $l->t('Configuration'); ?></th>
 					<!--<th><?php echo $l->t('Options'); ?></th> -->
 					<?php if ($_['isAdminPage']) echo '<th>'.$l->t('Applicable').'</th>'; ?>
@@ -17,14 +18,19 @@
 			<?php $_['mounts'] = array_merge($_['mounts'], array('' => array())); ?>
 			<?php foreach ($_['mounts'] as $mountPoint => $mount): ?>
 				<tr <?php echo ($mountPoint != '') ? 'class="'.$mount['class'].'"' : 'id="addMountPoint"'; ?>>
+					<td class="status">
+					<?php if (isset($mount['status'])): ?>
+						<span class="<?php echo ($mount['status']) ? 'success' : 'error'; ?>"></span>
+					<?php endif; ?>
+					</td>
 					<td class="mountPoint"><input type="text" name="mountPoint"
 												  value="<?php p($mountPoint); ?>"
-												  placeholder="<?php echo $l->t('Mount point'); ?>" /></td>
+												  placeholder="<?php echo $l->t('Folder name'); ?>" /></td>
 					<?php if ($mountPoint == ''): ?>
 						<td class="backend">
 							<select id="selectBackend" data-configurations='<?php echo json_encode($_['backends']); ?>'>
 								<option value="" disabled selected
-										style="display:none;"><?php echo $l->t('Add mount point'); ?></option>
+										style="display:none;"><?php echo $l->t('Add storage'); ?></option>
 								<?php foreach ($_['backends'] as $class => $backend): ?>
 									<option value="<?php echo $class; ?>"><?php echo $backend['backend']; ?></option>
 								<?php endforeach; ?>
@@ -67,9 +73,8 @@
 									<?php endif; ?>
 								<?php endif; ?>
 							<?php endforeach; ?>
-							<?php if (isset($_['backends'][$mount['class']]['custom'])): ?>
-								<?php OCP\Util::addScript('files_external',
-														  $_['backends'][$mount['class']]['custom']); ?>
+							<?php if (isset($_['backends'][$mount['class']]['custom']) && !in_array('files_external/js/'.$_['backends'][$mount['class']]['custom'], \OC_Util::$scripts)): ?>
+								<?php OCP\Util::addScript('files_external', $_['backends'][$mount['class']]['custom']); ?>
 							<?php endif; ?>
 						<?php endif; ?>
 					</td>
diff --git a/lib/files/storage/common.php b/lib/files/storage/common.php
index cb41d17e446a12f523fd4bf40c04667d2f1e470f..8aa227ec0b72deb06bdd553b04d46e1a0c6fc565 100644
--- a/lib/files/storage/common.php
+++ b/lib/files/storage/common.php
@@ -334,6 +334,13 @@ abstract class Common implements \OC\Files\Storage\Storage {
 		return implode('/', $output);
 	}
 
+	public function test() {
+		if ($this->stat('')) {
+			return true;
+		}
+		return false;
+	}
+
 	/**
 	 * get the free space in the storage
 	 *