function ServiceManager(EventManager, ServiceMap) {
	var ServiceFormParent = null;
	var ServiceChildren = new Array();
	
	var knownServices = new Array();

	this.addService = function(servXMLobj) {
		var title = servXMLobj.getAttribute('title');
		knownServices[title] = servXMLobj;
	}

	this.removeService = function(servTitle) {
		if(knownServices[servTitle]) {
			delete knownServices[servTitle];
		}
	}

	/* set the spawn parent function to do something other than this default 
	 * for specific interfaces
	 */
	this.spawnParent = function(title) {
		return document.getElementById(ServiceFormParent);
	}

	/* set if a parent from a custom spawn function needs to be removed
	*/
	this.clearParent = function(title) {
		return false;
	}

	var MySelf = this;

	function renderServiceForm(serviceXMLObj) {
		var servTitle = serviceXMLObj.getAttribute('title');
		var serviceForm = new ServiceForm(EventManager, serviceXMLObj, ServiceMap);
		var formParent = MySelf.spawnParent(servTitle);
		if(formParent) {
			ServiceChildren[servTitle] = serviceForm;
			serviceForm.setParent(formParent.getAttribute('id'));
		} else {
			alert('Service Form Parent not set! Unable to render service object!');
		}
		serviceXMLObj = null;
	}

	this.serviceForm = function(serviceXMLObj) {
		var servTitle = serviceXMLObj.getAttribute('title');
		if(serviceXMLObj.getAttribute('type') && serviceXMLObj.getAttribute('type').match(/inspect/i)) {
			var mapBook = serviceXMLObj;
			while(mapBook.parentNode) {
				mapBook = mapBook.parentNode;
			}

			var specificType = serviceXMLObj.getAttribute('type').split('-');
			if(!specificType[1]) {
				specificType[1] = 'default';
			}
			if(ServiceFormParent) {
				document.getElementById(ServiceFormParent).innerHTML = '<b>'+'Please Choose a Point on the Map'+'</b>';
			}
			EventManager.addEventListener('changetool','ServInspect', function () {
				EventManager.removeEventListener('changetool','ServInspect');
				EventManager.removeEventListener('finishdrawing', 'ServInspect');

			});
			EventManager.addEventListener('finishdrawing','ServInspect', function (p) {
					var serviceXML = mapBook.createElement('service');
					//serviceXML.setAttribute('title', serviceXMLObj.getAttribute('title'));


					var url = mapBook.createElement('url');
					url.appendChild(mapBook.createTextNode(serviceXMLObj.getElementsByTagName('url')[0].firstChild.nodeValue));
					serviceXML.appendChild(url);

					var inputs = serviceXMLObj.getElementsByTagName('input');
					var copyAttributes = ['name','title','value','delim','display','return','selectable','shape'];

					for(var i = 0; i < copyAttributes.length; i++) {
						var v = serviceXMLObj.getAttribute(copyAttributes[i]);
						if(v) {
							serviceXML.setAttribute(copyAttributes[i], v);
						}
					}

					var latLong = new Point();
					if(window.toLatLong) {
						var sysArr = (new String(MAP_COORDINATE_SYSTEM)).split('-');
						var unitConversion = new Point(p[0].x, p[0].y);
						var llPoint = window.toLatLong(sysArr[1], unitConversion);
						latLong = llPoint;
					}



					for(var i = 0; i < inputs.length; i++) {
						var newInput = mapBook.createElement('input');
						var inputType = new String(inputs[i].getAttribute('type')).toLowerCase();
						for(var attr = 0; attr < copyAttributes.length; attr++) {
							newInput.setAttribute(copyAttributes[attr], new String(inputs[i].getAttribute(copyAttributes[attr])));
						}
						if(inputType == 'point') {
							var delim = inputs[i].getAttribute('delim');
							if(!delim) { delim = ','; }
							var pValue = p[0].toString(delim);
							newInput.setAttribute('type','hidden');
							newInput.setAttribute('value', pValue);
						} else if(inputType.match(/point.x/)) {
							newInput.setAttribute('type','hidden');
							newInput.setAttribute('value', p[0].x);
						} else if(inputType.match(/point.y/)) {
							newInput.setAttribute('type','hidden');
							newInput.setAttribute('value', p[0].y);
						} else if(inputType.match(/point.lat/)) {
							newInput.setAttribute('type','hidden');
							newInput.setAttribute('value', latLong.y);
						} else if(inputType.match(/point.long/)) {
							newInput.setAttribute('type','hidden');
							newInput.setAttribute('value', latLong.x);
						} else if(inputType.match(/multipoint/)) {
							var delim = inputs[i].getAttribute('delim');
							var pairDelim = inputs[i].getAttribute('pointdelim');
							if(!delim) { delim = ','; }
							if(!pairDelim) { pairDelim = ' '; }
							var value = '';
							var shape = serviceXMLObj.getAttribute('shape');
							if(shape && (shape.match(/poly/i)  || shape.match(/measurearea/i))) {
								p[p.length] = p[0];
							}
							for(var pi = 0; pi < p.length; pi++) {
								var pValue = p[pi].toString(delim);
								value = value+pairDelim+pValue;
							}
							value = value.substring(1);
							newInput.setAttribute('type','hidden');
							newInput.setAttribute('value', value);
						} else if(inputType.match(/multipoint.x/)) {
							var delim = inputs[i].getAttribute('delim');
							if(!delim) { delim = ','; }
							var value = '';
							p[p.length] = p[0];
							for(var pi = 0; pi < p.length; pi++) {
								var pValue = p[pi].x;
								value = value+delim+pValue;
							}
							value = value.substring(1);
							newInput.setAttribute('type','hidden');
							newInput.setAttribute('value', value);
						} else if(inputType.match(/multipoint.y/)) {
							var delim = inputs[i].getAttribute('delim');
							if(!delim) { delim = ','; }
							var value = '';
							p[p.length] = p[0];
							for(var pi = 0; pi < p.length; pi++) {
								var pValue = p[pi].y;
								value = value+delim+pValue;
							}
							value = value.substring(1);
							newInput.setAttribute('type','hidden');
							newInput.setAttribute('value', value);
						} else {
							newInput.setAttribute('type', inputs[i].getAttribute('type'));
						}
						serviceXML.appendChild(newInput);
					}
					//serviceXML.setAttribute('type', 'default');
					serviceXML.setAttribute('type', specificType[1]);
					//EventManager.removeEventListener('changetool','ServInspect');
					//EventManager.removeEventListener('finishdrawing', 'ServInspect');
					renderServiceForm(serviceXML);
					serviceXML = null;
					ServiceMap.clearDrawingArea();
			});
			//ServiceMap.pointDrawTool();
			//ServiceMap.loadDrawTool('measurearea', true);
			var shape = serviceXMLObj.getAttribute('shape');
			if(!shape || shape == 'null') {
				shape = 'poly';
			}
			ServiceMap.loadDrawTool(shape, true);
			if(serviceXMLObj.getAttribute('cursor')) {
				ServiceMap.setMapCursor(serviceXMLObj.getAttribute('cursor'));
			}
			return false;
		}
		renderServiceForm(serviceXMLObj);

	}

	this.clearServiceForm = function(serviceXMLObj) {
		var servTitle = serviceXMLObj.getAttribute('title');
		if(ServiceChildren[servTitle]) {
			ServiceChildren[servTitle].clearForm();
		}
		MySelf.clearParent(serviceXMLObj);
	}

	this.setParent = function(p) {
		ServiceFormParent = p;
	}

	this.serviceCount = function() {
		var i = 0;
		for(var l in knownServices) {
			i++;
		}
		alert(i+' known services.');
	}
}
