function cMarkerControls(infoWindowOpenCallback, infoWindowCloseCallback, clickCallback) {
	this.cMarkerControl = function(inTagID, infoWindowOpenCallback, infoWindowCloseCallback, clickCallback) {
		this.ctor = function(inTagID, infoWindowOpenCallback, infoWindowCloseCallback, clickCallback) {
			this.mTagID = inTagID;
			this.mDestinationInfo = null;
			this.mInfoWindowOpenCallback = infoWindowOpenCallback;
			this.mInfoWindowCloseCallback = infoWindowCloseCallback;
			this.mClickCallback = clickCallback;
			error_log('set click callback to ' + boolToInt(clickCallback !== null));
		}

		this.isset = function() {
			return this.mDestinationInfo != null;
		}

		this.issetTo = function(dbID) {
			return this.mDestinationInfo.mDatabaseID == dbID;
		}

		// Note default parameter
		this.reset = function() {
			var resetValue = defaultParameter(arguments, 1, 0);
			
			document.getElementById(this.mTagID).value = resetValue;

			if(this.mDestinationInfo != null) {
				this.mDestinationInfo.resetMarkerIcon();
				this.mDestinationInfo = null;
			}
		}

		this.set = function(dbID, iconInfo) {
			document.getElementById(this.mTagID).value = dbID;
			this.mDestinationInfo = getCityByDBID(dbID);
			this.mDestinationInfo.showMarker(true, iconInfo, this.mInfoWindowOpenCallback, this.mInfoWindowCloseCallback,
												this.mClickCallback);
		}

		this.ctor(inTagID, infoWindowOpenCallback, infoWindowCloseCallback, clickCallback);
	}

	this.ctor = function(infoWindowOpenCallback, infoWindowCloseCallback, clickCallback) {
		this.mStart = new this.cMarkerControl('start', infoWindowOpenCallback, infoWindowCloseCallback, clickCallback);
		this.mEnd = new this.cMarkerControl('end', infoWindowOpenCallback, infoWindowCloseCallback, clickCallback);
		this.mClickCallback = clickCallback;
	}
	
	this.getClicked = function(latLng) {
		if(this.mStart.isset() && fuzzilyEqual(this.mStart.mDestinationInfo.mLatLng, latLng)) {
			return 'start';
		} else if(this.mEnd.isset() && fuzzilyEqual(this.mEnd.mDestinationInfo.mLatLng, latLng)) {
			return 'end';
		} else {
			return 'neither';
		}
	}
	
	this.resetFlag = function(tagID, tagValue) {
		if(tagID == 'start')
			this.mStart.reset(tagValue);
		else
			this.mEnd.reset(tagValue);
	}
	
	this.setFlag = function(tagID, dbID) {
		var icon = new GIcon();
		icon.iconSize = new GSize(32, 32);

		if(tagID == 'start') {
			if(dbID == 0) {
				this.mStart.reset();
			} else {
				icon.image = 'http://' + serverName + '/vamos/images/startflag.png';
				icon.iconAnchor = new GPoint(0, 32);
				icon.infoWindowAnchor = new GPoint(15, 5);
		
				this.mStart.set(dbID, icon);
			}
		} else {
			if(dbID == 0) {
				this.mEnd.reset();
			} else {
				icon.image = 'http://' + serverName + '/vamos/images/endflag.png';
				icon.iconAnchor = new GPoint(7, 32);
				icon.infoWindowAnchor = new GPoint(2, 5); 

				this.mEnd.set(dbID, icon);
			}
		}
	}

	this.setFlags = function(dbID) {
		if(!this.mStart.isset()) {
			var icon = new GIcon();
			icon.image = 'http://' + serverName + '/vamos/images/startflag.png';
			icon.iconSize = new GSize(32, 32);
			icon.iconAnchor = new GPoint(0, 32);
			icon.infoWindowAnchor = new GPoint(15, 5);
		
			this.mStart.set(dbID, icon);
		} else {
			if(this.mStart.issetTo(dbID)) {
				// User clicked start point again; reset both start and finish so he can begin again
				this.mStart.reset();
				this.mEnd.reset();
			} else {
				// User clicked something other than the start point. Call that his endpoint
				if(!this.mEnd.isset()) {
					var icon = new GIcon();
					icon.image = 'http://' + serverName + '/vamos/images/endflag.png';
					icon.iconSize = new GSize(32, 32);
					icon.iconAnchor = new GPoint(7, 32);
					icon.infoWindowAnchor = new GPoint(2, 5); 

					this.mEnd.set(dbID, icon);
				} else {
					if(this.mEnd.issetTo(dbID)) {
						// User clicked end point again; reset the end so he can choose a different end
						this.mEnd.reset();
					}
				}
			}
		}
	}
	
	this.ctor(infoWindowOpenCallback, infoWindowCloseCallback, clickCallback);
}
