    function MapLocation () {
        this.name = null;
        this.address = null;
	this.structuredAddress = null;
        this.isCenter = false;
        this.latLng = null;
        this.zoomLevel = null;
        this.iconName = null;
        this.marker = null;
    }
    
    MapLocation.prototype.equals = function(mapLocation) {
	if (mapLocation == null) {
	   return false;
	} 
	return this.address == mapLocation.address;
    }

    
    function MapLocations() {
        this.map = null;
        this.geocoder = null;
        this.centerLocation = null;
        this.mapLocations = new Array();
	this.projection = G_NORMAL_MAP.getProjection();
	this.measure = "px";
	this.INVALID_CANVAS_UNIT_MSG = "Map canvas is measured in invalid units";
	this.DEFAULT_ZOOM_LEVEL = 12;
	this.debugMode = null;

	this.geoAccuracy = new Array();
        this.geoAccuracy[0] = 3;
        this.geoAccuracy[1] = 4;
        this.geoAccuracy[2] = 8;
        this.geoAccuracy[3] = 10;
        this.geoAccuracy[4] = 12;
        this.geoAccuracy[5] = 14;
        this.geoAccuracy[6] = 14;
        this.geoAccuracy[7] = 15;
        this.geoAccuracy[8] = 16; 
    }
    
    MapLocations.prototype.saveMapLocation = function(mapLocation) {
        if (mapLocation.isCenter) {
            this.centerLocation = mapLocation;            
        } 
        this.mapLocations.push(mapLocation);
    }

    MapLocations.prototype.resetMapLocations = function() {
	this.mapLocations = new Array();
    }	
    
    MapLocations.prototype.geocodeAndAddToMap = function(mapLocation, fitAll, validLocationCallBack, invalidLocationCallBack) {
        var mapLocationsCallBackObj = this;
        this.geocoder.getLocations(mapLocation.address, function(location) {
	    if (!location.Placemark) {
		mapLocationsCallBackObj.removeLocation(mapLocation);
		if (invalidLocationCallBack) {
		   invalidLocationCallBack(mapLocation);
		} else {
		   alert ("Location " + mapLocation.address + " not found"); 
		}
	   	return;
	    }
            var placemark = location.Placemark[0];
            mapLocation.latLng = new GLatLng(placemark.Point.coordinates[1],
                  placemark.Point.coordinates[0]);
	    mapLocation.zoomLevel = mapLocationsCallBackObj.geoAccuracy[placemark.AddressDetails.Accuracy];
	    mapLocation.structuredAddress = placemark.address;
	    if (validLocationCallBack) {
		validLocationCallBack(mapLocation);
	    } else {
            	mapLocationsCallBackObj.addLocationToMapAndAdjustZoom(mapLocation, fitAll);
	    }
       });
    }

    MapLocations.prototype.addLocationToMapAndAdjustZoom = function(mapLocation, fitAll) {
	this.addLocationToMap(mapLocation);
	if (fitAll) {
	   this.fitMapLocationsOnCanvas(mapLocation);
	}
    }
    
    MapLocations.prototype.addLocationToMap = function(mapLocation) {
        if (mapLocation.isCenter) {
            this.map.setCenter(mapLocation.latLng, (mapLocation.zoomLevel == null) ? this.DEFAULT_ZOOM_LEVEL : mapLocation.zoomLevel);
        }
     
        var marker = new GMarker(mapLocation.latLng);
	/*
        if (mapLocation.iconName != null) {   
            marker.Ea.image = "http://www.google.com/mapfiles/marker" + mapLocation.iconName + ".png";
        }        
	*/

        mapLocation.marker = marker;
	var mapLocationsCallBackObj = this;
        GEvent.addListener(mapLocation.marker, "click", function(){
            var html = "<span style=\"font-family:Arial,Helvetica;font-size:10pt\">";
            if (mapLocation.name != null) {
                html += "<strong>" + mapLocation.name + "</strong><br />";
            }
            html += ((mapLocation.structuredAddress == null) ? mapLocation.address : mapLocation.structuredAddress) + "<br />";
	    if (mapLocationsCallBackObj.debugMode) {
	    	html += "Latitude/Longitude: " + mapLocation.latLng.lat() + "/" + mapLocation.latLng.lng() + "<br />";
	    	html += "Zoom level: " + mapLocationsCallBackObj.map.getZoom() + "</span>";
	    }
            marker.openInfoWindowHtml(html);
        });
        this.map.addOverlay(marker);
    }   

    MapLocations.prototype.removeLocation = function(mapLocation) {
	for (var i=0; i<this.mapLocations.length; i++) {
	   if (mapLocation.equals(this.mapLocations[i])) {
		this.mapLocations.splice(i, 1);	
	   }
    	}
    }

    MapLocations.prototype.removeLocationFromMap = function(locationToRemove)  {
	for (var i=0; i<this.mapLocations.length; i++) {
	   var mapLocation = this.mapLocations[i];
	   if (locationToRemove.equals(mapLocation) && mapLocation.marker != null) {
		this.map.removeOverlay(marker);	
	   }
    	}
    }

    MapLocations.prototype.fitMapLocationsOnCanvas = function(mapLocation) {
	var bounds = new GLatLngBounds();

	for (var i=0; i<this.mapLocations.length; i++) {
	   var loc = this.mapLocations[i];
	   bounds.extend(loc.latLng); 
	}
 	this.map.setZoom(this.map.getBoundsZoomLevel(bounds));	
	this.map.setCenter(bounds.getCenter());
    }

