function ComponentManager(controlId, id, communicatorObj, requestObj, responseObj, messageElemID, preSendRequestFunction, postRecievedReplyFunction) {
    
    ComponentManager.prototype.sendMapRequest = function(startup) {
        
        this.sendRequest(this.requestObj.mapRequest(this, startup), true);
    }
    
    ComponentManager.prototype.sendPanRequest = function(panDirection) {
    
        this.sendRequest(this.requestObj.panRequest(this, panDirection), true);
    }
    
    ComponentManager.prototype.sendOverviewMapZoomRequst = function(minX, minY, maxX, maxY) {
        
        this.mapObj.resetDrawingTools(true);
        this.mapObj.setExtent(minX, minY, maxX, maxY);
        this.sendRequest(this.requestObj.mapRequest(false));
    }
    
    ComponentManager.prototype.sendOverviewMapPanRequst = function(x, y) {
        
        this.mapObj.resetDrawingTools(true);
        
        var xOffSet = (this.mapObj.minX + (this.mapObj.distanceX / 2)) - x;
        var yOffSet = (this.mapObj.minY + (this.mapObj.distanceY / 2)) - y;
        
        var minX = this.mapObj.minX + xOffSet;
        var maxY = this.mapObj.maxY + yOffSet;
        this.mapObj.moveExtent(minX, maxY);
        this.mapObj.sendMapRequst(false);
    }
    
    ComponentManager.prototype.sendToolRequest = function(toolBarObj, toolObj) {
        
        this.toolObj = toolObj;
        if (toolBarObj && toolObj.getAttribute(toolBarObj.TOOL_ATTR_BUTTON_TYPE).toLowerCase() == toolBarObj.TOOL_BUTTON_MODE) {
            var length = this.toolBarObjList.length;
            var currentToolbar;
            for (var i=0; i<length; i++) {
                currentToolbar = this.toolBarObjList[i];
                if (currentToolbar.id != toolBarObj.id) {
                    currentToolbar.deactivateTool();
                }
            }
        }
        this.sendRequest(this.requestObj.toolRequest(this), true);
    }
    
    ComponentManager.prototype.sendSnapRequest = function() {
        
        this.sendRequest(this.requestObj.snapRequest(this), true);
    }
    
    ComponentManager.prototype.sendTOCRefreshRequest = function(toolObj) {
        
        this.toolObj = toolObj;
        this.sendRequest(this.requestObj.TOCRefreshRequest(this), false);
    }
    
    ComponentManager.prototype.sendTOCActiveLayerRequest = function(toolObj) {
        
        this.toolObj = toolObj;
        this.sendRequest(this.requestObj.TOCActiveLayerRequest(this), false);
    }
    
    ComponentManager.prototype.sendTOCZoomActiveLayerRequest = function(toolObj) {
        
        this.sendToolRequest(null, toolObj);
    }
    
    ComponentManager.prototype.sendTOCGetMetadataRequest = function(toolObj) {
        
        this.sendToolRequest(null, toolObj);
    }
    
    ComponentManager.prototype.sendToolClick = function(toolObj) {
        
        this.sendToolRequest(null, toolObj);
    }
    
    ComponentManager.prototype.sendZoomRequest = function(zoomObj) {
        
        this.sendRequest(this.requestObj.zoomRequest(zoomObj, this), true);
    }
    
    ComponentManager.prototype.sendLegendRequest = function() {
        
        this.sendRequest(this.requestObj.legendRequest(this), false);
    }
    
    ComponentManager.prototype.sendMeasureMode = function(mode) {
        
        this.sendRequest(this.requestObj.measureModeRequest(this, mode), false);
    }
    
    ComponentManager.prototype.disableComponents = function() {
        
        this.mapObj.disable();
        
        var length = this.toolBarObjList.length;
        for (var i=0; i<length; i++) {
            this.toolBarObjList[i].disable();
        }
        
        if (this.TOCObj) {
            this.TOCObj.disable();
        }
        if (this.overviewObj) {
            this.overviewObj.disable();
        }
        if (this.bufferObj) {
            this.bufferObj.disable();
        }
        if (this.snapObj) {
            this.snapObj.disable();
        }
    }
    
    ComponentManager.prototype.enableComponents = function() {
        
        this.mapObj.enable();
        
        var length = this.toolBarObjList.length;
        for (var i=0; i<length; i++) {
            this.toolBarObjList[i].enable();
        }
        
        if (this.TOCObj) {
            this.TOCObj.enable();
        }
        if (this.overviewObj) {
            this.overviewObj.enable();
        }
        if (this.bufferObj) {
            this.bufferObj.enable();
        }
        if (this.snapObj) {
            this.snapObj.enable();
        }
    }
    
    ComponentManager.prototype.sendRequest = function(request, clearSnap) {
        
        if (this.waitingForReply) {
            return; //Do nothing why waiting for the reply.
        }
        
        if (clearSnap) {
            this.clearSnap();
        }
        
        if (this.preSendRequestFunction && this.preSendRequestFunction.length > 0) {
            eval(this.preSendRequestFunction);
            request = RequestObj.getXMLString();
        }
        
        this.loadSplashVisible(true);
        this.clearServerError();
        this.disableComponents();
        this.waitingForReply = true;
        
        this.communicatorObj.sendRequest(this.controlId, this.id, request);
    }
    
    ComponentManager.prototype.processResponse = function(response) {
        this.waitingForReply = false;
        this.enableComponents();
        try {
            this.mapObj.resetDrawingTools(true); //So does not display when doing history.
            this.mapObj.setDefaultMapType();
            this.responseObj.process(response, this, this.mapObj, this.snapObj);
            this.setScale(this.mapObj.scale, this.mapObj.scaleFactor);
            this.setOverviewLocation(this.mapObj.minX, this.mapObj.minY, this.mapObj.maxX, this.mapObj.maxY);
            
            if (this.snapObj && this.snapObj.useSnap && this.snapObj.snapPointsUpdated) {
                this.mapObj.addRectangleCoords(this.snapObj.snapCoordinates);
                this.snapObj.snapPointsUpdated = false;
            }
            if (this.postRecievedReplyFunction && this.postRecievedReplyFunction.length > 0) {
                eval(this.postRecievedReplyFunction);
            }
            this.loadSplashVisible(false);
        }
        catch(e) {
            this.displayError(e);
        }
    }
    
    ComponentManager.prototype.setOverviewLocation = function(minX, minY, maxX, maxY) {
        
        if (this.overviewObj) {
            this.overviewObj.resetDrawingTools(true);
            this.overviewObj.setLocator(minX, minY, maxX, maxY);
        }
    }
    
    ComponentManager.prototype.setStatus = function(x, y) {

        if (this.statusObj) {
            this.statusObj.setCoordinates(x, y);
        }
    }
    
    ComponentManager.prototype.setScale = function(scale, scaleFactor) {
        
        if (this.TOCObj) {
            this.TOCObj.setScale(scaleFactor);
        }
        
        if (this.statusObj) {
            this.statusObj.setScale(scale);
        }
    }
    
    ComponentManager.prototype.setZoomInfo = function(step, scale) {
        
        var length = this.zoomObjList.length;
        for (var i=0; i<length; i++) {
            this.zoomObjList[i].setInfo(step, scale);
        }
    }
    
    ComponentManager.prototype.setLegend = function(url) {
        
        if (this.legendObj) {
            this.legendObj.setLegend(url);
        }
    }
    
    ComponentManager.prototype.loadSplashVisible = function(visible) {
        
        if (visible) {
            this.loadSplashTimer[this.loadSplashTimer.length] = setTimeout(this.mapObj.id + '.loadSpash.style.display = "";', this.mapObj.loadSplashDelay);
        }
        else {
            var length = this.loadSplashTimer.length
            for (var i=0; i<length; i++) {
                clearTimeout(this.loadSplashTimer[i]);
            }
            this.mapObj.loadSpash.style.display = "none";
        }
    }
    
    ComponentManager.prototype.setDrawMode = function(drawMode) {
        this.mapObj.setDrawMode(drawMode);
    }
    
    ComponentManager.prototype.setDrawPointEvents = function() {
        this.mapObj.setDrawPointEvents();
    }
    
    ComponentManager.prototype.clearSnap = function() {
        this.mapObj.clearRectangleCoords();
        if (this.snapObj) {
            this.snapObj.snapCoordinates = null;
        }
    }
    
    ComponentManager.prototype.getSnapDistance = function(latitude) {
    
        if (this.snapObj) {
            return this.snapObj.getSnapDistance(latitude);
        }
    }
    
    ComponentManager.prototype.useSnap = function() {
        
        if (this.snapObj) {
            return this.snapObj.useSnap;
        }
    }
    
    ComponentManager.prototype.snapPoint = function(coord,unit) {
        
        var returnValue = coord;
        if (this.snapObj) {
            returnValue = this.snapObj.snapPoint(coord, unit);
        }
        return returnValue;
    }
    
    ComponentManager.prototype.zoomByStep = function(step) {
        
        this.mapObj.zoomByStep(step);
    }

    ComponentManager.prototype.displayError = function(error) {
        this.loadSplashVisible(false);
        var message = "An Error Occured:" + "\n";
        if (error.name) message +=  "Type: " + error.name + "\n";
        if (error.lineNumber) message +=  "Line: " + error.lineNumber + "\n";
        if (error.message) message +=  "Message: " + error.message + "\n";
        if (error.description) message += "Descrtption: " + error.description + "\n";
        alert(message);
    }
    
    ComponentManager.prototype.displayServerError = function(response) {
        this.waitingForReply = false;
        this.loadSplashVisible(false);
        this.enableComponents();
        if (this.messageObj) {
            this.messageObj.innerHTML = "The following error was returned: " + response.replace(/&lt;br&gt;/g, "<br>");;
        }
    }
    
    ComponentManager.prototype.clearServerError = function() {
        this.messageObj.innerHTML = "";
    }
    
    ComponentManager.prototype.setDebugMessage = function(message) {
        this.messageObj.innerHTML = message;
    }
    
    ComponentManager.prototype.setMeasureInformation = function(segment, total, area, perimeter, metersPerPixel) {
    
        if (this.measureInfoObj) {
            this.measureInfoObj.setInformation(segment, total, area, perimeter);
        }
    }
    
    ComponentManager.prototype.getMeasureMode = function() {
        
        var mode;
        if (this.measureInfoObj) {
            mode = this.measureInfoObj.mode;
        }
        return mode;
    }
    
    ComponentManager.prototype.switchMeasureMode = function() {
        this.mapObj.shapeInfo();
    }
    
    ComponentManager.prototype.setMeasureMode = function(mode) {
        
        if (this.measureInfoObj) {
            this.measureInfoObj.setMode(mode);
        }
    }
    
    ComponentManager.prototype.setPrecision = function(value, precision) {
            
            if (precision > 0) {
                var calcFactor = Math.pow(10, precision);
                var value = Math.round(value * calcFactor, precision) / calcFactor;
                value = value.toString();
                if (value.indexOf(".") == -1) {
                    value += ".";
                }
                var count = precision - value.substr(value.indexOf(".") + 1).length;
                if (count > 0) {
                    for (var i=0; i<count; i++) {
                        value += 0;
                    }
                }
            }
            else {
                value = Math.round(value);
            }
            
			return value;
    }
    
    ComponentManager.prototype.registerToolbar = function(toolBarObj) {
        
        if (toolBarObj) {
            this.toolBarObjList[this.toolBarObjList.length] = toolBarObj;
        }
    }
    
    this.controlId = controlId;
    this.id = id;
    this.communicatorObj =  communicatorObj;
    this.requestObj = requestObj;
    this.responseObj = responseObj;
    this.mapObj;
    this.overviewObj;
    this.toolObj;
    this.toolBarObjList = new Array();
    this.statusObj;
    this.measureInfoObj;
    this.snapObj;
    this.TOCObj;
    this.legendObj;
    this.zoomObjList = new Array();
    this.bufferObj;
    this.loadSplashTimer = new Array();
    this.MEASURE_DISTANCE; //This is set by measureInfoObj
    this.MEASURE_AREA; //This is set by measureInfoObj
    this.messageObj = document.getElementById(messageElemID);
    this.preSendRequestFunction = preSendRequestFunction;
    this.postRecievedReplyFunction = postRecievedReplyFunction;
}
