diff --git a/templates/map/client/libs/netgis/LayerTree.js b/templates/map/client/libs/netgis/LayerTree.js
index 948db2b4..9f52a2f0 100644
--- a/templates/map/client/libs/netgis/LayerTree.js
+++ b/templates/map/client/libs/netgis/LayerTree.js
@@ -18,7 +18,6 @@ netgis.LayerTree.prototype.load = function()
 {
 	this.root = document.createElement( "section" );
 	this.root.className = "netgis-layer-list netgis-dialog netgis-shadow netgis-hide";
-	//this.root.className = "netgis-layer-list netgis-dialog netgis-shadow";
 	
 	this.list = document.createElement( "ul" );
 	this.list.className = "root";
@@ -32,12 +31,9 @@ netgis.LayerTree.prototype.load = function()
 	this.root.appendChild( this.tools );
 	
 	this.buttonAddService = document.createElement( "button" );
-	this.buttonAddService.setAttribute( "type", "button" );
-	//this.buttonAddService.className = "netgis-primary netgis-hover-primary netgis-shadow";
 	this.buttonAddService.className = "netgis-text-primary netgis-hover-primary";
-	//this.buttonAddService.innerHTML = "<i class='fas fa-plus' style='color: #000'></i> Dienst hinzufügen";
 	this.buttonAddService.innerHTML = "<i class='fas fa-folder-plus'></i> Dienst hinzufügen";
-	//this.buttonAddService.innerHTML = "<i class='fas fa-cloud-upload-alt'></i> Dienst hinzufügen";
+	this.buttonAddService.setAttribute( "type", "button" );
 	this.buttonAddService.addEventListener( "click", this.onAddServiceClick.bind( this ) );
 	this.tools.appendChild( this.buttonAddService );
 	
diff --git a/templates/map/client/libs/netgis/MapOpenLayers.js b/templates/map/client/libs/netgis/MapOpenLayers.js
index 7a8c6bba..4731f1ae 100644
--- a/templates/map/client/libs/netgis/MapOpenLayers.js
+++ b/templates/map/client/libs/netgis/MapOpenLayers.js
@@ -302,7 +302,7 @@ netgis.MapOpenLayers.prototype.createLayer = function( data )
 		
 		case netgis.LayerTypes.WFS:
 		{
-			layer = this.createLayerWFS( data.url, data.name, this.client.config.map.projection, data.outputFormat );
+			layer = this.createLayerWFS( data.url, data.name, this.client.config.map.projection, data.outputFormat, data.username, data.password );
 			break;
 		}
 	}
@@ -371,7 +371,7 @@ netgis.MapOpenLayers.prototype.createLayerWMS = function( url, layerName, format
 		//ratio: 3.0
 	};
 
-	// Authorization
+	// User Auth
 	if ( user && password )
 	{
 		params.imageLoadFunction = function( image, src )
@@ -403,7 +403,7 @@ netgis.MapOpenLayers.prototype.createLayerWMS = function( url, layerName, format
 	return layer;
 };
 
-netgis.MapOpenLayers.prototype.createLayerWFS = function( url, typeName, projection, outputFormat )
+netgis.MapOpenLayers.prototype.createLayerWFS = function( url, typeName, projection, outputFormat, user, password )
 {
 	url = url
 			+ "service=WFS"
@@ -420,16 +420,48 @@ netgis.MapOpenLayers.prototype.createLayerWFS = function( url, typeName, project
 		{
 			format: new ol.format.GeoJSON(),
 			strategy: ol.loadingstrategy.bbox,
-			url: function( extent )
-			{
-				return url
-						+ "&typename=" + typeName
-						+ "&srsname=" + projection
-						+ "&bbox=" + extent.join( "," ) + "," + projection
-						+ "&outputFormat=" + outputFormat;
-			}
 			
-			//TODO: custom loader function to catch xhr response parse errors
+			loader: function( extent, resolution, proj, success, failure )
+			{
+				//proj = proj.getCode();
+				
+				var requestURL = url
+									+ "&typename=" + typeName
+									+ "&srsname=" + projection
+									+ "&bbox=" + extent.join( "," ) + "," + projection
+									+ "&outputFormat=" + outputFormat;
+				
+				var request = new XMLHttpRequest();
+				request.open( "GET", requestURL );
+				
+				if ( user && password )
+				{
+					request.setRequestHeader( "Authorization", "Basic " + window.btoa( user + ":" + password ) );
+				}
+				
+				request.onerror = function()
+				{
+					console.error( "WFS Request Error" );
+					failure();
+				};
+				
+				request.onload = function()
+				{
+					if ( request.status === 200 )
+					{
+						var features = source.getFormat().readFeatures( request.responseText );
+						source.addFeatures( features );
+						success( features );
+					}
+					else
+					{
+						console.error( "WFS Request Status", request.status );
+						failure();
+					}
+				};
+				
+				request.send();
+			}
 		}
 	);
 
diff --git a/templates/map/client/libs/netgis/Modal.js b/templates/map/client/libs/netgis/Modal.js
index d38f4eff..7a411f85 100644
--- a/templates/map/client/libs/netgis/Modal.js
+++ b/templates/map/client/libs/netgis/Modal.js
@@ -207,6 +207,7 @@ netgis.Modal.prototype.createAddService = function()
 	
 	this.createSpace( container );
 	this.createInputHidden( container );
+	this.createInputHidden( container );
 	this.createText( container, "Bezeichnung:", "" );
 	this.createInputSelect( container, "Kartenebene:", [] );
 	this.createInputSelect( container, "Format:", [] );
@@ -793,13 +794,33 @@ netgis.Modal.prototype.onAddServiceLoad = function( e )
 	
 	// Get Base URL
 	var qmark = url.indexOf( "?" );
-	if ( qmark > -1 ) url = url.substr( 0, qmark );
+	var baseURL = ( qmark > -1 ) ? url.substr( 0, qmark ) : url;
+	var inputBaseURL = inputs[ 2 ];
+	inputBaseURL.value = baseURL;
 	
-	var getCaps = url + "?request=GetCapabilities";
+	// Get Params
+	var params = [ "request=GetCapabilities" ];
+	
+	if ( qmark > -1 )
+	{
+		// Existing Params
+		var parts = url.substr( qmark + 1 );
+		parts = parts.split( "&" );
+		
+		for ( var p = 0; p < parts.length; p++ )
+		{
+			var part = parts[ p ];
+			part = part.toLowerCase();
+			
+			if ( part.search( "service" ) > -1 ) { params.push( part ); continue; }
+			if ( part.search( "version" ) > -1 ) { params.push( part ); continue; }
+		}
+	}
+	
+	// Capabilities URL
+	var getCaps = baseURL + "?" + params.join( "&" );
 	
 	netgis.util.request( getCaps, this.onAddServiceCapsResponse.bind( this ) );
-	
-	console.info( "Add Service Load:", url );
 };
 
 netgis.Modal.prototype.onAddServiceCapsResponse = function( e )
@@ -809,7 +830,7 @@ netgis.Modal.prototype.onAddServiceCapsResponse = function( e )
 	var caps = xml.documentElement;
 	
 	var rows = this.addService.getElementsByTagName( "tr" );
-	var rowTitle = rows[ 5 ];
+	var rowTitle = rows[ 6 ];
 	
 	var inputs = this.addService.getElementsByTagName( "input" );
 	var inputType = inputs[ 1 ];
@@ -825,6 +846,7 @@ netgis.Modal.prototype.onAddServiceCapsResponse = function( e )
 	{
 		// WMS
 		case "WMS_Capabilities":
+		case "WMT_MS_Capabilities":
 		{
 			inputType.value = "wms";
 			
@@ -955,18 +977,12 @@ netgis.Modal.prototype.onAddServiceCapsResponse = function( e )
 
 netgis.Modal.prototype.onAddServiceAccept = function( e )
 {
-	/*var inputs = this.exportPDF.getElementsByTagName( "input" );
-	var resx = Number.parseInt( inputs[ 0 ].value );
-	var resy = Number.parseInt( inputs[ 1 ].value );
-	var margin = Number.parseInt( inputs[ 2 ].value );
-	var mode = inputs[ 3 ].checked;
-	this.client.invoke( netgis.Events.EXPORT_PDF, { resx: resx, resy: resy, mode: mode, margin: margin } );*/
-	
 	var inputs = this.addService.getElementsByTagName( "input" );
 	var selects = this.addService.getElementsByTagName( "select" );
 	
 	var url = inputs[ 0 ].value;
 	var type = inputs[ 1 ].value;
+	var baseURL = inputs[ 2 ].value;
 	
 	var selectLayer = selects[ 0 ];
 	var selectFormat = selects[ 1 ];
@@ -979,7 +995,7 @@ netgis.Modal.prototype.onAddServiceAccept = function( e )
 	var params =
 	{
 		id: id,
-		url: url,
+		url: baseURL,
 		title: layerOption.text,
 		name: layerOption.value,
 		format: formatOption.value