		function markerGroup(map, checkbox) {
		    if (checkbox != null) {
			    if (checkbox.substr) {
				    checkbox = $(checkbox);
			    }
			    this.checkbox = checkbox;
			    Event.observe(checkbox, 'change', function() { self.showHide(self.checkbox.checked); });
			}
			this.map = map;

			var self = this;
		}

		markerGroup.prototype = {
			markers: false,
			_visible: false,

			containsPoint: function(lat, lng) {
				var found = false;

				this.markers.each(function(m) {
					if (m.isAtPoint(lat, lng)) found = true;
				});

				return found;
			},

			add: function(marker) {
				if (!this.markers) this.markers = [];

				this.markers.push(marker);
				if (this._visible) {
					this.map.addOverlay(marker.getGMarker());
				}
			},

			showHide: function(show) {
				var map = this.map;
				this._visible = show;

				if (show) {
					this.markers.each(function(v) { map.addOverlay(v.getGMarker()); });
				} else {
					this.markers.each(function(v) { map.removeOverlay(v.getGMarker()); });
				}
			}
		};

		function marker(lat, lng, icon) {
			var point = new GLatLng(lat, lng);
			this._marker = new GMarker(point, icon);
		}

		marker.prototype = {
			addInfo: function(info) {
				var infoTabs = [];

				for (var k in info) {
					infoTabs.push(new GInfoWindowTab(k, info[k]));
				}

				var gm = this._marker;
				GEvent.addListener(gm, "click", function() {
					gm.openInfoWindowTabsHtml(infoTabs);
				});
			},
			isAtPoint: function(lat, lng) { var p = this._marker.getPoint(); return (lat == p.lat() && lng == p.lng()); },
			getGMarker: function() { return this._marker; }
		};

		Event.observe(window, 'unload', GUnload);

